bind: blackhole per query ricorsive non valide?

Ho un server di nome che è accessibile a livello pubblico in quanto è il server di nome autorevole per un paio di domini .

Attualmente il server è inondato di tipo falso ANY richiesta per isc.org, ripe.net e simili (che è un noto attacco DoS distribuito ).

  • Perché bind lentamente rispetto ai fornitori pubblici dns
  • Inserire il slave lento per aggiornare le zone
  • Quali sono tutte le possibili cause del messaggio di errore "Un controller di dominio di Active Directory (AD DC) per il dominio ..."?
  • samba_dnsupdate dns_tkey_negotiategss: TKEY è inaccettabile
  • DDOS da diversi IP con una connessione
  • Windows Server 2008, un DDoS molto piccolo è in grado di uccidere il mio server
  • Il server esegue BIND e ha impostato la allow-recursion nella mia LAN in modo che queste richieste vengano rifiutate. In questi casi il server risponde solo con authority e sezioni additional che si riferiscono ai server root.

    Posso configurare BIND in modo da ignorare completamente queste richieste senza submit una risposta affatto?

    7 Solutions collect form web for “bind: blackhole per query ricorsive non valide?”

    Di fronte allo stesso problema, ho scelto di ignorare tutte le richieste ricorsive. Tutti i resolver inviano una query non ricorsiva quando vogliono utilizzare il server come server autorevole. Solo i client e gli aggressori misconfigurati, nel mio caso, utilizzano query ricorsive.

    Purtroppo non ho trovato un modo per far BIND farlo, ma nel caso che iptables sia abbastanza buono per te, ho usato

     iptables -t raw -I PREROUTING -i eth0 -p udp --destination-port 53 \ -m string --algo kmp --from 30 \ --hex-string "|01000001000000000000|" -j DROP 

    Proverei:

     zone "." { type redirect; allow-query "none"; } 

    Le risposte che fanno riferimento ai client ai server root vengono controllate dalla zona "reindirizzamento". Questo dovrebbe dirle di non rispondere a quelle.

    Ciò è accennato nei documenti di Bind9: http://ftp.isc.org/isc/bind9/cur/9.9/doc/arm/Bv9ARM.ch06.html#id2592674

    Potresti sostituire "none" con la tua substring locale.

    Se hai già una zone "." dichiarazione, aggiungi semplicemente allow-query "none"; ad esso.

    In generale, vorrei suggerire:

    Attiva i registri di associazione e registri ips che vengono rifiutati. Installare il programma fail2ban, aggiungere l'azione blackhole: http://pastebin.com/k4BxrAeG (regola la regola nel file /etc/fail2ban/actions.d)

    Crea file di filter di collegamento in /etc/fail2ban/filter.d con qualcosa di simile (richiede il debug!)

     [Definition] failregex = ^.* security: info: client #<HOST>: query \(cache\) .* denied 

    Modifica fail2ban.conf, aggiungere sezione:

     [bindban] enabled = true filter = bind # "bantime" is the number of seconds that a host is banned. bantime = 6000 # A host is banned if it has generated "maxretry" during the last "findtime" # seconds. findtime = 60 # "maxretry" is the number of failures before a host get banned. maxretry = 150 action = blackhole logpath = /var/log/named.log 

    Spero che questo aiuterà!

    L'idea di base consente di classificare la risposta DNS come Refused quindi utilizzare iptables per convertire Refused in silently ignored.

    Refused è la parte più facile nella sezione delle opzioni named.conf:

     allow-recursion { none;}; 

    O naturalmente i tuoi ACL preferiti per le eccezioni locali …

    Next magia pazzo iptables, regolare o rimuovere "-o eth0" se necessario. Questo command assume l'intestazione di layer standard di 20 byte IPv4 prima di UDP.

     iptables -A OUTPUT -o eth0 -p udp --sport 53 -m string --from 30 --to 32 --hex-string "|8105|" --algo bm -j DROP 

    Queste chiavi sul field flags della risposta DNS con i seguenti bit impostati

    • Risposta DNS
    • Richiesta ricorsiva
    • Codice di risposta rifiutato

    Messaggio di registro noto che esegue l'associazione nel debug "errore di invio della risposta: host non raggiungibile" quando la regola corrisponde per avere qualche feedback per il test.

    Devo ammettere che questo è un esercizio un po 'inutile. Se non esiste alcuna amplificazione, un attaccante potrebbe anche riflettere facilmente il TCP SYN. In ultima analisi, il DNS non è semplicemente una soluzione valida diversa dall'uso di TCP o nella distribuzione di cookie DNS di Eastlake.

    Hai provato a bloccare string isc.org o bloccare la string esadecimale per esso?

    Questo ha funzionato per me:

    iptables -A INPUT -p udp -m string –hex-string "| 03697363036f726700 |" –algo bm -j DROP

    Questo attacco si chiama Denial of Service Amplified. Dovresti configurare il collegamento correttamente ma che il traffico non dovrebbe arrivare al tuo legame in primo luogo. Bloccarlo sul primo dispositivo di networking che è in grado di farlo nella tua networking. Ho avuto lo stesso problema e lo ho affrontato con la regola di sordità sorda:

    allarme udp $ EXTERNAL_NET qualsiasi -> $ HOME_NET 53 (msg: "PROTOCOLLO-DNS query eccessive di tipo ANY – potenziale DoS"; byte_test: 1,! &, 0xF8,2; contenuto: "| 00 00 FF 00 01 |"; detection_filter: traccia by_src, count 30, secondi 30; metadati: servizio dns; riferimento: url, foxpa.ws / 2010/07/21 / thwarting-the-isc-org-dns-ddos /; classtype: tentato-dos; sid : 21817; rev: 4;)

    In primo luogo, so che è una vecchia domanda ma …

    Ho eseguito per decenni il mio autoritativo server DNS non ricorsivo per decenni, ma non sono mai stato vittima in alcun attacco DDoS basato su DNS – finora, quando ho passato a un nuovo ISP. Migliaia di domande DNS ingiallite hanno inondato i miei registri e sono rimasto veramente irritato – non tanto sull'impatto sul mio server, quanto sul fatto che ha ingombrato i miei registri e la sensazione scomoda di essere abusata. Sembra che l'aggressore tenta di utilizzare il mio DNS in un attacco " Autorevole Nome Server ".

    Così ho capito che, anche se limiti le ricerche ricorsive alla mia networking interna (negando tutte le altre), preferisco trascorrere i loops di CPU in corrispondenza di stringhe in iptables che submit risposte negative agli indirizzi IP spoofed (less confusione nei miei log, less traffico di networking e un livello di soddisfazione più elevato del mio).

    Ho iniziato a fare come tutti gli altri sembrano fare , scoprire quali nomi di dominio è interrogato e ha creato una corrispondenza di stringhe su quel dominio con un target DROP. Ma presto ho capito che avrei finito con una grande quantità di regole, ognuno dei quali consumerebbe loops di CPU. Quindi che si fa? Dal momento che non ho eseguito un server di nomi ricorsivi ho pensato che potrei fare la corrispondenza sulle zone effettive che sono autorevole e lasciare tutto il resto.

    La mia politica predefinita in iptables è ACCEPT, se la tua politica è DROP probabilmente devi fare alcune modifiche se desideri utilizzare la seguente soluzione.

    Conservo la mia configuration di zona in un file separato (/etc/bind/named.conf.local), usiamo questo come esempio:

     zone "1.168.192.in-addr.arpa" { // Private type master; allow-query { 192.168.1.0/24; 127.0.0.1; }; allow-transfer { 127.0.0.1; }; file "/etc/bind/db.192.168.1"; }; zone "home.example.net" { // Private type master; allow-query { 192.168.1.0/24; 127.0.0.1; }; allow-transfer { 127.0.0.1; }; file "/etc/bind/pri/db.home.example.net"; }; zone "example.net" { type master; file "/etc/bind/pri/db.example.net"; allow-transfer { 127.0.0.1; 8.8.8.8; }; }; zone "example.com" { type slave; masters { 8.8.8.8; }; file "sec.example.com"; allow-transfer { 127.0.0.1; }; notify no; }; zone "subdomain.of.example.nu" { type slave; masters { 8.8.8.8; }; file "sec.subdomain.of.example.nu"; allow-transfer { 127.0.0.1; }; notify no; }; 

    Notare il commento "// Privato" sulle mie prime due zone, lo uso nel seguente script per escluderli dall'elenco delle zone valide.

     #!/usr/bin/perl # zone2iptables - Richard Lithvall, april 2014 # # Since we want to match not only example.net, but also (for example) # www.example.net we need to set a reasonable maximum value for a domain # name in our zones - 100 character should be more that enough for most people # and 255 is the absolute maximum allowed in rfc1034. # Set it to 0 (zero) if you would like the script to fetch each zone (axfr) # to get the actual max value. $maxLengthOfQueryName=255; $externalInterface="eth1"; print "# first time you run this, you will get error on the 3 first commands.\n"; print "# It's here to make it safe/possible to periodically run this script.\n"; print "/sbin/iptables -D INPUT -i $externalInterface -p udp --dport 53 -j DNSvalidate\n"; print "/sbin/iptables -F DNSvalidate\n"; print "/sbin/iptables -X DNSvalidate\n"; print "#\n"; print "# now, create the chain (again)\n"; print "/sbin/iptables -N DNSvalidate\n"; print "# and populate it with your zones\n"; while(<>){ if(/^zone\s+"(.+)"\s+\{$/){ $zone=$1; if($maxLengthOfQueryName){ $max=$maxLengthOfQueryName; } else { open(DIG,"dig -t axfr +nocmd +nostats $zone |"); $max=0; while(<DIG>){ if(/^(.+?)\.\s/){ $max=(length($1)>$max)?length($1):$max; } } close(DIG); } printf("iptables -A DNSvalidate -m string --from 40 --to %d --hex-string \"",($max+42)); foreach $subdomain (split('\.',$zone)){ printf("|%02X|%s",length($subdomain),$subdomain); } print("|00|\" --algo bm -j RETURN -m comment --comment \"$zone\"\n"); } } print "# and end the new chain with a drop\n"; print "/sbin/iptables -A DNSvalidate -j DROP\n"; print "# And, at last, make the new chain active (on UDP/53)\n"; print "/sbin/iptables -A INPUT -i $externalInterface -p udp --dport 53 -j DNSvalidate\n"; 

    Esegui lo script di cui sopra con il file di configuration della zona come argomento.

     root:~/tmp/# ./zone2iptables.pl /etc/bind/named.conf.local # first time you run this, you will get error on the 3 first commands. # It's here to make it safe/possible to periodically run this script. /sbin/iptables -D INPUT -i eth1 -p udp --dport 53 -j DNSvalidate /sbin/iptables -F DNSvalidate /sbin/iptables -X DNSvalidate # # now, create the chain (again) /sbin/iptables -N DNSvalidate # and populate it with your zones iptables -A DNSvalidate -m string --from 40 --to 297 --hex-string "|07|example|03|net|00|" --algo bm -j RETURN -m comment --comment "example.net" iptables -A DNSvalidate -m string --from 40 --to 297 --hex-string "|07|example|03|com|00|" --algo bm -j RETURN -m comment --comment "example.com" iptables -A DNSvalidate -m string --from 40 --to 297 --hex-string "|09|subdomain|02|of|07|example|02|nu|00|" --algo bm -j RETURN -m comment --comment "subdomain.of.example.nu" # and end the new chain with a drop /sbin/iptables -A DNSvalidate -j DROP # And, at last, make the new chain active (on UDP/53) /sbin/iptables -A INPUT -i eth1 -p udp --dport 53 -j DNSvalidate 

    Salvare l'output in uno script, piparla in una shell o copiare e incollarla nel tuo terminal per creare la nuova catena e iniziare a filtrare tutte le query DNS non valide.

    eseguire / sbin / iptables -L DNSvalidate -nvx per visualizzare i contatori dei pacchetti (e byte) su ciascuna regola della nuova catena (si consiglia di spostare la zona con la maggior parte dei pacchetti in cima all'elenco per renderla più efficiente).

    Nella speranza che qualcuno potrebbe trovare questo utile 🙂

    Suggerimenti per Linux e Windows Server, quali Ubuntu, Centos, Apache, Nginx, Debian e argomenti di rete.