bind: geçersiz özyinelemeli sorgular için kara delik?


13

Birkaç etki alanı için yetkili ad sunucusu olduğundan herkesin erişebildiği bir ad sunucum var .

Şu anda sunucu ANYisc.org, mature.net ve benzeri için sahte tip taleplerle doludur (bu bilinen bir dağıtılmış DoS saldırısıdır ).

Sunucu BIND'ı çalıştırır ve allow-recursionbu isteklerin reddedilmesi için LAN'ımı ayarladı. Bu gibi durumlarda sunucu sadece ile yanıt authorityve additionalbölümler kök sunucularını atıfta.

BIND'ı yanıt göndermeden bu istekleri tamamen yok sayacak şekilde yapılandırabilir miyim?

Yanıtlar:


5

Aynı sorunla karşı karşıya kaldım, tüm özyinelemeli istekleri yoksaymayı seçtim. Tüm çözümleyiciler, sunucumu yetkili bir sunucu olarak kullanmak istediklerinde özyinelemeli olmayan bir sorgu gönderir. Yalnızca benim durumumda yanlış yapılandırılmış istemciler ve saldırganlar yinelemeli sorgular kullanır.

Ne yazık ki BIND'in bunu yapmasına izin vermenin bir yolunu bulamadım, ancak iptables'ın sizin için yeterince iyi olması durumunda,

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

Hayır, bu kural yetkili türdeki istekleri de engeller (en azından makinemde). Görünüşe göre her türlü DNS isteğini engelliyor.
Udo G

İki kez kontrol ettim ve tam olarak bu kuralı kullanıyorum. İşte canlı sunucudan bir kes ve yapıştır. Komut: iptables -t raw -S PREROUTING. Çıktı:, -P PREROUTING ACCEPTardından gelir -A PREROUTING -i eth0 -p udp -m udp --dport 53 -m string --hex-string "|01000001000000000000|" --algo kmp --from 30 --to 65535 -j DROP. Doğru çalıştığını test ettim host -ar exampledomain.com dns-server.example.net. Tabii -rseçeneği ekleyene kadar doğru çalışmadı .
pino42

Tamam, -rseçenek fark yaratıyor. Şahsen basit hostsorguların artık işe yaramadığını sevmiyorum ve bu çok kafa karıştırıcı olabilir. Bu muhtemelen geçerli (şimdiye kadarki en iyi) bir cevap ve ben size ödül vereceğim, çünkü OUTPUT'u filtreleyerek kendi yaklaşımımı kullanmaya devam etsem bile süresi dolmak üzere.
Udo G

Teşekkürler! Daha iyi bir çözümle karşılaşırsam, paylaştığımdan emin olurum. Sana katılıyorum: bu bir hack. Çalışan bir, ama yine de bir kesmek.
pino42

2

Ben denemek istiyorum:

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

İstemcileri kök sunuculara yönlendiren yanıtlar "yönlendirme" bölgesi tarafından denetlenir. Bu, onlara cevap vermemesini söylemelidir.

Bu, Bind9 belgelerinde ima edilmektedir: http://ftp.isc.org/isc/bind9/cur/9.9/doc/arm/Bv9ARM.ch06.html#id2592674

"none"Yerel alt ağınızla değiştirmek için ile değiştirebilirsiniz .

Zaten bir zone "."bildiriminiz varsa, basitçe ekleyin allow-query "none";.


zone "." { type hint; file "/etc/bind/db.root"; };Kök sunucuları listeleyen db.root ile bir bildirim var . Bu bildirimin kaldırılması yabancı etki alanlarına yönelik yanıtları durdurur ancak sunucu yine de "sunucu hatasıyla" yanıt verir ve bu nedenle DoS için kullanılabilir.
Udo G

@UdoG: eklemekte denediniz allow-query "none";için zone "."yapılandırma?
freiheit

Bu, sadece bol olması gereken olsa da, yukarı akış bant genişliğinden tasarruf ediyor gibi görünüyor. Sizin düzeltmenizle, saldırgan sunucularınızı aşağı akış bant genişliği ve işleme gücünden zaten
tüketti

@TheLQ: Soru bunun bir DDoS saldırısı olduğu anlamına geliyor. Yaygın DNS tabanlı DDoS saldırısı, hedefin sahte IP'si ile DNS sorguları göndermektir. DNS yanıt paketi sorgudan daha büyük olduğundan bir çarpan sağlar. Sunucunuz çok daha büyük bir paketle yanıt vermiyorsa, sunucunuzu saldırıda kullanma nedenini ortadan kaldırdınız.
freiheit

@UdoG: Kök sunuculara yönlendirme muhtemelen birkaç yüz bayt iken sunucu hatası paketi yalnızca 31 ila 32'dir. Sunucunuzun yanıtı sorgu ile aynı boyuttaysa veya yalnızca biraz daha büyükse, sunucunuz bir DNS DDoS saldırısında işe yaramaz, çünkü saldırganlar hedeflerine göndermenizi sağlayacak kadar bant genişliği tüketir. Muhtemelen iyi yapılandırılmış bir dizi yetkili ad sunucusuna (google'ınki gibi) karşı test ettim ve "özyineleme istendi ancak mevcut değil" şeklinde yanıtladım.
freiheit

1

Genellikle şunu öneririm:

Bağlama günlüklerini açın ve yanıt reddedilen ips'leri kaydedin. Fail2ban programını yükleyin, kara delik eylemi ekleyin: http://pastebin.com/k4BxrAeG (/etc/fail2ban/actions.d dosyasındaki kuralı koy)

/Etc/fail2ban/filter.d dosyasında böyle bir şeyle bağlayıcı filtre dosyası oluşturun (hata ayıklama gerekir!)

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

Fail2ban.conf dosyasını düzenleyin, bölüm ekleyin:

[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

Umarım bu yardımcı olur!


YAPILACAKLAR: bağlama günlük dosyası örneği.
Andrei Mikhaltsov

1

Temel fikir, bind'in DNS yanıtını Reddedildi olarak sınıflandırmasına izin verdikten sonra iptables'ı kullanarak Reddedildi'yi sessizce yoksayıldı.

Refused, named.conf options bölümündeki kolay bölümdür:

allow-recursion { none;};

Veya elbette yerel istisnalar için en sevdiğiniz EKL'ler ...

Sonraki deli iptables sihirli, ayarlamak veya gerektiği gibi "-o eth0" kaldırmak. Bu komut, UDP'den önce standart 20 bayt IPv4 katman üstbilgisini varsayar.

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

Aşağıdaki bitler ayarlanmış olarak DNS yanıtının bayraklar alanındaki bu tuşlar

  • DNS Yanıtı
  • Yinelenen sorgu
  • Yanıt kodu reddedildi

Kural test için bazı geri bildirimler almak için eşleştiğinde hata ayıklama "hata gönderme yanıtı: ana bilgisayara erişilemiyor" hatası çalışırken çalışan günlük iletisi.

Bu biraz anlamsız bir egzersiz olduğunu itiraf etmeliyim. Herhangi bir amplifikasyon yoksa, saldırgan TCP SYN'yi de kolayca yansıtabilir. Sonuçta DNS, TCP kullanmak veya Eastlake'in DNS çerezlerini dağıtmaktan başka geçerli bir çözüm değildir.


0

İsc.org dizesini veya bunun için onaltılık dizeyi engellemeyi denediniz mi?

Bu benim için çalıştı:

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


Sunucunun yanıt vermesi gereken tüm etki alanları için onaltılık dizeleri tanımlamak, bunlara izin vermek için yukarıdakileri yapmak ve diğer tüm udp / 53 trafiğini bırakmak daha iyi olmaz mıydı?
freiheit

Şu anda kök sunuculara atıfta bulunan UDP yanıtlarını zaten engelliyorum: iptables -A OUTPUT -p udp -m string -hex-string "|726f6f742d73657276657273|" –algo bm –to 65535 -j DROPAma gerçekten mümkünse sadece BIND yapılandırmasına dayanan bir çözümü tercih ederim.
Udo G

bu zayıf. etki alanı olarak istediğiniz her şeyi yaratabilirsiniz. şu anda bu sorunla karşı karşıyayız ve bunu statik adla engellemenin yolu değil'bnrexex.www.sf97.net/A/IN' 'whzpkacpxpiuycm.www.tpa.net.cn/A/IN'
3h4x

0

Bu saldırıya Kuvvetlendirilmiş Hizmet Reddi denir. Bağlamayı doğru şekilde yapılandırmalısınız, ancak bu trafik ilk etapta bağlantınıza ulaşmamalıdır. Ağınızda yapabilen ilk ağ cihazında engelleyin. Ben aynı sorunu vardı ve onunla deafult snort kural ele:

msgstr: "PROTOCOL-DNS ANY - potansiyel DoS türünde aşırı sorgular"; byte_test: 1,! &, 0xF8,2; içerik: "| 00 00 FF 00 01 |"; algılama_filter: by_src, sayım 30, saniye 30; meta veriler: hizmet dns; başvuru: url, foxpa.ws / 2010/07/21 / isc-org-dns-ddos /; classtype: attemptted-dos; sid : 21817; rev: 4;)


0

İlk olarak, bunun eski bir soru olduğunu biliyorum ama ...

Kendi yetkili, özyinelemeli olmayan DNS sunucumu onlarca yıldır çalıştırıyorum, ancak yeni bir ISS'ye geçtiğim zamana kadar hiçbir DNS tabanlı DDoS saldırısında kurban olmadım. Binlerce sahte DNS sorgusu günlüklerime su bastı ve gerçekten rahatsız oldum - sunucum üzerindeki etkisi hakkında çok fazla değil, daha çok günlüklerimi ve istismar edilen rahatsızlık hissini karıştırdı. Saldırganın DNS'imi “ Yetkili Ad Sunucusu saldırısı ” nda kullanmaya çalıştığı görülüyor .

Bu nedenle, iç ağımla özyinelemeli sorguları (diğerlerini reddederek) sınırlasam da, sahte döngülere (günlüklerimde daha az dağınıklık, daha az dağınıklık, daha az karışıklık) geri göndermek yerine iptables'daki iples eşleşmesine CPU döngülerimi harcadığımı düşündüm. ağ trafiği ve daha yüksek bir memnuniyet düzeyi).

Herkesin yaptığı gibi yaparak başladım , hangi etki alanı adlarının sorgulandığını bulun ve bu etki alanında hedef DROP ile bir dize eşleşmesi oluşturdum. Ama çok geçmeden fark ettim ki, her biri CPU döngüsü tüketen çok sayıda kuralla karşılaşacağım. Peki ne yapmalı? Özyinelemeli bir ad sunucusu çalıştırmadığım için, yetkili olduğum gerçek bölgelerdeki eşleştirmeyi yapabileceğimi ve diğer her şeyi bırakabileceğimi düşündüm.

Iptables'daki varsayılan politikam KABUL EDİYOR, politikanız DROP ise, aşağıdaki çözümü kullanmak istiyorsanız muhtemelen bazı ayarlamalar yapmanız gerekir.

Bölge yapılandırmamı ayrı bir dosyada (/etc/bind/named.conf.local) saklıyorum, bunu örnek olarak kullanalım:

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;
};

İlk iki bölgemdeki “// Private” yorumuna dikkat edin, bunları aşağıdaki kodlarda geçerli bölgeler listesinden çıkarmak için kullanıyorum.

#!/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";

Yukarıdaki komut dosyasını bölge yapılandırma dosyasıyla bağımsız değişken olarak çalıştırın.

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

Çıkışı bir komut dosyasına kaydedin, bir kabuğa ekleyin veya yeni zinciri oluşturmak ve tüm geçersiz DNS sorgularını filtrelemeye başlamak için terminalinize kopyalayıp yapıştırın.

yeni zincirdeki her kuralda paket (ve bayt) sayaçlarını görmek için / sbin / iptables -L DNSvalidate -nvx komutunu çalıştırın (daha verimli hale getirmek için çoğu paket içeren bölgeyi listenin en üstüne taşımak isteyebilirsiniz).

Umarım birisi bunu faydalı bulabilir :)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.