DNSサーバへの攻撃に対しfail2banを導入したが無意味だったという話

きっかけ

オープンリゾルバ-になっていて攻撃喰らった話 で出再帰的問い合わせを無効にしたのですが、その後も続く大量アクセスがウザい。
なのでpostfixやdovecot保護に利用しているfail2banを使おうと思いました。

ハマったポイント

ハマったポイントは3箇所。
①ログの出力形式
②TCPをブロックしていた為、全く攻撃を防げなかった。
③fail2banのログにalready ban が大量に出てしまう

ログの出力形式

fail2banではnamed用のフィルタがすでに用意されているのだが、namedのログ出力形式が異なるとうまくひっかからない。
わたしはdefault_debugというデフォルトで定義されているチャネルを使っていたが、fail2banで指定されている形式に変更した。

logging {
    channel security_file {
       file "data/named.run" versions 3 size 30m;
        severity dynamic;
        print-time yes;
    };
    category security {
        security_file;
    };
};

channel security_fileで世代数とかサイズとか、出力するログレベルなどを定義し、securityカテゴリを選択する。
細かいことは下記サイトを見るとよい。
http://donaisei.blog53.fc2.com/blog-entry-10.html
これでフィルタにひっかかるようになった。
fail2ban-regexっていうので試験できる。

fail2ban-regex /var/named/data/named.run /etc/fail2ban/filter.d/named-refused.conf

TCPをブロックしていた為、全く攻撃を防げなかった

UDPに変更して解決。
何気にこの考えに辿り着くまでに時間かかった。
セキュリティグループでTCP53を防いでもアクセスが止まなかったことで気づいた。
ググったのだが、DNSでもパケットサイズがでかくなるとUDPではなくTCPでやり取りするようになるようだ。
また、ゾーンファイル転送はTCPでやるようなので、TCP53ポートは開けておくことにした。

fail2banのログにalready ban が大量に出てしまう

これも解明まで時間かかった。
本当に信じられないほど大量(恐らく数千とか)のipからアクセスが来てbanがfail2banのログに連打されるのだが、already banのような記述も大量に出ていた。
え、banできていないの?と思いiptablesを確認したのだが、大量登録されているせいでbanされているのかどうかすらわからない。
ただ、iptablesに全く書き込めていないわけではなく、iptables –listとかやると大量のホストがbanされているはずなのだが・・・。
そこで仮説を立てた。
fail2banのbanリストには登録されているが、iptablesへの書き込みが間に合っていない。
だからbanリストにあるがアクセスが通ってしまい、already banが表示されているのではないのかと。※fail2banがbanリストを持っているかどうかわかっていなかったが持っているだろうと仮定した
そこでふと思ったのが、メール送付がボトルネックになっているのでは?と思った。
banと同時に個人メアドにメールを飛ばすように設定していたのだ。

それを止めたら途端にalready banが表示されなくなり、きれいにbanの行が続くようになった。

2020-08-23 08:01:32,165 fail2ban.actions        [24665]: NOTICE  [named-refused] Ban 68.14.40.241
2020-08-23 08:01:34,222 fail2ban.actions        [24665]: NOTICE  [named-refused] Ban 98.242.109.36
2020-08-23 08:01:35,483 fail2ban.actions        [24665]: NOTICE  [named-refused] Ban 191.103.51.133
2020-08-23 08:01:36,738 fail2ban.actions        [24665]: NOTICE  [named-refused] Ban 109.245.32.161
2020-08-23 08:01:40,797 fail2ban.actions        [24665]: NOTICE  [named-refused] Ban 148.255.196.8
2020-08-23 08:01:40,850 fail2ban.actions        [24665]: NOTICE  [named-refused] Ban 85.251.72.184
2020-08-23 08:01:42,104 fail2ban.actions        [24665]: NOTICE  [named-refused] Ban 173.167.36.146

最終的にこのようにfail2banを設定した。

[DEFAULT]
ignoreip = 127.0.0.1/8 172.16.0.0/16
bantime  = 86400
findtime  = 600
maxretry = 10
backend = systemd
usedns = yes
destemail = <送信先メールアドレス>
sender = <送信元メールアドレス>

[named-refused]
enabled = true
port     = domain,953
logpath = /var/named/data/named.run
bantime  = 604800
findtime  = 60
maxretry = 5
backend = auto
usedns = no
protocol = udp

結論~DNSサーバへの攻撃はfail2banで防げない~

ただ、これではだめだった。
なぜかというと、半日ぐらい待ったのだが、一向にアクセスがなくならない。
ログを確認するとban数も6時間くらいで8千とかいっている。
しかも恐ろしいことにipは重複していないのだ・・・。
つまりbanはできているがどんどん新しいipからアクセスが来ているということになる。

さすがにこんなにサーバ乗っ取れないだろう。
となるとip偽装が有力だ。
ググると、UDPはコネクションを貼らないのでip偽装が簡単とのこと。
こうなってくると、banしても全くの無意味ということになる。
いや、むしろ関係ない人達のipをブロックしてしまうのだから完全にダメだろう。

結局、fail2banでnamedを保護するというのはダメだと分かった。

代替案

いま考えているのは2点。
①もうオープンリゾルバーではないのでよそ様に迷惑かけるわけではない。
なので鬱陶しいがそのままにしておく。※コスト次第で対応するかを考える
②さくらVPSのような月額固定のサーバにDNSサーバを立てる。そうすればトラフィック量を気にする必要はなくなる。

コマンドメモ

・ban解除
fail2ban-client set named-refused unbanip 24.57.205.42

・すべてban解除
fail2ban-client unban --all

・iptablesに書き込まれているか確認
iptables --list