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!



