firewalld + IPSetで不正アクセスを弾くには

こんにちは〜Azusaです。

当サイトを運用しているサーバにもログを見ると結構な数の不正アクセスを試みる痕跡が残っています。

基本的には見つけ次第firewalldに設定をしてブロックをしていたのですが、あれよあれよと500件以上になってしまいまして、適応するのにも少し時間がかかるようになってしまいました。

このままではサイトの表示にも影響が出るのではと思い調べたところ、IPSetを併用することで負荷を最小限に抑えられるとのことだったので、導入して設定してみました。

ついでにfirewalldのセキュアではない設定についても警告が出ていたので設定変更しました。

firewalldのAllowZoneDriftingをオフ

このAllowZoneDriftingという設定は既定でオンになっているようなのですが、条件が重なると弾くはずだったトラフィックを受け入れてしまったりするようなのでオフにしました。

これがオンのままだと、

・zone1 target=default source=192.168.0.1 service=none

・zone2 target=default interface=eth0 service=ssh

という2つのゾーンがあったとして、192.168.0.1からSSHでアクセスする際はzone1が適用されて弾かれるはずですが、zone2の設定としてインターフェース全体でSSHを許可しているため、zone2の設定に従って接続できてしまうということのようです。

これがZone Driftingというわけで、オフにした場合で192.168.0.1にSSH接続を許可する場合は、zone1にも明示的にSSHを許可する必要があるそうです。

firewalldの設計として本来はzoneを跨がないのが正常(?)みたいですが、以前のバージョンにて上記のような動作をしてしまっていて、それを基準に設定をしている場合の後方互換のためにこのような設定が残されているようです。

上記のような動作はzone1のtargetがDROPやREJECTに設定されていれば起きないようですが、何故か当サイトのサーバのzone=dropはtargetがdefaultになっていて、zone=publicにドリフトしてた結果、拒否リストが機能してませんでした…。

サーバのセキュリティグループでWeb系以外のポートは弾いているので助かりましたが、家庭内サーバとかだったらと思うと怖いですね。

仮に晒されていたとしてもZone Driftingが無効になっていれば一応は弾けていたはずなので、そういうイレギュラーな事態でも被害を軽減するためにもオフにすることをオススメします。

IPSetの設定

IPSetの設定と言ってもfirewalldに含まれているようで、firewall-cmdで作成から適用まですることができるので、firewalldに内包されていると言ってもいいでしょう。

まず、弾きたいIP群の管理をするためのIPSetを作成します。

# firewall-cmd --permanent --new-ipset=test-v4 --type=hash:net // IPv4の場合

# firewall-cmd --permanent --new-ipset=test-v6 --type=hash:net --option=family=inet6 // IPv6の場合

上記コマンドでIPSetを作成します。

IPv4とIPv6両方のリストが欲しい場合は上下2段とも実行して作成してください。

“–new-ipset”に指定されているのは名称で、自分が分かる名前であれば何でもOKです。(今回は”test-v4″と”test-v6″にしました。)

作成したIPSetにIP群を追加していきます。

# firewall-cmd --permanent --ipset=test-v4 --add-entry=192.168.1.0/24

# firewall-cmd --permanent --ipset=test-v6 --add-entry=1234:5678:9abc:def0::/64

このような感じでサブネット込みで指定することができます。

消す場合は↓

# firewall-cmd --permanent --ipset=test-v4 --remove-entry=192.168.1.0/24

# firewall-cmd --permanent --ipset=test-v6 --remove-entry=1234:5678:9abc:def0::/64

また、量が多くなってきた場合にいちいち1つずつ追加するのは辛いので、1行に1ソースずつ書かれたテキストファイルを用意して一気に追加することもできます。

192.168.1.0/24
192.168.2.0/24
192.168.3.0/24

上記のような感じのファイルで、例として”test-source.txt”というファイルがあるとしたら、

# firewall-cmd --permanent --ipset=test-v4 --add-entries-from-file=test-source.txt

上記のコマンドで一括で追加できます。

ここで注意が必要なのですが、この後の適用時に複数のエントリーで範囲が被ってしまうとエラーで動かなくなります。

例えば、”192.168.1.0/24″と”192.168.1.1/32″というエントリーが同時に存在するとアウトです。

(“192.168.1.1″は”192.168.1.0/24″にも含まれているため、範囲がかぶっています。)

私はそのエラーで突然全通信が遮断されて冷や汗かきました…。

サーバ会社のコンソールから強制的に再起動をかけたところ、ファイアウォールが無効の状態で起動されてきたので、SSHで接続ができて事なきを得ましたが。

ですので、エントリーを追加する場合は、範囲が被ってないかをきちんと確認して追加することをおすすめします。

上記のことを確認してIPSetの作成を終えたら、firewalldのzoneのsourceに追加してリロードすることで有効になります。

# firewall-cmd --permanent --zone=drop --add-source ipset:test-v4

# firewall-cmd --permanent --zone=drop --add-source ipset:test-v6

# firewall-cmd --reload

zone=dropはデフォルトでtargetにDROPが指定されており、対象ソースからのパケットを無視して応答せずに捨てます。

上記のルールだと、”test-v4″と”test-v6″に含まれるIPからの接続は受け付けずに無視する設定になります。

IPSetはあくまでもソースの範囲等を管理するためのものなので、受け入れるためのIPSetとzoneを作成して適用することもできます。

これで迷惑なアクセスをしてくるIPを弾くことができるようになりました。

運用後の追加や削除は、上に書いてあるIPSetの追加や削除コマンドを実行した後にリロードするだけでOKです。

というわけで、今回は迷惑な不正アクセス等を弾くためのfirewalldとIPSetの設定でした♪

ではまた〜ノシ

コメントを残す