snortで変わりだねファイアウォール(flex_respを使う)
- 2001.10.11 α版公開
- 2001.11.15 snort1.8.2の注意事項追記
ネットワークベースでもホストベースでも使えるフレキシブルなIDS、snortには面白い機能があります。FlexRespと呼ばれるこの機能は、「パターンにマッチした通信を強制終了させる」というものです。
この機能を理解するには、TCP/IPがどの様に通信を制御しているか、が分からないと話になりません。ここでそれについて書き始めると大変なことになるので(^^;、ざっくり言い切ってしまうと、「RSTパケット(TCPの場合)もしくはICMP-Unreachable(UDPの場合)を受信すると通信は終了」という事になっています(詳細はRFCなり参考書なりを調べてください)。
この通信の約束事を利用すると、「ネットワークを流れる任意の通信を強制終了できる」わけです。これを悪用すると、通信をバンバン遮断することでDoS攻撃が可能、と言うことになりますが、これをうまく利用するのがここで紹介するFlexRespです。
悪意のある通信がネットワーク上を流れてきた場合、IDSがこれを検知し、すかさず「通信を終了するパケット」をネットワーク上に送信します。これを受信した攻撃対象マシンは通信を終了するので、攻撃の種類によっては攻撃をかわすことも可能となるわけです。
しかもIDSですから、攻撃手法も記録する、というわけです。
さて、使用するためには、2つの作業が必要です。1つは、libnetと呼ばれるライブラリをビルド、インストールすることです。libnetは、TCP/IPパケットを自在に作るためのAPIになっており、snortが終了用パケットを作成、送信するのに必要となります。libnetをビルドするには、libpcap(libpcap-devel)がインストールされていなければなりません。
もうひとつは、FlexResp機能を使えるようにするために、snortをリビルドすることです。これについては、configureスクリプトを実行する際に、「--enable-frexresp」オプションをつけて実行し、make;make installするだけです。ただし、先にlibnetをインストールしてある必要があります。
無事、上記インストールができれば、FlexRespが使えます。使い方は、ルール中に、resp:hoge;と書いておくだけです。具体的にルールを書いてみましょう。
alert tcp any any -> any 25 (msg:"Mail from/to shikap!";content:"shikap@yk.rim.or.jp";resp:rst_all;) (一行です)
上記のルールは、コンピュータのSMTPサーバに、「shikap@yk.rim.or.jp」と書かれた通信が送信されたら、通信を遮断する、と言うものです(これで多分あっていると思います、笑)。
最後の方の「resp:rst_all」というのが、FlexRespを使用するための書式です。ここでは、rst_allを使っていますが、そのほかに、rst_snd、rst_rcv、icmp_net、icmp_host、icmp_port、icmp_allという合計7つのオプションが使用できます。
これらそれぞれの意味は以下のとおりです。
- rst_snd:送信元にRSTパケットを送信する。TCP用。
- rst_rcv:受信先にRSTパケットを送信する。TCP用。
- rst_all:送信元、受信先両方にRSTパケットを送信する。TCP用。
- icmp_net:ネットワーク不到達ICMPを送信する。UDP用。
- icmp_host:ホスト不到達ICMPを送信する。UDP用。
- icmp_port:ポート不到達ICMPを送信する。UDP用。
- icmp_all:上記3つのICMPを全部送信する。UDP用。
と言うわけで、使い方そのものはとても簡単です。コンパイルが一番面倒かもしれないですね。
この機能の難しいところは、ルールをきちんと書いていないと、「関係のない通信も遮断してしまう」ということです。
もし、先に書いたルールの「25」と言うところをanyにするとどうなるでしょうか。どのコンピュータのどのサービスでも、「shikap@yk.rim.or.jp」という文字列が流れてきたら、すべて遮断、と言うことになるので、このWWWページも見れません。文字列がありますから。
また、ぼくのメールを受け取ることができません。僕のメールには必ずその文字列があるからです。25と言う数字はSMTPサーバの使用するポートですから、メールを送信するときだけチェックする、と言うことを示しています。WWWもPOP3もチェックしない、と言うことになるのです。
これらの事をよく考えてルールを作らないと、非常に面倒なことになります。
さて、ここでは変わり種な使い方も紹介しておきます。
あるサーバには多くの人のログインアカウントがあるとします。そして、特定のマシンからだけは、特定のアカウントだけFTPが使えるようにしたい、と言う要望があったとします。
この時には、以下の様なルールを書けばいいのです。
alert tcp 特定マシンのIPアドレス any -> あるサーバのIPアドレス 21 (msg:"Invalid login!"; content:"USER ";content:!"特定アカウント";resp:rst_all;) (一行です)
上記のようにすれば、特定アカウント以外でftp接続をしようとしたとたんに通信が切れ、ftp接続できなくなります。そして、snortのログには「Invalid login!」というアラートが記録されます。これは実際に使った手法です。
もっと変な使い方としては、「古いWWWブラウザは却下」を強制する、と言う方法ですね(^^)。「古いメーラーは却下」もできます。
パッチレベルまではチェックできませんし、httpリクエストをちょっと改竄されるとだめですけど、一般ユーザには十分な抑止力になります(^^)。新しいバージョンのWWWブラウザ以外使用禁止、みたいなパターンの時にどうでしょうか?ただし、使うときにはユーザに対してそれなりのアナウンスをした方がいいですよ。
ほかにも「APOP以外禁止」や「機密資料送信禁止」とかもできます。最後のはとても大変ですけれど:-P。
使い方次第でとても役立つFlexResp、ぜひ「試してみてください」。ただし、「運用模擬テスト」は怠らないようにしましょうね。でないと、違う通信も遮断しまくりますからねぇ。
2001.11.15追記
snort1.8.2がリリースされましたが、こちらのバージョンでは、Flexrespがまともに動かないことが確認されています。
このため、どうしても使いたい場合には、以下の手順を踏むことが必要です。
まず、snort.orgから、CVSツリーにアクセスして、sp_respond.cを入手します。そして、snort1.8.2のsp_respond.cと差し替えます。
それからビルドしてあげればFlexrespがまともに使えるようになります。ただし、RedHat7.1では、--enable-flexrespオプションをつけてコンパイルすると、コンパイルが通らない、という問題があるようです。これは、なんとなくconfigure中のtypoくさいですなんとなくconfigureの誤動作くさいです(^^;。未確認だけど。
ということで、責任は持ちませんが、ソース中のuint*_t定義のあたりをごにょごにょすると直るかも・・・・(無責任モード炸裂)