Solaris でファイアーウォールを作ろう/其の4

目次

変更点の概要

其の3で今後の課題としていたものなどから、以下の機能を追加しました。

  • ルールにあて先アドレスを指定できるようにする。
  • 許可ルールを追加できるようにする。
  • コマンドを使っての STREAM への fwall モジュールの挿入、および取り外し。
  • fwalladm コマンドから任意の順番でのルールの追加。
  • 複数のインターフェースを持つルータマシンでも動作するようにする。

それと、機能追加では無いのですが、fwall モジュールのコード読みやすくするために、いくつか既存のコードを変更しました。私のプログラムの書き方はかなりヘタレな部分が多く、「普通そうは書かないだろ!」思われる所もかなりあるのではないかと思います。もともと自分のC言語の勉強のためにはじめたプログラム作りなので、さらに勉強してまともなコードが書けるようにしていきたいと思います・・・。
で、そのコードの読みやすく(あとで自分がわかりやすく?)する一環として、いくつかの既存の関数名を変更し、あと可能な処理はマクロを利用することによって、見た目をすっきりさせました。

fwallモジュールの関数名の変更

変更前 ----------> 変更後機能
fwall_add_rule() --> fwall_insert_rule()新ルールの追加・挿入
fwall_chk_rule() --> fwall_check_rule()ルールに基づくパケットの評価
fwall_rm_rule() --> fwall_delete_rule()既存のルールの削除


fwall モジュールに追加したマクロ

マクロ名機能
RULES()現在の総ルール数をカウントする
WALKRULE()指定したルール番号のルールへのポインタを得る
COMPARE_ADDR()2つの IP アドレスの比較を行う

各関数内の変更内容は、プログラム中のコメントを見ていただければと思います。だいぶくどくどと書きました。3歩あるくと前のことをすぐ忘れる私もこれなら安心して忘れられます。(笑) モジュールに指令を与える fwalladm コマンドの方ですが、こちらはまたまたかなり汚いコードになっています。ユーザからの入力の文字列比較等がなかなかうまく書けません・・・うーん。これはこれで後々の検討課題ということにします。

ご注意

毎度のことですが、PANIC するとまずいことになるマシンでは絶対に動作させないでください。機能が多くなってきたら、だんだんデバッグが難しくなってきてしまいました。エラー処理が不完全なので、あらぬ操作で PANIC するやもしれません。

ソースコードとダウンロード

ソースファイル: fwall-0.4.tar.gz (2005/03/04 更新)

tar ファイルに含まれるファイルの概要
Makefilefwallモジュール、fwalladm コマンド用の makefile
fwall.cfwall モジュールの本体。
設定されたルールにもとづいて、IP パケットを通過させたり、破棄したりする。
fwalladm コマンドからの ioctl() コマンド(=M_IOCTLメッセージ)を解釈し、通過を許可/拒否する IP を動的に追加・変更・削除できる。
fwall.hfwall モジュール、fwalladm コマンド共通のヘッダーファイル。
fwall_rule_t 構造体は、fwall モジュール、fwalladm コマンド双方で参照・利用される構造体。 fwall モジュールは fwalladm コマンドから指示されたルールを fwall_rule_t 構造体のリンクリストとして保持している。
fwalladm.cfwall モジュールのフィルタールールを変更するコマンド
IP デバイスを open() し、そのストリームに fwall モジュールを PUSH。その後、ioctl() を使ってルールの追加、削除、参照コマンドを fwall モジュールに伝える。
fwallcntfwall の開始、停止を行うためのシェルスクリプト
fwallcntl start で、fwall モジュールをシステム上のすべての NIC の STREA に挿入
fwallcntl stop で、NIC の STREAM から fwall モジュールを抜き、モジュールをアンロードする。

使い方 その他

コンパイル&インストール

今回から、Makefile へのネットワークインターフェースに依存した記述を止めました。基本的に、make install ではモジュールとコマンドのコピーだけを行い、起動スクリプトと、コマンドでモジュールのロード・アンロード、パケットの調査を行うネットワークインターフェースの指定を行うようにしました。

# make						   
/usr/local/bin/gcc -g -D_KERNEL -c -m64 fwall.c	   
/usr/ucb/ld -dn -r fwall.o -o fwall		   
/usr/local/bin/gcc -g -lnsl fwalladm.c -o fwalladm 
# make install					   
/bin/cp fwall /kernel/strmod/sparcv9/fwall	   
/bin/cp fwalladm /usr/local/bin/fwalladm	   
/bin/cp fwallcntl /usr/local/bin/fwallcntl         

モジュールのロード

make install が終わった直後は、モジュールのロードも、ルールの設定も行われていません。まずは fwallcntl という起動スクリプトを使って、モジュールをロードし、STREAM に fwall モジュールを挿入します。

# /usr/local/bin/fwallcntl start

これによって、システム上のすべてのネットワークインターフェースに関連する STREAM に fwall モジュールが挿入され、パケットを調査する準備ができました。続いてはパケットの通過許可・不許可を決めるルールを設定します。これには fwalladm コマンドを使います。

Usage: fwalladm
   add rule <source address> <destination address> <action>
   insert rule <rule number> <source address> <destination address> <action>
   delete rule <rule number>
   list rule
   add interface <interface>
   delete interface <interface>
   list interface
# /usr/local/bin/fwalladm
>

其の3までは、コマンドの引数を指定することによっててルールの追加や削除を行っていましたが、今回からコマンドを起動すると、専用のプロンプトが出力されるようにし、ルールの設定はこのプロンプト上で行うようにしました。どっちの方が使い勝手がよいかわからないのですが、コマンドの引数が多くなったときに、引数の処理が難しくなったので、こうしたというのが正直なところです。あと、Sun の Firewall ソフトである Sun Scree の ssadm コマンドに似せて作ったというのもあります。私自身あまり Sun Screen をさわったことはなかったのですが、ユーザインターフェースの部分で雛型になるものがほしかったので、docs.sun.com でしらべて似たような感じにしました。

ルールの追加

新規のルールの設定の仕方は以下のようにします。

add rule <送信元アドレス> <あて先アドレス> <動作>

例)

# /usr/local/bin/fwalladm
> add rule 10.0.0.1 10.0.0.2 ALLOW
> add rule 10.0.0.1 10.0.0.3 ALLOW
> add rule 0 0 DENY

これは 10.0.0.1 から 10.0.0.2 と 10.0.0.3 宛てパケットは許可するが、それ以外はすべて破棄するというルールです。(リモートからこんなルールを設定したら即そのマシンにアクセスできなくなるでしょう)
注)アドレスに 0 を指定すると、すべてのアドレスに一致することになります。
「add rule」では、新規ルールをルールの一番最後に追加します。

ルールの表示

追加したルールは fwalladm コマンドの「list rule」で確認できます。

# /usr/local/bin/fwalladm
> list rule
Rule 0: 10.0.0.1 -> 10.0.0.2 ALLOW
Rule 1: 10.0.0.1 -> 10.0.0.3 ALLOW
Rule 2: 0.0.0.0 -> 0.0.0.0 DENY

ルールの挿入

既存のルールとルールの間に新規ルールを追加したい場合には「insert rule」を使います。

insert rule <ルール番号> <送信元アドレス> <あて先アドレス> <動作>

例)

# /usr/local/bin/fwalladm
> insert rule 2 10.0.0.1 10.0.0.4 ALLOW
> list rule
Rule 0: 10.0.0.1 -> 10.0.0.2 ALLOW
Rule 1: 10.0.0.1 -> 10.0.0.3 ALLOW
Rule 2: 10.0.0.1 -> 10.0.0.4 ALLOW
Rule 3: 0.0.0.0 -> 0.0.0.0 DENY

上記の例ではルール2として 10.0.0.1 から 10.0.0.4 へのパケットを許可するルールを追加しています。

ルールの削除

設定したルールを削除する場合には、fwalladm コマンドの「delete rule」を使います。
以下の例では上記例のルール番号1(Rule 1: 10.0.0.1 -> 10.0.0.2 ALLOW)を削除しています。

# /usr/local/bin/fwalladm
> delete rule 0
> list rule
Rule 0: 10.0.0.1 -> 10.0.0.3 ALLOW
Rule 1: 10.0.0.1 -> 10.0.0.4 ALLOW
Rule 2: 0.0.0.0 -> 0.0.0.0 DENY

インターフェースの追加

fwall モジュールでパケットの調査を行うネットワークインターフェースを fwalladm コマンドから設定できるようにしました。インターフェースの追加には「add interface」を使います。

# /usr/local/bin/fwalladm
> add interface hme0

この例では hme0 というネットワークインターフェースを調査対象として追加しています。

インターフェースの表示

ルールの場合と同じく「list interface」とすると、現在パケットの調査をおこなう対象となっているネットワークインターフェースの一覧が表示されます。

> list interface
hme
le

この出力から、現在 hme と le の二つのインターフェースが調査対象になっているのが分かります。・・・・ん?よく見るとインスタンス(hme0 とかの 0 の部分)が抜けてますね。これでは hme0 と hme1 を使っている場合などにはどっちが調査対象だかわからないですね・・要改善です。

インターフェースの削除

ネットワークインターフェースをパケット調査の対象からはずしたい場合には「delete interface」を使います。

> delete interface hme0
> list interface
le

上記例では hme0 を調査対象から削除しています。

モジュールのアンロード&アンインストール

モジュールをアンロードするには「fwallcntl」シェルスクリプトを使います。

# /usr/local/bin/fwallcntl stop

また、インストールしたモジュール、コマンドをシステムから削除するためには make を行ったディレクトリ上で「make uninstall」を実行します。

# make uninstall
/usr/local/bin/fwallcntl stop
fwall module removed from all interface
fwall module successfully unloaded
/bin/rm /kernel/strmod/sparcv9/fwall
/bin/rm /usr/local/bin/fwalladm
/bin/rm /usr/local/bin/fwallcntl

32bit 環境での利用

32bit 環境では Makefile32 という Makefile をつかって、コンパイル、インストールが行えます。

# make -f Makefile32
# make -f Makefile32 install
# make -f Makefile32 uninstall

これ以外は同じです。

今後の課題

  1. ルールにプロトコルを指定できるようにする。(ICMP, TCP, UDP)
  2. ルールに送信元、あて先ポート番号(TCP・UDP)を指定できるようにする。
    (あとこれくらいできなくっちゃ・・)
  3. プロトコル違反のパケットや、異常なアクセスを拒否する(これはまだまだとーぶん先でしょう・・)

トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2022-01-03 (月) 20:21:59