OpengateMd - MACアドレスチェック・ファイアウォール開閉デーモン
概要
ゲートウェイを通るパケットのMACアドレスを見てネットワーク開閉を行うデーモンである。許可するユーザ端末のMACアドレスとユーザ
IDは、事前にMySqlデータベースに登録する。 登録と更新は別システムで行う。以下の動きをする。
- ゲートウェイ上のファイアウォールは標準で閉鎖とする。
- ユーザが端末を使ってゲートウェイ下からネットワーク利用を開始する。
- デーモンプロセスがパケットをキャプチャし、データベースに問い合わせる。送信元MACアドレスの登録が確認できれば、ファイア
ウォールに開放ルールを追加 する。
- 一定時間、その端末からの利用がなければ、ファイアウォールから開放ルールを削除する。
- 開放閉鎖時に、ユーザIDを付けてログに記録する。
- データベース問い合わせは負荷となるので手元にキャッシュする。
インストール
- VirtualBox上の試用のドキュメントが新しい。まずはトップページにリンクしたそちらのドキュメントを参照すること。
- NICを2枚以上持ったゲートウェイマシンを用意しFreeBSDをインストールする。
Opengateが稼働しているゲートウェイがあれば、その環境に不足分(MySQLとOpengateMd)を追加設定することでイン
ストールできる。
- ゲートウェイ機能を有効にするために,/etc/rc.confに次の設定を記述する(もしくはインストール中にゲートウェイの機能
を有効にする)。
gateway_enable="YES"
- SQLite3、MySQLクライアント機能を追加する。ローカルでDBサーバ運用も行うならMySQLのサーバ機能も追加する。
- Version 0.8.0以降では、Layer2でのIPFWを有効にするために、/etc/sysctl.confに以下を設定する。
net.link.ether.ipfw=1
- Version 0.7.xから0.8.xへ移行する場合は、以下に注意すること。
- 作業データベースopengatemd.dbを削除する(プライマリキーを変更した。新たなデータベースは自動的に作成され る)。
- IPFW Layer2の全通過ルールをルールリストの最後に追加する(サンプルはアーカイブ中のrc.firewall.sample)。
- Layer2のチェックがOpengateMdのルールセット(10000-50000)を通ることを確認する(ルール 10000よ
り前に全通過ルールを入れない)。
- Webインターフェースを使う場合は、Apache2を追加して設定する。なおCGIファイルはOpengateMreg、
OpengateMown等から別途インストールする。
- Apacheの設定ファイル/usr/local/etc/apache22/httpd.confにおいて、以下の設定を 行う。
存在しないファイル要求にはDocumentRootを返す
ErrorDoument 404 /
CGIディレクトリでの実行を許可する
<Directory '/usr/local/www/cgi-bin'>
Options ExecCGI
</Directory>
ファイル拡張子CGIとVARのハンドラ設定を追加する
AddHandler cgi-script .cgi
AddHandler type-map .var
VARファイルをIndexに追加する
DirectoryIndex index.html.var index.html
SSLの設定ファイルを追加する(SSLは必須でないが推奨する。SSL設定についてはOpengateインストールのページや
Web上の解説サイトを参照すること)。
Include etc/apache22/extra/httpd-ssl.conf
サーバ名を付ける
ServerName opengate.og.saga-u.ac.jp
- システム設定ファイル/etc/rc.confにApacheの自動起動を記述する
apache22_enable="YES"
apache22ssl_enable="YES"
- 以下は必須ではない。必要であればOpengateインストールドキュメントやWeb上の解説サイトを参照すること。
DHCPサーバ設定を行う。
BIND設定を行う。
IPv6設定を行う。
- 本システムのアーカイブを展開して、アーカイブディレクトリ中のmdsrcからインストールする。「0.0.0」はバージョン番号である。
tar xzvf opengatem0.0.0.tar.gz
cd opengatemd0.0.0/mdsrc
sudo make install
opengatemdが稼働中であるとインストールに失敗する。この場合には、以下のように、一時的に停止してインストールする。
sudo opengatemd -s <=一時停止
sudo make install <=インストール
sudo opengatemd <=再稼働
- Defaultでは以下の場所に実行ファイルと設定ファイルサンプル、起動スクリプトが追加される。
/usr/local/bin/opengatemd
/etc/opengate/opengatemd.conf.sample
/et/rc.d/opengatemd
- OpengateMdの設定ファイルを環境に合わせて調整する。変更の必要があるのは、MySQLとの接続設定
(MySqlDb/Server,User,Password)、Pcapのキャプチャデバイス設定(Pcap/Device)である。
cd /etc/opengate
cp opengatemd.conf.sample opengatemd.conf
vi opengatemd.conf
- OpengateMsqlの説明を参照してMySQLデータベースを設定する。
- ファイアウォールを有効にするために、/etc/rc.confに以下のオプションを記述する。NATDの設定は任意である。イン
ターフェースは上流側NIC名を指定する。
firewall_enable="YES"
firewall_script="/etc/opengate/rc.firewall"
natd_enable="YES"
natd_interface="fxp1"
- ファイアウォールスクリプト/etc/opengate/rc.firewall内のアドレスやインターフェース名を環境に合わせて 調整する。
- Syslogによるログ記録を有効にするために、/etc/syslog.conf内に以下の設定を行い、対応するログファイルを作
成する(例:touch /var/log/openate.log)。
local1.* /var/log/opengate.log
↑ここはTABで区切る
- デーモンを起動し、ゲートウェイ下流から端末でアクセスして試す。起動はルートユーザで「opengatemd」。MySQLに登録
した端末からのアクセスのみがゲートウェイを通過する。
- システム起動時にデーモンを自動起動するには、/etc/rc.confに以下の行を追加する。
opengatemd_enable="YES"
- 一日に一度の再起動を行うには、以下の内容を/etc/crontabに追加する(この例では毎朝3時48分に再起動する)。もしくは、/etc
/periodic/daily/ディレクトリに、コマンドを実行するファイルを用意する。
48 3
*
*
* root
/usr/local/bin/opengatemd -r
運用
- 「opengatemd」と、パラメータ無しで起動するとデーモンとして動作する。
- 「opengatemd -c」(console mode)として起動すれば、コンソールモードとして動作する。
エラー等はコンソール画面に出る。
- 「opengatemd -e」 (end
mode)として起動すると、新規開放は行わず、残存しているファイアウォールルールや作業データベースレコードを適切に片づける。
起動中のデーモンがあれば停止し、自分自身も停止する。ただし、Opengate側で制御しているファイアウォールルール等はそのまま残る。
- 「opengatemd -s」 (stop
mode)として起動すると、既存デーモンを停止し自分自身も停止する。ファイアウォールルールやデータベースレコードはそのまま放置する。再びデーモン
を起動することでサービスの継続ができる。
- 「opengatemd -r」 (reload
mode)として起動すると、既存デーモンにHUPを送って自分は停止する。既存デーモンがないときは単に起動する。
- 設定ファイル/etc/opengate/opengatemd.confにおいて、以下の時間設定を含めた各種の設定ができる。
<CacheTimeout>=MACアドレスキャッシュ有効時間:短くするとDB更新をサービスへ反映するのが早くなる
が負荷が上がる(default:5分)
<UselessTimeout>=ルール削除に要する端末無使用時間:この時間だけ端末に関連するパケットが検出されな
ければipfwルールを削除する(default:3時間)
<UselessCheckInterval>=端末無使用・DB矛盾チェック間隔:この時間間隔でipfwルールと利用
状況データベースをチェックするルーチンが走る(default:1時間)
- 設定ファイルのDebugを2または3にすれば、関数呼び出しトレースが出力される。コンソールモードの時は画面、デーモンモードで
はSyslog先に出力する(Debug= 2ではビジーループの部分の表示が無い。Debug= 3では全ての表示となる)。
- MySQLとsyslogに利用ログが溜まっていくので、定期的に削除する必要がある。
特定の送信元MACアドレスを持つパケットを発見したときにSyslog経由で報告する機能を付けた(ver.0.9.1)。
- MySQL設定
監視するMACアドレス群はMySQLデータベース上のwatchlistテーブルで指定する(テーブルが無い場合はcreatetablescript
で作成する)。下記の例は2つのアドレス(コロン区切り、英小文字数字指定)を監視する。
+-------------------+-----------+------------+
| macAddress | reporting | memo |
+-------------------+-----------+------------+
| 11:22:33:aa:bb:cc | Y | test1 |
| 44:55:66:dd:ee:ff | Y | test2 |
+-------------------+-----------+------------+
パケットの送信元MACアドレスがmacAddressフィールドと一致し、reportingフィールドが"Y"であれば報告する。
ただし、watchlistテーブルがmacAddress="ALL"のレコードを含めば全てのアドレスについて(テーブル内に存在するか否かにかわらず)報告する。
- Syslog設定
報告はsyslogのwarningプライオリティで出力するので、対応するsyslog.confの設定を行う。例えば下記は、コンソール上へ報告する
設定である。Default設定のままならば他のログと一緒にファイル出力される。syslog.confはTAB区切りであることに注意する
local1.!=warning /var/log/opengate.log
local1.=warning /dev/console
連携して動く個別メール送信プログラムphpsrc/sendreportmail.phpを用意した。これを起動するには以下の設定とする。
local1.=warning | /path/sendreportmail.php
- 設定の反映
テーブルデータの変更は再起動時に反映される(「opengatemd -r」でデーモンを再起動すると上記のテーブルデータをメモリ上にロードする)。
またsyslog.confの変更を反映す るにはsyslogの再起動が必要である。
- 報告タイミング
報告はキャッシュ切れの時間(設定ファイルの<CacheTimeout>)ごとに行われ る。
関連システム
- FreeBSD/Ipfw=OSとファイアウォール
- Libpcap=パケット キャプチャ ライブラリ
- SqLite3=作業データベース(ローカルに途中経過を保持し、停止・再起動に対処)
- MySQL=管理データベース(MACアドレス登録、利用記録保持)
- Syslog=利用記録、エラー出力
処理概要

[メイン処理]
- 以下を繰り返す。
- Pcapを使い、1パケットヘッダをキャプチャして、MAC/IPアドレス対を取得する
- そのMAC/IPアドレス対がキャッシュにあればチェックをスキップする(あれば、最近チェックしたアドレスである)
- そのアドレスのセッションが作業DBにあるかチェックする(あれば、そのアドレスに対するファイアウォールが既 に開 いている)
- そのMACアドレスが管理DBに登録されているか調べる
- 登録済みで未開放なら、セッションを開始する(ファイアウォール開放、作業DB登録、ログ記録)
- 登録済みで開放済みなら、パケット検出時間を更新する
- 登録無しで開放済みなら、セッションを終了する(ファイアウォール閉鎖、作業DB削除、ログ記録)
- 定期的に、パケット検出時間をチェックして、使っていないセッションを終了する
[最近チェックしたMAC/IPアドレス対か否かの確認処理]
ハッシュテーブル(key=MAC/IPアドレス対、Value=登録時間)とキュー (MAC/IPアドレス対をFIFOで保持)を使って実装する。
- MAC/IPアドレス対をキーとしてハッシュテーブルを引く
- テーブルから取得した登録時間がハッシュ保持時間より後ならば、TRUE(最近チェックあり)を返す
- テーブルから取得した登録時間がハッシュ保持時間より前ならば、
- 当該アドレスが出てくるまでキューからアドレスを取得し、それをハッシュテーブルから消すことを繰り返す(当該アドレスより古い登録のアドレ
スを一括消去)
- 当該アドレスを、新たにキューとハッシュテーブルに登録する
- FALSE(最近チェックなし)を返す
- テーブルから取得できなければ、ハッシュテーブルとキューに登録して、FALSE(最近チェックなし)を返す
[使っていないセッションを終了する処理]
- 前回チェック時間(初期値ゼロ)から指定時間が経過していないなら何もしない
- 前回チェック時間を現在時刻に更新する
- 最新パケット時間が指定時間より古いセッションを終了する
- IPFWルール一覧とOpengatemd/Opengateの管理するセッション一覧(作業DB)を比較し、対応していないDBレ
コード/IPFWルールを削除する。またOpengate管理セッションの場合にはその端末用のプロセスが無いなら消す。
[IPFWファイアウォール制御]
IPFWルールセットは、Layer2とLayer3の2回スキャンする。Layer2スキャン(MAC表記のルール)
では該当MACアドレスにタグを付けて全パケットをLayer3へ回す。Layer3ではタグ付きパケットを許可する。またWebパケットは
フォワードする(登録ページや警告ページへ誘導)。タグ付けルールはデーモンプログラムによって動的に追加削除する。
10000 count tag 123 ip from any to any MAC any 11:22:33:44:55:66
keep-state
10000 count tag 123 ip from any to any MAC 11:22:33:44:55:66 any
keep-state
----
60000 allow ip from any to any tagged 123
60010 allow ip from any to any MAC any any
60100 fwd 127.0.0.1 tcp from any to any dst-port 80
60900 deny ip from any to any
利用データベース
- MySQL: opengatem R/W (管理DB)
- SqLite3: opengatemd.db R/W(OpengateMd用作業DB)
- SqLite3: opengate.db R (Opengate用作業DB)