Merge pull request #76 from satishweb/master

Docker compose based doh-server setup example
This commit is contained in:
Star Brilliant authored and GitHub committed 2020-04-05 20:42:36 +08:00
commit 81b977ca11
1 file changed
+195 -211
+195 -211
View File
@@ -4,68 +4,66 @@ DNS-over-HTTPS
Client and server software to query DNS over HTTPS, using [Google DNS-over-HTTPS protocol](https://developers.google.com/speed/public-dns/docs/dns-over-https) Client and server software to query DNS over HTTPS, using [Google DNS-over-HTTPS protocol](https://developers.google.com/speed/public-dns/docs/dns-over-https)
and [IETF DNS-over-HTTPS (RFC 8484)](https://www.rfc-editor.org/rfc/rfc8484.txt). and [IETF DNS-over-HTTPS (RFC 8484)](https://www.rfc-editor.org/rfc/rfc8484.txt).
## Guide ## Guides
[Tutorial to setup your own DNS-over-HTTPS (DoH) server](https://www.aaflalo.me/2018/10/tutorial-setup-dns-over-https-server/). (Thanks to Antoine Aflalo) - [Tutorial: Setup your own DNS-over-HTTPS (DoH) server](https://www.aaflalo.me/2018/10/tutorial-setup-dns-over-https-server/). (Thanks to Antoine Aflalo)
- [Tutorial: Setup your own Docker based DNS-over-HTTPS (DoH) server](https://github.com/satishweb/docker-doh/blob/master/README.md). (Thanks to Satish Gaikwad)
## Installing ## Installing
### From Source ### From Source
Install [Go](https://golang.org), at least version 1.10. - Install [Go](https://golang.org), at least version 1.10.
> Note for Debian/Ubuntu users: You need to set `$GOROOT` if you could not get your new version of Go selected by the Makefile.)
(Note for Debian/Ubuntu users: You need to set `$GOROOT` if you could not get your new version of Go selected by the Makefile.) - First create an empty directory, used for `$GOPATH`:
```bash
First create an empty directory, used for `$GOPATH`: mkdir ~/gopath
export GOPATH=~/gopath
mkdir ~/gopath ```
export GOPATH=~/gopath - To build the program, type:
```bash
To build the program, type: make
```
make - To install DNS-over-HTTPS as Systemd services, type:
```bash
To install DNS-over-HTTPS as Systemd services, type: sudo make install
```
sudo make install - By default, [Google DNS over HTTPS](https://dns.google.com) is used. It should
By default, [Google DNS over HTTPS](https://dns.google.com) is used. It should
work for most users (except for People's Republic of China). If you need to work for most users (except for People's Republic of China). If you need to
modify the default settings, type: modify the default settings, type:
```bash
sudoedit /etc/dns-over-https/doh-client.conf
```
- To automatically start DNS-over-HTTPS client as a system service, type:
```bash
sudo systemctl start doh-client.service
sudo systemctl enable doh-client.service
```
- Then, modify your DNS settings (usually with NetworkManager) to 127.0.0.1.
sudoedit /etc/dns-over-https/doh-client.conf - To test your configuration, type:
```bash
To automatically start DNS-over-HTTPS client as a system service, type: dig www.google.com
Output:
sudo systemctl start doh-client.service ;; SERVER: 127.0.0.1#53(127.0.0.1)
sudo systemctl enable doh-client.service ```
Then, modify your DNS settings (usually with NetworkManager) to 127.0.0.1.
To test your configuration, type:
dig www.google.com
If it is OK, you will see:
;; SERVER: 127.0.0.1#53(127.0.0.1)
#### Uninstall #### Uninstall
To uninstall, type: - To uninstall, type:
```bash
sudo make uninstall sudo make uninstall
```
The configuration files are kept at `/etc/dns-over-https`. Remove them manually if you want. > Note: The configuration files are kept at `/etc/dns-over-https`. Remove them manually if you want.
### Using docker image ### Using docker image
``` ```bash
docker run -itd --name doh-server \ docker run -itd --name doh-server \
-p 8053:8053 \ -p 8053:8053 \
-e UPSTREAM_DNS_SERVER="udp:8.8.8.8:53" \ -e UPSTREAM_DNS_SERVER="udp:8.8.8.8:53" \
-e DOH_HTTP_PREFIX="/dns-query" -e DOH_HTTP_PREFIX="/dns-query"
-e DOH_SERVER_LISTEN=":8053" -e DOH_SERVER_LISTEN=":8053"
-e DOH_SERVER_TIMEOUT="10" -e DOH_SERVER_TIMEOUT="10"
-e DOH_SERVER_TRIES="3" -e DOH_SERVER_TRIES="3"
-e DOH_SERVER_VERBOSE="false" -e DOH_SERVER_VERBOSE="false"
satishweb/doh-server satishweb/doh-server
``` ```
@@ -104,200 +102,186 @@ upstream_selector = "random"
``` ```
### Example configuration: Apache ### Example configuration: Apache
```bash
SSLProtocol TLSv1.2
SSLHonorCipherOrder On
SSLCipherSuite ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+3DES:!aNULL:!MD5:!DSS:!eNULL:!EXP:!LOW:!MD5
SSLUseStapling on
SSLStaplingCache shmcb:/var/lib/apache2/stapling_cache(512000)
SSLProtocol TLSv1.2 <VirtualHost *:443>
SSLHonorCipherOrder On ServerName MY_SERVER_NAME
SSLCipherSuite ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+3DES:!aNULL:!MD5:!DSS:!eNULL:!EXP:!LOW:!MD5 Protocols h2 http/1.1
SSLUseStapling on ProxyPass /dns-query http://[::1]:8053/dns-query
SSLStaplingCache shmcb:/var/lib/apache2/stapling_cache(512000) ProxyPassReverse /dns-query http://[::1]:8053/dns-query
</VirtualHost>
<VirtualHost *:443> ```
ServerName MY_SERVER_NAME
Protocols h2 http/1.1
ProxyPass /dns-query http://[::1]:8053/dns-query
ProxyPassReverse /dns-query http://[::1]:8053/dns-query
</VirtualHost>
(Credit: [Joan Moreau](https://github.com/m13253/dns-over-https/issues/51#issuecomment-526820884)) (Credit: [Joan Moreau](https://github.com/m13253/dns-over-https/issues/51#issuecomment-526820884))
### Example configuration: Nginx ### Example configuration: Nginx
```bash
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name MY_SERVER_NAME;
server { server_tokens off;
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name MY_SERVER_NAME;
server_tokens off;
ssl_protocols TLSv1.2 TLSv1.3; # TLS 1.3 requires nginx >= 1.13.0
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/nginx/dhparam.pem; # openssl dhparam -dsaparam -out /etc/nginx/dhparam.pem 4096
ssl_ciphers EECDH+AESGCM:EDH+AESGCM;
ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0
ssl_session_timeout 10m;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off; # Requires nginx >= 1.5.9
ssl_stapling on; # Requires nginx >= 1.3.7
ssl_stapling_verify on; # Requires nginx => 1.3.7
ssl_early_data off; # 0-RTT, enable if desired - Requires nginx >= 1.15.4
resolver 1.1.1.1 valid=300s; # Replace with your local resolver
resolver_timeout 5s;
# HTTP Security Headers
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security "max-age=63072000";
ssl_certificate /path/to/your/server/certificates/fullchain.pem;
ssl_certificate_key /path/to/your/server/certificates/privkey.pem;
location /dns-query {
proxy_pass http://localhost:8053/dns-query;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
ssl_protocols TLSv1.2 TLSv1.3; # TLS 1.3 requires nginx >= 1.13.0
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/nginx/dhparam.pem; # openssl dhparam -dsaparam -out /etc/nginx/dhparam.pem 4096
ssl_ciphers EECDH+AESGCM:EDH+AESGCM;
ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0
ssl_session_timeout 10m;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off; # Requires nginx >= 1.5.9
ssl_stapling on; # Requires nginx >= 1.3.7
ssl_stapling_verify on; # Requires nginx => 1.3.7
ssl_early_data off; # 0-RTT, enable if desired - Requires nginx >= 1.15.4
resolver 1.1.1.1 valid=300s; # Replace with your local resolver
resolver_timeout 5s;
# HTTP Security Headers
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security "max-age=63072000";
ssl_certificate /path/to/your/server/certificates/fullchain.pem;
ssl_certificate_key /path/to/your/server/certificates/privkey.pem;
location /dns-query {
proxy_pass http://localhost:8053/dns-query;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
```
(Credit: [Cipherli.st](https://cipherli.st/)) (Credit: [Cipherli.st](https://cipherli.st/))
### Example configuration: Caddy ### Example configuration: Caddy
```bash
https://MY_SERVER_NAME { https://MY_SERVER_NAME {
log / syslog "{remote} - {user} [{when}] \"{method} {scheme}://{host}{uri} {proto}\" {status} {size} \"{>Referer}\" \"{>User-Agent}\" {>X-Forwarded-For}" log / syslog "{remote} - {user} [{when}] \"{method} {scheme}://{host}{uri} {proto}\" {status} {size} \"{>Referer}\" \"{>User-Agent}\" {>X-Forwarded-For}"
errors syslog errors syslog
gzip gzip
proxy /dns-query http://[::1]:18053 { proxy /dns-query http://[::1]:18053 {
header_upstream Host {host} header_upstream Host {host}
header_upstream X-Real-IP {remote} header_upstream X-Real-IP {remote}
header_upstream X-Forwarded-For {>X-Forwarded-For},{remote} header_upstream X-Forwarded-For {>X-Forwarded-For},{remote}
header_upstream X-Forwarded-Proto {scheme} header_upstream X-Forwarded-Proto {scheme}
} }
root /var/www root /var/www
tls { tls {
ciphers ECDHE-ECDSA-WITH-CHACHA20-POLY1305 ECDHE-RSA-WITH-CHACHA20-POLY1305 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-GCM-SHA256 ciphers ECDHE-ECDSA-WITH-CHACHA20-POLY1305 ECDHE-RSA-WITH-CHACHA20-POLY1305 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-GCM-SHA256
curves X25519 p384 p521 curves X25519 p384 p521
must_staple must_staple
} }
} }
### Example configuration: Docker Flow Proxy + Docker Swarm
``` ```
version: '3.7' ### Example configuration: Docker Compose + Traefik + Unbound (Raspberry Pi/Linux/Mac) [linux/amd64,linux/arm64,linux/arm/v7]
```yaml
version: '2.2'
networks: networks:
default: default:
driver: overlay
attachable: true
external: false
proxy:
external: true
services: services:
swarm-listener:
image: dockerflow/docker-flow-swarm-listener:latest
hostname: swarm-listener
init: true
networks:
- default
- proxy
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- DF_NOTIFY_CREATE_SERVICE_URL=http://proxy:8080/v1/docker-flow-proxy/reconfigure
- DF_NOTIFY_REMOVE_SERVICE_URL=http://proxy:8080/v1/docker-flow-proxy/remove
deploy:
placement:
constraints:
- node.role==manager
restart_policy:
condition: any
delay: 10s
max_attempts: 99
window: 180s
healthcheck:
test: [ "CMD", "wget", "http://localhost:8080/v1/docker-flow-swarm-listener/ping", "-O", "/dev/null" ]
interval: 2m
timeout: 1m
retries: 3
proxy: proxy:
image: dockerflow/docker-flow-proxy:latest # The official v2 Traefik docker image
image: traefik:v2.2
hostname: proxy hostname: proxy
init: true
networks: networks:
- default - default
- proxy
ports:
- 80:80
- 443:443
volumes:
- ./data/proxy/certs:/certs
environment: environment:
TINI_SUBREAPER: 1 TRAEFIK_ACCESSLOG: "true"
LISTENER_ADDRESS: swarm-listener TRAEFIK_API: "true"
MODE: swarm TRAEFIK_PROVIDERS_DOCKER: "true"
COMPRESSION_ALGO: gzip TRAEFIK_API_INSECURE: "true"
COMPRESSION_TYPE: text/css text/html text/javascript application/javascript text/plain text/xml application/json TRAEFIK_PROVIDERS_DOCKER_NETWORK: "${STACK}_default"
CONNECTION_MODE: http-keep-alive # DNS provider specific environment variables for DNS Challenge using route53 (AWS)
DEBUG: "true" AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
HTTPS_ONLY: "true" AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY}
STATS_URI: /stats AWS_REGION: ${AWS_REGION}
EXTRA_FRONTEND: http-request set-log-level debug,http-response set-log-level debug,capture request header User-Agent len 64,acl is_vd path -i /dns-admin,http-request redirect scheme https drop-query append-slash if is_vd,http-response set-header X-Frame-Options DENY,http-response set-header X-Content-Type-Options nosniff, AWS_HOSTED_ZONE_ID: ${AWS_HOSTED_ZONE_ID}
EXTRA_GLOBAL: ports:
SSL_BIND_OPTIONS: no-sslv3 no-tls-tickets no-tlsv10 no-tlsv11 # The HTTP port
SSL_BIND_CIPHERS: EECDH+AESGCM:EDH+AESGCM - "80:80"
deploy: # The HTTPS port
replicas: 1 - "443:443"
restart_policy: # The Web UI (enabled by --api.insecure=true)
condition: any - "8080:8080"
delay: 10s command:
max_attempts: 99 #- "--log.level=DEBUG"
window: 180s - "--providers.docker.exposedbydefault=false"
healthcheck: - "--entrypoints.web.address=:80"
test: [ "CMD", "sh", "-c", "/usr/local/bin/check.sh"] - "--entrypoints.websecure.address=:443"
interval: 2m - "--certificatesresolvers.letsencrypt.acme.dnschallenge=true"
timeout: 1m # Providers list:
retries: 3 # https://docs.traefik.io/https/acme/#providers
# https://go-acme.github.io/lego/dns/
- "--certificatesresolvers.letsencrypt.acme.dnschallenge.provider=route53"
# Enable below line to use staging letsencrypt server.
#- "--certificatesresolvers.letsencrypt.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
- "--certificatesresolvers.letsencrypt.acme.email=${EMAIL}"
- "--certificatesresolvers.letsencrypt.acme.storage=/certs/acme.json"
volumes:
# So that Traefik can listen to the Docker events
- /var/run/docker.sock:/var/run/docker.sock
- ./data/proxy/certs:/certs
doh-server: doh-server:
image: satishweb/doh-server image: satishweb/doh-server:latest
# Docker Image based on https://github.com/m13253/dns-over-https
hostname: doh-server hostname: doh-server
networks: networks:
- default - default
environment: environment:
DEBUG: "0" # Enable below line to see more logs
UPSTREAM_DNS_SERVER: "udp:YOUR-DNS-SERVER-IP:53" # DEBUG: "1"
DOH_HTTP_PREFIX: "/dns-query" UPSTREAM_DNS_SERVER: "udp:unbound:53"
DOH_SERVER_LISTEN: ":8053" DOH_HTTP_PREFIX: "${DOH_HTTP_PREFIX}"
DOH_SERVER_LISTEN: ":${DOH_SERVER_LISTEN}"
DOH_SERVER_TIMEOUT: "10" DOH_SERVER_TIMEOUT: "10"
DOH_SERVER_TRIES: "3" DOH_SERVER_TRIES: "3"
DOH_SERVER_VERBOSE: "true" DOH_SERVER_VERBOSE: "false"
# You can add more variables here or as docker secret and entrypoint #volumes:
# script will replace them inside doh-server.conf file
# Entrypoint script source is at https://github.com/satishweb/docker-doh
volumes:
# If you want to use your custom doh-server.conf, use below volume mount.
# - ./doh-server.conf:/server/doh-server.conf # - ./doh-server.conf:/server/doh-server.conf
# Mount app-config script with your customizations
# - ./app-config:/app-config # - ./app-config:/app-config
deploy: depends_on:
replicas: 1 - unbound
restart_policy: labels:
condition: any - "traefik.enable=true"
delay: 10s - "traefik.http.routers.doh-server.rule=Host(`${SUBDOMAIN}.${DOMAIN}`) && Path(`${DOH_HTTP_PREFIX}`)"
max_attempts: 99 - "traefik.http.services.doh-server.loadbalancer.server.port=${DOH_SERVER_LISTEN}"
window: 180s - "traefik.http.middlewares.mw-doh-compression.compress=true"
labels: - "traefik.http.routers.doh-server.tls=true"
- com.df.notify=true - "traefik.http.middlewares.mw-doh-tls.headers.sslredirect=true"
- com.df.distribute=true - "traefik.http.middlewares.mw-doh-tls.headers.sslforcehost=true"
- com.df.servicePath='/dns-query' - "traefik.http.routers.doh-server.tls.certresolver=letsencrypt"
- com.df.port=8053 - "traefik.http.routers.doh-server.tls.domains[0].main=${DOMAIN}"
- "traefik.http.routers.doh-server.tls.domains[0].sans=${SUBDOMAIN}.${DOMAIN}"
# Protection from requests flood
- "traefik.http.middlewares.mw-doh-ratelimit.ratelimit.average=100"
- "traefik.http.middlewares.mw-doh-ratelimit.ratelimit.burst=50"
- "traefik.http.middlewares.mw-doh-ratelimit.ratelimit.period=10s"
unbound:
image: satishweb/unbound:latest
hostname: unbound
networks:
- default
ports:
# Disable these ports if DOH server is the only client
- 53:53/tcp
- 53:53/udp
volumes:
- ./unbound.sample.conf:/templates/unbound.sample.conf
- ./data/unbound/custom:/etc/unbound/custom
# Keep your custom.hosts file inside custom folder
#environment:
# DEBUG: "1"
```` ````
> Above example needs you to add your chained SSL certificate in folder: ./data/proxy/certs and configure upstream DNS server address.
> Complete Docker Stack with DFProxy + Lets Encrypt SSL: https://github.com/satishweb/docker-doh > Complete Guide available at: https://github.com/satishweb/docker-doh
> Docker Flow Proxy: https://github.com/docker-flow/docker-flow-proxy
> No IPV6 Support: Docker Swarm does not support IPV6 as of yet. Issue is logged [here](https://github.com/moby/moby/issues/24379) > No IPV6 Support: Docker Swarm does not support IPV6 as of yet. Issue is logged [here](https://github.com/moby/moby/issues/24379)
> IPV6 Support for Docker Compose based configuration TBA
## DNSSEC ## DNSSEC
DNS-over-HTTPS is compatible with DNSSEC, and requests DNSSEC signatures by DNS-over-HTTPS is compatible with DNSSEC, and requests DNSSEC signatures by