diff --git a/README.md b/README.md index dae6727..fb73509 100644 --- a/README.md +++ b/README.md @@ -53,50 +53,90 @@ curl https://git.daplie.com/Daplie/goldilocks.js/raw/master/install.sh | bash Modules & Configuration ----- -Goldilocks has several core systems, which all have their own configuration and some of which have modules: +Goldilocks has several core systems, which all have their own configuration and +some of which have modules: -``` -* http - - static - - redirect - - proxy (reverse proxy) -* tls - - acme - - proxy (reverse proxy) -* tcp - - forward -* tunnel_server -* tunnel_client -* mdns +* [http](#http) + - [proxy (reverse proxy)](#httpproxy-how-to-reverse-proxy-ruby-python-etc) + - [static](#httpstatic-how-to-serve-a-web-page) + - [redirect](#httpredirect-how-to-redirect-urls) +* [tls](#tls) + - [proxy (reverse proxy)](#tlsproxy) + - [acme](#tlsacme) +* [tcp](#tcp) + - [forward](#tcpforward) +* [udp](#udp) + - [forward](#udpforward) +* [domains](#domains) +* [tunnel_server](#tunnel_server) +* [tunnel_client](#tunnel) +* [mdns](#mdns) * api -``` + +All modules require a `type` and an `id`, and any modules not defined inside the +`domains` system also require a `domains` field (with the exception of the `forward` +modules that require the `ports` field). ### http The HTTP system handles plain http (TLS / SSL is handled by the tls system) +Example config: ```yml http: trust_proxy: true # allow localhost, 192.x, 10.x, 172.x, etc to set headers allow_insecure: false # allow non-https even without proxy https headers primary_domain: example.com # attempts to access via IP address will redirect here - # modules can be nested in domains - domains: - - names: - - example.com - modules: - - name: static - root: /srv/www/:hostname - - # The configuration above could also be represented as follows: + # An array of modules that define how to handle incoming HTTP requests modules: - - name: static + - type: static domains: - example.com root: /srv/www/:hostname ``` +### http.proxy - how to reverse proxy (ruby, python, etc) + +The proxy module is for reverse proxying, typically to an application on the same machine. +(Though it can also reverse proxy to other devices on the local network.) + +It has the following options: +``` +address The DNS-resolvable hostname (or IP address) and port connected by `:` to proxy the request to. + Takes priority over host and port if they are also specified. + ex: locahost:3000 + ex: 192.168.1.100:80 + +host The DNS-resolvable hostname (or IP address) of the system to which the request will be proxied. + Defaults to localhost if only the port is specified. + ex: localhost + ex: 192.168.1.100 + +port The port on said system to which the request will be proxied + ex: 3000 + ex: 80 +``` + +Example config: +```yml +http: + modules: + - type: proxy + domains: + - api.example.com + host: 192.168.1.100 + port: 80 + - type: proxy + domains: + - www.example.com + address: 192.168.1.16:80 + - type: proxy + domains: + - '*' + port: 3000 +``` + ### http.static - how to serve a web page The static module is for serving static web pages and assets and has the following options: @@ -109,50 +149,20 @@ root The path to serve as a string. ``` Example config: - ```yml http: modules: - - name: static + - type: static domains: - example.com root: /srv/www/:hostname ``` -### http.proxy - how to reverse proxy (ruby, python, etc) - -The proxy module is for reverse proxying, typically to an application on the same machine. - -It has the following options: - -``` -host The DNS-resolvable hostname (or IP address) of the system to which the request will be proxied - ex: localhost - ex: 192.168.1.100 - -port The port on said system to which the request will be proxied - ex: 3000 - ex: 80 -``` - -Example config: - -```yml -http: - modules: - - name: proxy - domains: - - example.com - host: localhost - port: 3000 -``` - ### http.redirect - how to redirect URLs The redirect module is for, you guessed it, redirecting URLs. It has the following options: - ``` status The HTTP status code to issue (301 is usual permanent redirect, 302 is temporary) ex: 301 @@ -169,11 +179,10 @@ to The new URL path which should be used. ``` Example config: - ```yml http: modules: - - name: proxy + - type: proxy domains: - example.com status: 301 @@ -184,41 +193,14 @@ http: ### tls The tls system handles encrypted connections, including fetching certificates, -and uses ServerName Indication (SNI) to determine if the connection should be handled -by the http system, a tls system module, or rejected. - -It has the following options: - -``` -acme.email The default email address for ACME certificate issuance - ex: john.doe@example.com - -acme.server The default ACME server to use - ex: https://acme-v01.api.letsencrypt.org/directory - ex: https://acme-staging.api.letsencrypt.org/directory - -acme.challenge_type The default ACME challenge to request - ex: http-01, dns-01, tls-01 - -acme.approved_domains The domains for which to request certificates - ex: example.com -``` +and uses ServerName Indication (SNI) to determine if the connection should be +handled by the http system, a tls system module, or rejected. Example config: - ```yml tls: - acme: - email: 'joe.shmoe@example.com' - # IMPORTANT: Switch to in production 'https://acme-v01.api.letsencrypt.org/directory' - server: 'https://acme-staging.api.letsencrypt.org/directory' - challenge_type: 'http-01' - approved_domains: - - example.com - - example.net - modules: - - name: proxy + - type: proxy domains: - example.com - example.net @@ -227,17 +209,44 @@ tls: Certificates are saved to `~/acme`, which may be `/var/www/acme` if Goldilocks is run as the www-data user. -### tls.acme +### tls.proxy -The acme module overrides the acme defaults of the tls system and uses the same options except that `approved_domains` -(in favor of the domains in the scope of the module). +The proxy module routes the traffic based on the ServerName Indication (SNI) **without decrypting** it. + +It has the same options as the [HTTP proxy module](#httpproxy-how-to-reverse-proxy-ruby-python-etc). Example config: - ```yml tls: modules: - - name: acme + - type: proxy + domains: + - example.com + address: '127.0.0.1:5443' +``` + +### tls.acme + +The acme module defines the setting used when getting new certificates. + +It has the following options: +``` +email The email address for ACME certificate issuance + ex: john.doe@example.com + +server The ACME server to use + ex: https://acme-v01.api.letsencrypt.org/directory + ex: https://acme-staging.api.letsencrypt.org/directory + +challenge_type The ACME challenge to request + ex: http-01, dns-01, tls-01 +``` + +Example config: +```yml +tls: + modules: + - type: acme domains: - example.com - example.net @@ -246,41 +255,18 @@ tls: challenge_type: 'http-01' ``` -### tls.proxy - -The proxy module routes the traffic based on the ServerName Indication (SNI) **without decrypting** it. - -It has the following options: - -``` -address The hostname (or IP) and port of the system or application that should receive the traffic -``` - -Example config: - -```yml -tls: - modules: - - name: proxy - domains: - - example.com - address: '127.0.0.1:5443' -``` - ### tcp The tcp system handles all tcp network traffic **before decryption** and may use port numbers or traffic sniffing to determine how the connection should be handled. It has the following options: - ``` bind An array of numeric ports on which to bind ex: 80 ``` -Example Config - +Example Config: ```yml tcp: bind: @@ -288,7 +274,7 @@ tcp: - 80 - 443 modules: - - name: forward + - type: forward ports: - 22 address: '127.0.0.1:2222' @@ -298,18 +284,15 @@ tcp: The forward module routes traffic based on port number **without decrypting** it. -It has the following options: +In addition to the same options as the [HTTP proxy module](#httpproxy-how-to-reverse-proxy-ruby-python-etc), +the TCP forward modules also has the following options: ``` ports A numeric array of source ports ex: 22 - -address The destination hostname and port - ex: 127.0.0.1:2222 ``` -Example Config - +Example Config: ```yml tcp: bind: @@ -317,10 +300,79 @@ tcp: - 80 - 443 modules: - - name: forward + - type: forward ports: - 22 - address: '127.0.0.1:2222' + port: 2222 +``` + +### udp + +The udp system handles all udp network traffic. It currently only supports +forwarding the messages without any examination. + +It has the following options: +``` +bind An array of numeric ports on which to bind + ex: 53 +``` + +Example Config: +```yml +udp: + bind: + - 53 + modules: + - type: forward + ports: + - 53 + address: '127.0.0.1:8053' +``` + +### udp.forward + +The forward module routes traffic based on port number **without decrypting** it. + +It has the same options as the [TCP forward module](#tcpforward). + +Example Config: +```yml +udp: + bind: + - 53 + modules: + - type: forward + ports: + - 53 + address: '127.0.0.1:8053' +``` + +### domains + +To reduce repetition defining multiple modules that operate on the same domain +name the `domains` field can define multiple modules of multiple types for a +single list of names. The modules defined this way do not need to have their +own `domains` field. + +Example Config + +```yml +domains: + names: + - example.com + - www.example.com + - api.example.com + modules: + tls: + - type: acme + email: joe.schmoe@example.com + challenge_type: 'http-01' + http: + - type: redirect + from: /deprecated/path + to: /new/path + - type: proxy + port: 3000 ``` @@ -417,15 +469,14 @@ See [API.md](/API.md) TODO ---- -* http - nowww module -* http - Allow match styles of `www.*`, `*`, and `*.example.com` equally -* http - redirect based on domain name (not just path) -* tcp - bind should be able to specify localhost, uniquelocal, private, or ip -* tcp - if destination host is omitted default to localhost, if dst port is missing, default to src -* sys - handle SIGHUP -* sys - `curl https://daplie.me/goldilocks | bash -s example.com` -* oauth3 - `example.com/.well-known/domains@oauth3.org/directives.json` -* oauth3 - commandline questionnaire -* modules - use consistent conventions (i.e. address vs host + port) - * tls - tls.acme vs tls.modules.acme -* tls - forward should be able to match on source port to reach different destination ports +* [ ] http - nowww module +* [ ] http - Allow match styles of `www.*`, `*`, and `*.example.com` equally +* [ ] http - redirect based on domain name (not just path) +* [ ] tcp - bind should be able to specify localhost, uniquelocal, private, or ip +* [ ] tcp - if destination host is omitted default to localhost, if dst port is missing, default to src +* [ ] sys - `curl https://daplie.me/goldilocks | bash -s example.com` +* [ ] oauth3 - `example.com/.well-known/domains@oauth3.org/directives.json` +* [ ] oauth3 - commandline questionnaire +* [x] modules - use consistent conventions (i.e. address vs host + port) + * [x] tls - tls.acme vs tls.modules.acme +* [ ] tls - forward should be able to match on source port to reach different destination ports