Por que os hackers atacariam um servidor DNS com um DoS?
Acordei esta manhã com um servidor reinicializado. O servidor DNS estava funcionando a mais de 100%. Depois de um pouco de trabalho, instalei o fail2ban para bloquear todas essas solicitações.
As próprias solicitações são válidas, apenas repetidas centenas de vezes por segundo. Depois que o bloco obteve muitos (centenas) de IPs, posso ver que estou bloqueando 1 milhão de acessos UDP a cada poucas horas.
Isso é apenas um ataque [D]DoS? (provavelmente considerado dinâmico, pois muitos computadores estão envolvidos e, uma vez bloqueado por tempo suficiente, parece que interrompe as solicitações)
A outra possibilidade em que posso pensar é que o invasor está tentando travar o servidor DNS e obter acesso quando ele reiniciar ou travar todo o computador e tentar conexões com outros serviços. (ou seja, caso você não saiba como instalar seu firewall antes de iniciar seus serviços)
Desde minha última redefinição de firewall, aqui estão minhas estatísticas:
Acessos: 2.346.742
Número de IPs: 473
Vai rápido. Várias centenas de acessos por segundo. O número de IPs não cresce muito, no entanto.
Respostas
A partir do comentário de @Schroeder, fiz algumas pesquisas adicionais e descobri muito mais sobre esse tipo de ataque.
Eu era o alvo!
Em primeiro lugar, parece que sou o alvo do ataque. Por quê? Porque o ataque de amplificação de DNS significa que a porta de origem das solicitações de DNS é definida como 53. Isso possibilita forçar meu DNS a enviar uma resposta não solicitada a outro servidor (consulte o gráfico abaixo). Como tenho menos de 0,1% desses acessos usando essa porta, não acho que meu DNS tenha sido usado para a amplificação, mas sim que era o alvo.
Como funciona o ataque?
O invasor configura um computador com software enviando pacotes UDP para alguns servidores DNS aleatórios solicitando um nome de domínio. O pacote parece normal, exceto pelo fato de que o invasor coloca o endereço IP de um computador diferente em vez de seu endereço IP como origem. O resultado é que o DNS envia a resposta para o computador errado :
10.0.0.1 10.0.0.2 10.0.0.3
+------------+ +------------+ +------------+
| | | | | |
| Attacker +-->| Some DNS +-->| Me |
| | | | | |
+------------+ +--+---------+ +------------+
| ^
v |
+---------+--+ This step is not required, it happens if
| | your DNS is setup to accept recursive
| Master DNS | requests (which is not a good idea)
| |
+------------+
10.0.0.4
No exemplo acima, a solicitação do invasor deve ter 10.0.0.1 como endereço de origem UDP. Mas, em vez disso, o invasor altera seu endereço IP para 10.0.0.3. Como resultado, quando o DNS em 10.0.0.2 recebe o pacote UDP e está pronto para enviar uma resposta, ele envia os dados para 10.0.0.3.
O DNS mestre do domínio será usado se o DNS em 10.0.0.2 não souber nada sobre o nome de domínio que está sendo consultado.
NOTA IMPORTANTE: Isso vale para todos os serviços UDP. O DNS é provavelmente o pior em termos de amplificação, mas o NTP, por exemplo, também pode ser direcionado.
Por que não apenas verificar o endereço de origem?
Não é possível a partir de 10.0.0.2 porque o UDP não se lembra da origem real do pacote.
O que é possível é que os ISPs verifiquem se todos os pacotes que saem de um determinado computador têm o endereço IP desse computador. Alguns sim, eu acho, mas provavelmente não. Tem um pequeno impacto na velocidade ... o que, claro, com uma amplificação de DNS é motivo de riso (a amplificação de DNS tem um efeito muito pior na Internet do que uma pequena verificação das origens do pacote UDP).
A outra coisa pode ser que um usuário ainda consiga se conectar à Internet de forma a ignorar a verificação do ISP. Não sei se e/ou como isso seria possível, mas não me surpreenderia que pudesse ser feito.
Na verdade, isso é muito problemático, pois a origem desses ataques é difícil de rastrear e certamente é por isso que eles ainda ocorrem em massa.
Por que isso é um DDoS?
O pacote para solicitar um registro DNS, que é o que acontece aqui, é muito pequeno, talvez 300 bytes. Portanto, o invasor precisa enviar apenas um pequeno pacote UDP.
A resposta, no entanto, pode ser vários kilobytes de dados. Especificamente, há um domínio que está sendo usado nesses ataques:
peacecorps.gov
e esse domínio retorna mais de 3Kb de dados! (Ele define muitos campos 'TXT' que são usados nesse ataque de amplificação.) É por isso que é chamado de Ataque de Amplificação.
Como resultado, as solicitações do atacante são transformadas em respostas cerca de 10× maiores e o computador que está sendo atacado (10.0.0.3) fica inundado com um grande número de pacotes UDP bastante grandes.
Aqui eu mostro a entrada resultante em iptables
. O primeiro número representa o número de acessos ao meu computador DNS após cerca de 40 minutos (portanto, mais de 10.000 acessos por minuto...):
pkts bytes target prot opt in out source destination
61637 4376227 DROP udp -- eno1 * 0.0.0.0/0 0.0.0.0/0 udp dpt:53 STRING match "|0a7065616365636f72707303676f76|" ALGO name bm TO 65535
Observe também como a string foi totalmente transformada em números hexadecimais.
Uma solicitação HTTP não seria ainda pior?!
HTTP 0.9/1.0/1.1/2 usa TCP, que é um protocolo bidirecional e nenhuma amplificação pode ser gerada com TCP. ou seja, o TCP é interrompido se você não se conectou corretamente com o handshake completo.
HTTP/3, no entanto, apresenta o protocolo QUIC , que é HTTP sobre pacotes UDP. Até agora não ouvi falar de grandes problemas com o QUIC, mas o protocolo mudou muito nos últimos 6-7 anos e ainda não foi amplamente implementado. Aqui está um artigo sobre o fato de o QUIC ter construído recursos para evitar ataques de amplificação, então há esperança de que isso tenha sido resolvido.
Algumas pessoas estão falando sobre o uso de HTTP para consultar nomes de domínio. (DoH — Domínio sobre HTTP). Espero que isso não seja implementado usando o QUIC ...
Como posso corrigir o problema?
A amplificação ocorre porque seu DNS está configurado para aceitar solicitações de nomes de domínio que você não controla (ou seja, domínios dos quais você não é o proprietário).
O BIND tem uma opção que permite fazer amplificação, que é chamada de recursão no jargão do DNS. Esse recurso agora está desativado por padrão, mas você pode tê-lo ativado (por engano?).
Aqui está a configuração errada :
allow-recursion { any; };
O que você quer é usar as configurações corretas :
trusted-servers { 192.0.2.4; } // list all your trusted servers
allow-recursion { trusted-servers; };
Isso fará com que seu servidor negue automaticamente todas essas solicitações. Portanto, se você não estiver peacecorps.gov
e receber tal solicitação, o BIND simplesmente parará ali e escreverá uma nota em seus logs de DNS sobre a solicitação negada.
Eu poderia bloquear o IP dessas solicitações?
Sim. Comecei fazendo isso porque meu servidor estava rodando bem acima de 100% em tempo de CPU. No entanto, pode não ser sábio fazê-lo. Na imagem acima, você pode ver que seu servidor DNS fica entre um invasor e uma vítima. Se você bloquear o endereço IP de origem, não é o IP do invasor que você está bloqueando, é o da vítima. Isso significa que você está realmente impedindo que a vítima veja seus nomes de domínio e faça solicitações legítimas. Provavelmente não é isso que você quer!
A princípio, gerei uma mensagem de log do meu firewall. Se eu detectasse 5 ou mais solicitações para a porta 53 (UDP) do mesmo endereço IP em um curto período de tempo (5 segundos), bloquearia o endereço IP. Para fazer isso, eu usei fail2ban
.
Primeiro, tenho um filtro que detecta os links com UDP e a porta 53 como destino:
# Filter: /etc/fail2ban/filter.d/named-fast-requests.conf
[Definition]
failregex = \sIN=[a-z0-9]+ .* SRC=<HOST> .* PROTO=UDP .* DPT=53\s
Em segundo lugar, tenho uma prisão que fornece os outros parâmetros:
# Jail: /etc/fail2ban/jail.d/named-fast-requests.conf
[named-fast-requests]
enabled = true
filter = named-fast-requests
action = named-action[scheme=all,period=year,reason=named fast requests]
logpath = /var/log/iptables/iptables.log
maxretry = 5
findtime = 5
bantime = 1036800
O ponto principal aqui é o maxretry
e findtime
que são definidos 5 vezes em 5 segundos ou menos. Quando isso acontece, eu bloqueio o arquivo <HOST>
.
Você vai querer atualizar a ação com suas próprias coisas. Eu uso minha própria iplockferramenta aqui. O comando que uso na ação:
actionban = /usr/sbin/iplock -s named -b <ip>
Por padrão, fail2ban usa iptables
diretamente. Pesquise suas ações para ver como isso é feito.
Não seja a fonte de amplificação
Você deve bloquear solicitações em que a porta UDP de origem é menor que 1024. Elas não são válidas. Se você oferecer um servidor, a porta 53 será a porta de destino, não a de origem.
iptables -I INPUT 123 -i eth0 -p udp -m udp --sport 0:1023 -j DROP
ATENÇÃO: substitua a posição (123) pelo número correto!
Essa regra diz que, para qualquer pacote UDP recebido em eth0
, que tenha uma porta de origem entre 0 e 1023, descarte o pacote. Isso impede que alguém use seu servidor DNS para amplificação. No entanto, ele não protege seu próprio servidor da amplificação de outros. Observe que, mesmo com a allow-recursion
configuração adequada, você não impediria um ataque de amplificação se o invasor selecionasse corretamente um de seus nomes de domínio para o ataque.
Observação: se você especificar um servidor de nomes diferente para resolver nomes de domínio em seu computador, convém abrir essas conexões antes de bloquear tudo, desde a porta 0 até 1023. Isso seria mais ou menos assim:
iptables -I INPUT 123 -i eth0 -p udp -m udp --sport 53 -s 8.8.8.8 \
-d <your-static-ip> -j ACCEPT
Estes são os dados retornados do servidor de nomes 8.8.8.8, que você provavelmente deseja receber. Não é provável que seu provedor ou algum outro servidor de nomes oficial seja a fonte direta de um ataque UDP. Se você não tiver um endereço IP estático, não precisará incluir a -d
opção.
No entanto, provavelmente é muito melhor usar o ESTABLISHED
recurso que agora está disponível para mensagens UDP (já faz um tempo, mas me lembro de uma época em que não estava disponível...):
iptables -I INPUT 123 -i eth0 -p udp -m state \
--state ESTABLISHED,RELATED -m udp -d <your-static-ip> -j ACCEPT
Isso significa que você aceitará automaticamente as respostas do seu provedor de servidor de nomes de domínio, pois o firewall saberá que você enviou uma solicitação e deseja aceitar as respostas. Esta regra deve aparecer antes da DROP
regra acima.
Elimine solicitações indesejadas com antecedência
Obviamente, ter o BIND aceitando todos esses pedidos peacecorps.gov
não é algo que alguém queira. Na verdade, você pode bloqueá-los diretamente no seu firewall. Isso funciona porque os pacotes UDP não são criptografados, portanto, o nome do domínio fica visível.
Aqui está uma regra que pode ser usada para bloquear essas solicitações de nome de domínio:
sudo iptables -I INPUT 123 -i eno1 -p udp -m udp --dport 53 \
-m string --hex-string "|0A|peacecorps|03|gov|" --algo bm -j DROP
Obviamente, se o seu DNS tiver qualquer domínio ou subdomínio, incluindo "peacecorps.gov", ele não deve usar essa iptables
regra. Para a maioria de nós, embora deva ser raro.
A --hex-string
opção permite que você especifique uma string. A forma como é definido no pacote UDP usa uma forma de P-string (tamanho + dados). Como "peacecorps" tem 10 caracteres, colocamos 0x0A logo antes dele. Novamente, o "gov" tem três letras, então usamos 0x03. Se usássemos a string "peacecorps.gov", não funcionaria, pois o ponto não corresponderia ao byte 0x03. No entanto, o primeiro tamanho é opcional (embora você corresponda a qualquer coisa que pareça igual, como "bestpeacecorps").
Ter essa regra salvará seu serviço de nome de domínio de uma tonelada de tráfego totalmente indesejado.
Atualização: embora o ataque tenha parado cerca de duas semanas depois que postei minha pergunta, o problema "peacecorps.gov" ainda ocorre cerca de 10 vezes por dia.
Fonte:https://defragged.org/2020/05/20/tips-and-tricks-blocking-dns-requests-via-iptables/
Depurando seu DNS
Para ver qual consulta seu servidor DNS recebe e responde, você pode executar os seguintes comandos em seu console:
sudo rndc querylog
Agora olhe para os logs, geralmente aqui:
less /var/log/named.log
GObserve a parte inferior (pressione less
) e você deve começar a ver consultas de IPs remotos. Os logs incluem o nome de domínio que está sendo verificado. É muito prático, especialmente se você esqueceu de inserir alguns de seus próprios nomes de domínio em seu DNS secundário ou terciário.