O DNS recursivo é responsável por efetuar consultas quando você envia uma solicitação, por exemplo, para acessar um site. Graças ao serviço de DNS (Domain Name System), não precisamos ficar decorando o IP dos sites que precisamos acessar. Portanto quando digitamos o endereço de um site no navegador, o DNS recursivo é quem vai fazer as consultas necessárias na internet para encontrar o que você procura.
Este é o primeiro de uma série de artigos detalhando a configuração de servidores de DNS. Faremos a configuração de um servidor MASTER e um SLAVE com DNS Recursivo, Autoritativo e Reverso. Além de implementar a segurança do servidor com o Fail2ban + nftables.
Ex.: ASN – CIDR/22
Nesse exemplo vou usar um bloco /22, que seria o bloco público do nosso ASN da empresa fictícia XPTO.
Bloco recebido: IPv4 – 45.80.48.0/22 IPv6 – 2804:f123::/32
Domínio: xpto.com.br
Antes de mais nada o mínimo de conhecimento é saber realizar cálculos de sub-redes.
Address: 45.80.48.0 00101101.01010000.001100 00.00000000 Netmask: 255.255.252.0 = 22 11111111.11111111.111111 00.00000000 Wildcard: 0.0.3.255 00000000.00000000.000000 11.11111111 => Network: 45.80.48.0/22 00101101.01010000.001100 00.00000000 (Class A) Broadcast: 45.80.51.255 00101101.01010000.001100 11.11111111 HostMin: 45.80.48.1 00101101.01010000.001100 00.00000001 HostMax: 45.80.51.254 00101101.01010000.001100 11.11111110 Hosts/Net: 1022
IP address 2804:f123::/32
type GLOBAL-UNICAST
network 2804:f123::
Prefix length 32
network range 2804:f123:0000:0000:0000:0000:0000:0000-
2804:f123:ffff:ffff:ffff:ffff:ffff:ffff
total IP addresses 79228162514264337593543950336
IP address (full) 2804:f123:0000:0000:0000:0000:0000:0000
integer ID 53194779852530942278490391458128855040
hexadecimal ID 0x2804f123000000000000000000000000
dotted decimal ID 40.4.241.35.0.0.0.0.0.0.0.0.0.0.0.0
base 85 ID bUNzq7N(z7V!Hn|9W{O%
binary ID 00101000000001001111000100100011...
ip6.arpa Format 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.3.2.1.f.4.0.8.2.ip6.arpa
This prefix can contain one of the following:
* 4294967296 (2^32 or 4.3e+09) subnets /64
* 16777216 (2^24 or 1.7e+07) subnets /56
* 65536 (2^16 or 6.6e+04) subnets /48
Para ilustrar “nossa rede” conto com os seguintes servidores:
ROUTER GW -> 45.80.48.1 / 2804:f123:bebe:cafe::1 (MIKROTIK)
SRV DNS MASTER -> 45.80.48.2 / 2804:f123:bebe:cafe::2 (DEBIAN 10)
SRV DNS SLAVE -> 45.80.48.3 / 2804:f123:bebe:cafe::3 (DEBIAN 10)
SRV WEB + FTP -> 45.80.48.4 / 2804:f123:bebe:cafe::4 (CENTOS 8)
SRV ZABBIX + phpIPam -> 45.80.48.5 / 2804:f123:bebe:cafe::5 (DEBIAN 10)
SRV E-MAIL -> 45.80.48.6 / 2804:f123:bebe:cafe::6 (mail,imap,pop,smtp) (CENTOS 8)
Dentro da rede ainda temos os blocos de IPs inválidos/internos 192.168.0.0/16, 172.16.0.0/12, 100.64.0.0/10 e 10.0.0.0/8 utilizando NAT que também precisam fazer consultas recursivas no servidores.
Tenha sua interface de rede configurada corretamente.
# vim /etc/network/interfaces
# This file describes the network interfaces available on your system # and how to activate them. For more information, see interfaces(5). source /etc/network/interfaces.d/* # The loopback network interface auto lo iface lo inet loopback # The primary network interface allow-hotplug enp0s3 iface enp0s3 inet static address 45.80.48.2/28 gateway 45.80.48.1 dns-nameservers 127.0.0.1 dns-search localhost iface enp0s3 inet6 static pre-up modprobe ipv6 address 2804:f123:bebe:cafe::2 netmask 64 gateway 2804:f123:bebe:cafe::1
MASTER (NS1)
# su - # apt install bind9 dnsutils
Alteramos o DNS do servidor fazendo com que ele consulte em si próprio. Essa alteração deve ser feita no arquivo /etc/resolv.conf.
# echo "nameserver 127.0.0.1" > /etc/resolv.conf
Para descobrir se seu servidor esta resolvendo nomes use o comando dig.
# dig google.com @localhost
Retornará algo como:
[...] ;; ANSWER SECTION: google.com. 300 IN A 172.217.162.110 [...]
Os arquivos de configuração do bind ficam no diretório /etc/bind/ e agora no Debian 10 Buster também separando os root servers em /usr/share/dns/
# cd /etc/bind
Iremos alterar o named.conf.options, o próprio nome já se auto descreve o que vamos encontrar nele.
# cp /etc/bind/named.conf.options /etc/bind/named.conf.options.bkp # echo > named.conf.options
Explicação comentada no arquivo.
# vim /etc/bind/named.conf.options
// ACL "autorizados" vão ficar os ips que são autorizados a fazer
// consultas recursivas neste servidor.
// Neste caso vou incluir os ips que foram nos delegados bem como de localhost e IPs privados
acl autorizados {
127.0.0.1;
::1;
45.80.48.0/22;
2804:f123::/32;
192.168.0.0/16;
172.16.0.0/12;
100.64.0.0/10;
10.0.0.0/8;
};
options {
// O diretório de trabalho do servidor
// Quaisquer caminho não informado será tomado como padrão este diretório
directory "/var/cache/bind";
//Suporte a DNSSEC
dnssec-enable yes;
dnssec-validation auto;
// Conforme RFC1035
// https://www.ietf.org/rfc/rfc1035.txt
auth-nxdomain no;
// Respondendo para IPv4 e IPv6
// Porta 53 estará aberta para ambos v4 e v6
listen-on { any; };
listen-on-v6 { any; };
// Limitação da taxa de resposta no sistema de nomes de domínio (https://kb.isc.org/docs/aa-00994)
// Se você esta montando um servido apenas para autoritativo descomente as linhas a baixo.
//rate-limit {
// responses-per-second 15;
// window 5;
//};
// Melhora o desempenho do servidor, reduzindo os volumes de dados de saída.
// O padrão BIND é (no) não.
minimal-responses yes;
// Especifica quais hosts estão autorizados a fazer consultas
// recursivas através deste servidor.
// Aqui que você vai informar os IPs da sua rede que você irá permitir consultar os DNS.
allow-recursion {
autorizados;
};
// Endereço estão autorizados a emitir consultas ao cache local,
// sem acesso ao cache local as consultas recursivas são inúteis.
allow-query-cache {
autorizados;
};
// Especifica quais hosts estão autorizados a fazer perguntas DNS comuns.
allow-query { any; };
// Especifica quais hosts estão autorizados a receber transferências de zona a partir do servidor.
// Seu servidor Secundário, no nosso ex vou deixar então o ips dos dois servidores v4 e v6.
allow-transfer {
45.80.48.3;
2804:f123:bebe:cafe::3;
};
also-notify {
45.80.48.3;
2804:f123:bebe:cafe::3;
};
// Esta opção faz com que o servidor slave ao fazer a transferência de zonas
// mastes deste servidor não compile o arquivo, assim no outro servidor o arquivo
// da zona terá um texto "puro"
masterfile-format text;
// Para evitar que vase a versao do Bind, definimos um nome
// Reza a lenda que deixar RR DNS Server seu servidor nunca sofrerá ataques.
version "RR DNS Server";
};
Caso você não queria seu servidor sendo recursivo altere na ACL autorizados deixando apenas 127.0.0.1 e ::1.
Se seu servidor não tiver IPv6? (Que triste rsrsrs) Recomendo que desative o ipv6 no bind.
# vim /etc/default/bind9
Adicione um -4 em OPTIONS.
OPTIONS="-u bind" #para OPTIONS="-4 -u bind"
# vim /etc/bind/named.conf.options
listen-on-v6 { any; };
#para:
listen-on-v6 { none; };
Toda alteração feita no bind para ter efeito é necessário restartar o serviço.
# systemctl restart bind9
# cat /etc/bind/named.conf.options |grep -v "//" > /tmp/named.conf.options ; mv /tmp/named.conf.options /etc/bind/
# named-checkconf /etc/bind/named.conf.options
Se nada retornar é porque não tem nenhum erro. Verifique também o status do bind para ver se o mesmo era rodando.
# systemctl restart bind9 # systemctl status bind9
bind9.service - BIND Domain Name Server Loaded: loaded (/lib/systemd/system/bind9.service; enabled; vendor preset: enabled) Active: active (running) since Fri 2019-07-19 14:17:09 -03; 4s ago Docs: man:named(8) Process: 706 ExecStart=/usr/sbin/named $OPTIONS (code=exited, status=0/SUCCESS) Main PID: 707 (named) Tasks: 4 (limit: 2359) Memory: 11.9M CGroup: /system.slice/bind9.service └─707 /usr/sbin/named -u bind
Fail2Ban + nftables
Fail2Ban é uma estrutura de software de prevenção de intrusões que protege os servidores de computadores contra ataques de força bruta, que opera monitorando arquivos de logs. Sendo o mais comum usado para bloquear endereços IPs selecionados que podem pertencer a hosts que estão tentando violar a segurança.
# apt install nftables fail2ban
Como o iptables está sendo substituído por nftables começando com o Debian Buster, vamos configurar o Fail2Ban para usar o nftables como padrão.
Mas vou ir além em vez de usar o filtro multiport vou setar allports e modifica-lo para que quando uma tentativa de violação acontecer o Fail2Ban crie uma regra de firewall que dropa definitivamente o IP e não apenas fechando a porta do serviço para “invasor”.
# vim /etc/fail2ban/jail.conf
Procure por “banaction = iptables-multiport” e “banaction_allports = iptables-allports” e altere seu valor para “nftables-allports”:
#banaction = iptables-multiport #banaction_allports = iptables-allports banaction = nftables-allports banaction_allports = nftables-allports
Altere o modo de bloqueio em nftables-allports.conf para fazer que ele de um “drop all”.
# vim /etc/fail2ban/action.d/nftables-allports.conf
Procure por nftables_mode = meta l4proto e altere deixando seu valor vazio:
#nftables_mode = meta l4proto <protocol> nftables_mode =
Em nftables-common.conf alteraremos o padrão de reject para drop
# vim /etc/fail2ban/action.d/nftables-common.conf
Procure por “blocktype = reject” e altere seu valor para “drop”.
#blocktype = reject blocktype = drop
Melhorias feitas, precisamos ativar o filtro para ler os logs do bind, porém ao ativar o filtro named-refused me deparei com seu não funcionamento, e quebrando a cabeça descobri que os logs do bind estão diferente e a expressão regular do filtro está errada. Os desenvolvedores do fail2ban já fizeram a correção, mas acredito que irá levar um tempo para o pessoal do Debian fazer um novo empacotamento.
A correção pode ser feita editando o arquivo /etc/fail2ban/filter.d/named-refused.conf
- prefregex = ^%(__line_prefix)s( error:)?\s*client <HOST>#\S+( \([\S.]+\))?: <F-CONTENT>.+</F-CONTENT>$ + prefregex = ^%(__line_prefix)s( error:)?\s*client( @[0-9a-z]+)? <HOST>#\S+( \([\S.]+\))?: <F-CONTENT>.+</F-CONTENT>$
Porém como eu vou ser mais “bruto” no filtro. Vou criar nosso próprio filtro bind9, vamos lá!
# vim /etc/fail2ban/filter.d/bind9.conf
# Fail2Ban filter file for named (bind9.11). # [Definition] # Daemon name _daemon=named # Shortcuts for easier comprehension of the failregex __pid_re=(?:\[\d+\]) __daemon_re=\(?%(_daemon)s(?:\(\S+\))?\)?:? __daemon_combs_re=(?:%(__pid_re)s?:\s+%(__daemon_re)s|%(__daemon_re)s%(__pid_re)s?:) # hostname daemon_id spaces # this can be optional (for instance if we match named native log files) __line_prefix=(?:\s\S+ %(__daemon_combs_re)s\s+)? prefregex = ^%(__line_prefix)s( error:)?\s*client( @[0-9a-z]+)? <HOST>#\S+( \([\S.]+\))?: <F-CONTENT>.+</F-CONTENT>$ failregex = ^(view (internal|external): )?query(?: \(cache\))? '.*' denied\s*$ ^zone transfer '\S+/AXFR/\w+' denied\s*$ ^bad zone transfer request: '\S+/IN': non-authoritative zone \(NOTAUTH\)\s*$ ignoreregex =
Ajustei o tempo de banimento por 24h, você pode ajustar para mais se achar necessário. E “maxretry” que é a quantidade de tentativas para 1.
# vim /etc/fail2ban/jail.d/bind9.conf
[bind9] enabled = true port = domain,953 protocol = tcp logpath = /var/log/named/security.log bantime = 24h maxretry = 1
Vale lembrar que o filtro de SSH já vem ativo por padrão em “/etc/fail2ban/jail.d/defaults-debian.conf”.
Precisamos fazer o bind gerar os logs com tentativas de consultas negadas (denied), incluído logging {…} no arquivo named.conf.
# vim /etc/bind/named.conf
// This is the primary configuration file for the BIND DNS server named.
//
// Please read /usr/share/doc/bind9/README.Debian.gz for information on the
// structure of BIND configuration files in Debian, *BEFORE* you customize
// this configuration file.
//
// If you are just adding zones, please do that in /etc/bind/named.conf.local
logging {
channel security_file {
file "/var/log/named/security.log" versions 3 size 30m;
severity dynamic;
print-time yes;
};
channel file_log {
file "/var/log/named/named.log" versions 2 size 50k;
severity info;
print-time yes;
print-severity yes;
print-category yes;
};
channel errors_syslog {
syslog daemon;
severity warning;
};
category security { security_file; };
category dnssec { errors_syslog; };
category default { file_log; };
category lame-servers { null; };
category edns-disabled { null; };
category resolver { null; };
category unmatched { null; };
};
include "/etc/bind/named.conf.options";
include "/etc/bind/named.conf.local";
include "/etc/bind/named.conf.default-zones";
Crie o diretório onde o bind vai registrar seus logs e de permissão para que possa gravar nesta pasta.
# mkdir /var/log/named/ # chown bind. /var/log/named/
É importante ativar o nftables na inicialização e restartar os serviços para que nossas configurações sejam interpretadas.
# systemctl enable nftables # systemctl restart bind9 # systemctl restart nftables # systemctl restart fail2ban
Para visualizar seu firewall use o comando:
# nft list ruleset
Alguns comandos legais do fail2ban
# fail2ban-client status
Veja quais filtros estão ativos
Status |- Number of jail: 2 `- Jail list: bind9, sshd
fail2ban-client status NOME_FILTRO
Exemplo:
# fail2ban-client status bind9 Status for the jail: bind9 |- Filter | |- Currently failed: 0 | |- Total failed: 2 | `- File list: /var/log/named/security.log `- Actions |- Currently banned: 2 |- Total banned: 2 `- Banned IP list: 71.6.199.23 185.94.111.1 # fail2ban-client status sshd Status for the jail: sshd |- Filter | |- Currently failed: 0 | |- Total failed: 0 | `- File list: /var/log/auth.log `- Actions |- Currently banned: 3 |- Total banned: 3 `- Banned IP list: 142.44.130.186 191.54.227.13 92.63.194.90
Para remover um IP que foi bloqueado:
# fail2ban-client set bind9 unbanip IPADDRESS
Pronto agora já temos um servidor DNS com um nível de segurança bem elevado!
Atualizando ROOT SERVERS
Para finalizar o master vamos fazer uma atualização no root server que na versão do debian 10 buster passou a ser /usr/share/dns/root.hints. A vesão instalada é de 13/03/2019 “last update: March 13, 2019”
Para obter uma versão mais recente, iremos mover nosso arquivo root.hints e baixar um novo.
mv /usr/share/dns/root.hints /usr/share/dns/root.hints.`date +%Y%m%d` wget https://www.internic.net/domain/named.root -O /usr/share/dns/root.hints --no-check-certificate
Pode editar o arquivo /usr/share/dns/root.hints e verificar qual é a ultima atualização. Reinicie o serviço para ter efeito.
systemctl restart bind9 systemctl status bind9
Parabéns! Seu servidor master está pronto!
Fonte
wiki.debian.org/Bind9
blog.remontti.com.br
