Criando um servido de DNS-over-HTTPS (DoH)
Neste tutorial vamos aprender como criar um servidor para consultar o DNS através de HTTPS, usando o Google DNS-over-protocolo HTTPS e IETF DNS-over-HTTPS (RFC 8484).
O Google Chrome já a partir da versão 78 irá implantar o DNS-over-HTTPS (DoH), criptografando as solicitações de DNS.
Pressupõe que você tenha um servidor DNS em funcionamento (eu uso o bind9).
Estou utilizando Debian 10 (Instalação limpa) para fazer esta instalação
Também será necessário configurar o seu ambiente Golang, veja aqui como proceder
Com o Golang já preparado vamos instalar alguns pacotes necessários para compilação:
# apt install curl software-properties-common build-essential wget unzip
Vamos usar o projeto m13253/DNS-over-HTTPS.
# cd /tmp # wget https://github.com/m13253/dns-over-https/archive/master.zip # unzip master.zip # cd dns-over-https-master/ # make # make install
Agora vamos configurar o servidor DoH, seu arquivo de configuração fica em /etc/dns-over-https/doh-server.conf
Supondo que você esteja instalando no mesmo servidor de DNS, vamos apenas alterar o upstream para usar as consultar para localhost (127.0.0.1:53).
# mv /etc/dns-over-https/doh-server.conf /etc/dns-over-https/doh-server.conf.old # vim /etc/dns-over-https/doh-server.conf
# HTTP listen port listen = [ "127.0.0.1:8053", "[::1]:8053", ## To listen on both 0.0.0.0:8053 and [::]:8053, use the following line # ":8053", ] # Local address and port for upstream DNS # If left empty, a local address is automatically chosen. local_addr = "" # TLS certification file # If left empty, plain-text HTTP will be used. # You are recommended to leave empty and to use a server load balancer (e.g. # Caddy, Nginx) and set up TLS there, because this program does not do OCSP # Stapling, which is necessary for client bootstrapping in a network # environment with completely no traditional DNS service. cert = "" # TLS private key file key = "" # HTTP path for resolve application path = "/dns-query" # Upstream DNS resolver # If multiple servers are specified, a random one will be chosen each time. # You can use "udp", "tcp" or "tcp-tls" for the type prefix. # For "udp", UDP will first be used, and switch to TCP when the server asks to # or the response is too large. # For "tcp", only TCP will be used. # For "tcp-tls", DNS-over-TLS (RFC 7858) will be used to secure the upstream connection. upstream = [ "udp:127.0.0.1:53", ] # Upstream timeout timeout = 10 # Number of tries if upstream DNS fails tries = 3 # Enable logging verbose = false # Enable log IP from HTTPS-reverse proxy header: X-Forwarded-For or X-Real-IP # Note: http uri/useragent log cannot be controlled by this config log_guessed_client_ip = false
Vamos ativa-lo na inicialização do sistema e restartar o serviço.
# systemctl enable doh-server # systemctl restart doh-server
Verifique se o serviço esta rodando
# systemctl status doh-server
Perfeito nosso doh-server já está rodando!
Instalação de configuração do Apache2 com um domínio virtual utilizando o Let’s Encrypt para criptografar nossa conexão HTTPs.
# apt install apache2 apache2-utils letsencrypt python-certbot-apache # a2enmod http2 proxy proxy_http proxy_connect # systemctl restart apache2
Vou editar a configuração padrão do servidor web, informado meu real ServerName, no exemplo “doh.remontti.com.br“, e ErrorDocument quando um IP não autorizado acessar ser redirecionado.
# vim /etc/apache2/sites-available/000-default.conf
Faça as devidas alterações, não esqueça de alterar em Require ip para os IPs que você vai autorizar as conexões.
<virtualhost *:80> Protocols h2 http/1.1 ServerName doh.remontti.com.br ServerAdmin noc@remontti.com.br ErrorDocument 403 http://www.remontti.com.br/ DocumentRoot /var/www/html <Directory /var/www/html/> Options FollowSymLinks AllowOverride All Require ip 127.0.0.1 ::1 192.168.0.0/16 172.16.0.0/12 100.64.0.0/10 10.0.0.0/8 250.0.0.0/22 2000:000::/32 </Directory> LogLevel warn ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </virtualhost>
Por segurança recomendo remover a assinatura do servidor, para isso edite:
# sed -i 's/ServerTokens OS/ServerTokens Prod/' /etc/apache2/conf-available/security.conf # sed -i 's/ServerSignature On/ServerSignature Off/' /etc/apache2/conf-available/security.conf
Para que quando alguém (autorizado) acessar seu endereço DoH não veja aquela tela Default do Apache2, vamos remover o /var/www/html/index.html e criar uma index mais legal 😛
# rm /var/www/html/index.html # wget https://blog.remontti.com.br/wp-content/uploads/2019/10/doh.jpg -O /var/www/html/doh.jpg # vim /var/www/html/index.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>Dns Over Https - DoH</title> <!-- Altere para o endereço que você deseja que ele seja direcionado apos 5seg--> <meta http-equiv="refresh" content="5; URL='http://www.remontti.com.br/'"/> <style type="text/css"> body, html { background-color: #fff112; } img { width: 95%; height: auto; } </style> </head> <body> <img src="doh.jpg"> </body> </html>
Geramos o certificado
# systemctl stop apache2 # letsencrypt
Agora já é possível acessar “doh.remontti.com.br” com HTTPS, faça um teste se seu domínio esta respondendo corretamente. Teste também seu HTTP2 em https://tools.keycdn.com/http2-test
Para evitar que o certificado expire faça um script e colocando ele no cron para que o mesmo renove automaticamente.
# vim /etc/renovassl.sh
Adicione
#!/bin/bash /usr/bin/systemctl stop apache2 /usr/bin/certbot -q renew /usr/bin/systemctl start apache2
De permissão de execução:
# chmod +x /etc//renovassl.sh
Adicione ao cron e restarte o cron
# echo '00 00 * * * root /etc/renovassl.sh' >> /etc/crontab # systemctl restart cron
Altere algumas configuração no 000-default-le-ssl.conf criado pelo Let’s Encrypt para trabalhar como um proxy do nosso DoH
# vim /etc/apache2/sites-enabled/000-default-le-ssl.conf
Adicione as entradas destacadas:
<IfModule mod_ssl.c> 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) <VirtualHost *:443> Protocols h2 http/1.1 ServerName doh.remontti.com.br ServerAdmin noc@remontti.com.br ErrorDocument 403 http://www.remontti.com.br/ ProxyPreserveHost On ProxyPass /dns-query http://[::1]:8053/dns-query ProxyPassReverse /dns-query http://[::1]:8053/dns-query <Proxy "*"> Require ip 127.0.0.1 ::1 192.168.0.0/16 172.16.0.0/12 100.64.0.0/10 10.0.0.0/8 250.0.0.0/22 2000:000::/32 </Proxy> DocumentRoot /var/www/html <Directory /var/www/html/> Options FollowSymLinks AllowOverride All Require ip 127.0.0.1 ::1 192.168.0.0/16 172.16.0.0/12 100.64.0.0/10 10.0.0.0/8 250.0.0.0/22 2000:000::/32 </Directory> ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined SSLCertificateFile /etc/letsencrypt/live/su-151.speedrs.com.br/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/su-151.speedrs.com.br/privkey.pem Include /etc/letsencrypt/options-ssl-apache.conf </VirtualHost> </IfModule>
Restar o apache
# systemctl restart apache2
Configuramos o apache para encaminhar solicitações para nosso servidor DoH. Agora vamos fazer alguns testes.
O servidor DoH retorna em formato JSON, e para testar apenas abra no seu navegador:
https://doh.remontti.com.br/dns-query?name=remontti.com.br&type=A
Ou já que você está com o terminal aberto digite:
# curl -s "https://doh.remontti.com.br/dns-query?name=google.com.br&type=A" | python -m json.tool
Vai retornar:
{ "AD": false, "Answer": [ { "Expires": "Fri, 04 Oct 2019 16:48:23 UTC", "TTL": 300, "data": "172.217.29.227", "name": "google.com.br.", "type": 1 } ], "CD": false, "Question": [ { "name": "google.com.br.", "type": 1 } ], "RA": true, "RD": true, "Status": 0, "TC": false, "edns_client_subnet": "186.250.168.0/0" }
Legal, nosso DoH esta funcionando!
Configure seu navegador
Bem, no Firefox, isso é bem fácil, entre no menu Preferências, role até o final e clique em Configurar Conexão… em seguida marque a caixa Ativar DNS sobre HTTPS selecione Personalizado e informe o endereço do seu servidor DoH https://doh.exemplo.com.br/dns-query
No linux a versão que utilizei foi uma beta, pois na estável ainda não aparecia a opção.
Já no Chrome Versão Dev 79.0.3921.0 no linux não consegui testar, pois a opção aparece como: Not available on your platform.
Agora basta navegar! E para ter certeza que ele realmente ta fazendo as consulta em seu DoH Server, verifique os logs do seu apache:
# tail -f /var/log/apache2/access.log
O que você vai acontecer quando o DoH estiver ativado?
Quando o DoH está ativado, você não notará nada. O Firefox e o Chrome implementaram extensos mecanismos de fallback para situações em que o DoH pode cair, como um provedor de DNS que não oferece suporte a DoH.
Quais navegadores suportam o DoH?
Por enquanto, os únicos principais navegadores programados para oferecer suporte ao DoH são o Mozilla Firefox e Chrome 78 ou superior (embora, especialmente, o Chrome para iOS e o Chrome para Linux não suportem esse recurso ainda). Resta saber se o Safari da Apple seguirá o exemplo.
Ambos os navegadores se o DoH não funcionar como planejado simplesmente retornará ao método padrão de pesquisa de DNS.
Se quiser fazer uma doação para o café ficarei muito feliz pelo seu reconhecimento!
Se não puder doar pode deixar seu agradecimento nos comentário também ficarei feliz em saber que ajudei. Se tiver qualquer pergunta deixe-a também. Se preferir entrar em Contato clique aqui.
Abraço!