iptablesで特定文字列にマッチしたパケットを拒否する方法
こんにちは、Tです。
今回はタイトルの通り、iptablesで特定文字列を含んだパケットを拒否する方法を書きたいと思います。
事の発端
つい最近、ECサイトを公開しているサーバで下記のアクセスログが記録されていました。
xxx.xxx.xxx.xxx - - [08/Apr/2022:18:33:51 +0900] "GET /xxxxx/xxxxx/xxxxx/ HTTP/1.1" 404 12794 "-" "facebookcatalog/1.0"
Facebookのクローラーらしいんですが、これが複数のIPアドレスから結構な量のアクセスをしてくるせいで、ちょくちょくロードアベレージが閾値超過してアラートを検知するんですよね。(robots.txtも無視されました)
幸い手動で遮断できる量だったのでそうしたんですが、今後も同様のアクセスorIPアドレスが増えるなどの対応で来られたらさすがにきついなと思いまして・・・。
何か手はないかと調べたところ、サーバ内で動いているiptablesを使ってそれっぽいこと出来そうだった(最終的にはできませんでした)ので紹介します。
iptables-extensions
iptablesで使用できる拡張されたパケットマッチングモジュールです。
送信元MACアドレスやパケットサイズに条件を付けて処理出来たりします。
マッチングモジュールの一つに「string」モジュールがあります。
string
This modules matches a given string by using some pattern matching strategy. It requires a linux kernel >= 2.6.14.
ふむふむ・・・与えられた文字列をパターンマッチングでマッチさせると記載されていますね。
manページの例を参考に早速やってみましょう。
-A INPUT -m string --algo bm --string hoge -j DROP
とりあえずhogeとマッチしたらDROPします、ルール追加したらこんな感じ。
[root@xxxxx ~]# iptables -nvL | grep hoge
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 STRING match "hoge" ALGO name bm TO 65535
別のサーバからhogeを送ります。
[root@xxxxx ~]# echo hoge | nc xxx.xxx.xxx.xxx 80
[root@xxxxx ~]# iptables -nvL | grep hoge
10 570 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 STRING match "hoge" ALGO name bm TO 65535
ちゃんとDROPしてくれましたね。
ここで気づいたのですがこれHTTPSだとマッチしないんですよね、通信内容暗号化されてるので。
以上です、本当にありがとうございました。