で書いたように自宅サーバで、広告避けオープンDNSリゾルバを運用しているが、DoS攻撃と思われるクエリがよく来ている。
自分のリゾルバは広告除去目的の限定的なオープンリゾルバなので、今回利用されたドメインへのクエリを一時的に禁止してみる。
zone "ripe.net" IN {DNSリゾルバにセカンダリを正しく設定してあればそっちに問い合わせするので問題ない。高々最初のアクセスのレスポンスが1秒ほど遅くなるだけ。
type master;
file "block.db;
allow-query {none;};
};
BIND9にはunboundのdenyに相当する設定が無いので、refusedを返さず無視することが出来ない。仕方ないのでiptablesルールで何とかする。
コードが5=REFUSEDなレスポンスをDROPするルールを追記して対応
-A OUTPUT -p udp -m udp --sport 53 -m u32 --u32 "0>>22&0x3C@8&0x0F=5" -j DROP
上の2つで弾けているはずが、なかなかDoSのクエリがとまらなかったので、テストを兼ねてhashlimitルールでINPUT側をフィルタしてみた
-A INPUT -p udp -m udp --dport 53 -m state --state NEW -j ACCEPTだったものを
-A INPUT -p tcp -m tcp --dport 53 -m state --state NEW -j ACCEPT
-N DNSCHECKINに置き換え。これでほとんどDROPできた。
-A INPUT -p udp -m udp --dport 53 -m state --state NEW -j DNSCHECKIN
-A INPUT -p tcp -m tcp --dport 53 -m state --state NEW -j DNSCHECKIN
-A DNSCHECKIN -m hashlimit --hashlimit-upto 1/s --hashlimit-burst 50 --hashlimit-mode srcip --hashlimit-name DNSDENY --hashlimit-htable-expire 300000 -j ACCEPT
-A DNSCHECKIN -j DROP
最初に50クエリまで許可して、以後1クエリ/sに制限。リゾルバのキャッシュが正しく効いてる普通のユーザーなら問題は無いはず。NATで複数人が回線共有していた場合残念なことになるが、そもそんな状況の人はオープンリゾルバ使わないだろうから「NATの中の人などいない」と割り切る。
(3G回線の人ならroot化済みでhostsでブロックしてるだろうし)
セカンダリにはGoogle提供の8.8.8.8あたりをどうぞ。