alias.log
ファイルの形式を変更するパッチ実際には、「開発」というほど大げさなものではありません。ちょっとした苦労談とでも言いましょうか。
東京めたりっく通信のころはPPPoEだったので、パケットのフィルタリングも、NATも、ppp
で設定していました。しかし、Yahoo! BBはブリッジ (IPoE) なので、ipfw
とnatd
との組合せに変更しました。ところが、なかなか思うように動きません。設定内容は、従来と同じにしているはずなのに、なぜか振舞いが違うのです。
原因を調べて、正しく設定するために、さまざまなデバッグ環境を使ったのですが、NATテーブルを参照することができません。しかたがないので、とりあえず作ったのが、以下のパッチです。
もともとnatd
にはalias.log
というログファイルを生成する機能があり、-l
オプションで有効にできます。これはNATテーブルの状態を出力することになっています。しかし実際には、プロトコル別の有効トランスレーションエントリの個数がわかるだけなので、アドレスが意図通りに変換されているかどうかの確認には使えません。そこで、NATテーブルの内容を追跡できるように、新しいエントリが追加または削除されるたびに、そのエントリの内容をログとして出力するようにしたものです。
このパッチは、natd
が内部的に利用するlibalias
の一部を変更するものです。本格的にパッチを適用するには、natd
とlibalias
のソース一式を取り寄せて、全体をコンパイルし直すことになります。手軽に試すためには、natd
とlibalias
の全ソースをまとめて一つのディレクトリに置き、Makefile
は利用せず、全*.c
を一気にコンパイルしてしまうといいでしょう。
パッチと言っても、実際に修正を行うのは、libalias
の一部であるalias_db.c
というファイルだけです。
natd
のソースは、FreeBSDソースツリーのsrc/sbin/natd/
配下にあります。libalias
は、src/lib/libalias/
配下にあります。
このパッチを適用すると、ログの形式が変わります。natd
を起動する際に-l
オプションを指定すると、新しい形式でalias.log
が採取されます。修正したソースでは、従来の形式のalias.log
を採取することはできなくなります。
採取されるログの例を以下に示します。ローカル側が192.168.1.1、パブリック側が219.63.255.49というアドレスを持つマシン上でnatdを動かしています。このマシンではDNSサーバも動作しており、ローカル側のサブネットに接続されたパソコンは、このマシンにDNSの問い合わせを送るようになっています。
+ udp 219.63.255.49:1024 211.5.1.219:53 219.63.255.49:1024 *:* (0x8060100) + udp 219.63.255.49:1024 165.76.0.98:53 219.63.255.49:1024 *:* (0x8060180) + udp 219.63.255.49:1024 165.76.4.2:53 219.63.255.49:1024 *:* (0x8060200) + udp 219.63.255.49:1024 211.5.1.217:53 219.63.255.49:1024 *:* (0x8060280) + tcp 192.168.1.188:1346 210.142.46.154:80 219.63.255.49:1346 *:* (0x8060300) + udp 219.63.255.49:1024 210.141.108.194:53 219.63.255.49:1024 *:* (0x8060400) + udp 219.63.255.49:1024 210.239.166.194:53 219.63.255.49:1024 *:* (0x8060480) + tcp 192.168.1.188:1347 219.106.255.170:80 219.63.255.49:1347 *:* (0x8060500) + tcp 192.168.1.188:1348 219.106.255.170:80 219.63.255.49:1348 *:* (0x8060600) + udp 219.63.255.49:1024 210.142.46.155:53 219.63.255.49:1024 *:* (0x8060700) + udp 219.63.255.49:1024 211.18.214.210:53 219.63.255.49:1024 *:* (0x8060780) - tcp 192.168.1.188:1346 210.142.46.154:80 219.63.255.49:1346 *:* (0x8060300) + tcp 192.168.1.188:1349 210.142.46.155:80 219.63.255.49:1349 *:* (0x8060300) - tcp 192.168.1.188:1349 210.142.46.155:80 219.63.255.49:1349 *:* (0x8060300) - udp 219.63.255.49:1024 211.5.1.217:53 219.63.255.49:1024 *:* (0x8060280) - tcp 192.168.1.188:1348 219.106.255.170:80 219.63.255.49:1348 *:* (0x8060600) - udp 219.63.255.49:1024 165.76.4.2:53 219.63.255.49:1024 *:* (0x8060200) - udp 219.63.255.49:1024 210.239.166.194:53 219.63.255.49:1024 *:* (0x8060480) - udp 219.63.255.49:1024 165.76.0.98:53 219.63.255.49:1024 *:* (0x8060180)
ログは1行1件の形式で、各項目を空白で区切って並べています。各項目は、先頭から順に、以下の内容です。
link_type
)。natdが特別扱いしないプロトコルの場合には、名前の代わりにプロトコル番号になります。src_addr
とsrc_port
)。dst_addr
とdst_port
)。alias_addr
とalias_port
)。proxy_addr
とproxy_port
)。struct alias_link
データブロックの先頭アドレス。(大抵の場合、この情報は必要ありません。)おおざっぱに言うと、"+" から始まる行は、新しいトランスレーションルールが追加されたことを表し、"-" から始まる行は、既存のトランスレーションルールが削除されたことを表し、"=" から始まる行は、既存のトランスレーションルールの内容の一部が変更されたことを表します。(現在のところ、"=" は、トランスペアレントプロキシのルールの場合にだけ使われます。)
上の例では、192.168.1.188というアドレスのパソコンが、あるWWWサーバにアクセスしたときのログを示しています。
udp のエントリでは、パブリック側エンドポイントのポート番号はすべて53で、これがDNSの問い合わせであることを暗示しています。また、ローカル側エンドポイントがすべて219.63.255.49:1024ですが、これはこのマシンで動作するnamed
が使用している問い合わせ用のポートです。この例では、udpのエントリはどれもソースとアリアスが一致していますが、これは、udpのリンクが全てこのマシンで動作するプログラム (named) による通信だったために実際にはトランスレーションが行われなかったためです。
tcpのエントリでは、パブリック側エンドポイントのポート番号はすべて80で、これがHTTPのアクセスであることを暗示しています。ローカル側エンドポイントのIPアドレスは192.168.1.188というパソコンのものになっています。アリアスのIPアドレスは、natd
が動作するマシンのパブリック側のIPアドレスになっており、アドレスがトランスレートされていることを示しています。ポート番号は、ローカル側とアリアスで同じ値になっていますが、これは偶然ではなく、natd
が (デフォルトでは) できるだけポート番号を変更しないようにトランスレーションルールを生成するためです。
前半では、新規に発生したトラヒックをトランスレートするために新しいエントリが次々と作られ、後半では不要になったエントリが次々と削除されています。ただし、上に示した範囲では、全エントリが削除されていず、一部のエントリが残っています。このエントリは、もう少し時間が経つと削除されるはずです。
新しい形式のログは、従来の形式に比べてファイルの寸法が大きくなりがちです。もともとalias.log
というファイルは、すぐにファイルサイズが大きくなりすぎるという問題を持っています。デバッグ用に、必要なときだけ採取するという使い方が現実的だと思います。alias.log
を採取したまま、長時間natd
を動かすような使い方は、お勧めできません。
新しい形式のログは、従来の形式に比べて、ログの生成にかかるCPUのオーバーヘッドが増えています。高い負荷のかかるルーターでalias.log
を採取することはお勧めできません。
このパッチは十分にテストされていません。このパッチは、ログの形式を変更するだけで、natd
の動作自体を変更するものではないため、もしもバグがあっても、ログの形式がおかしくなること以上の不具合は起きないはずですが、保証はできません。このパッチの利用は自己責任でお願いします。
ついでなんで、新しい形式のログを集計して、「現時点での」トランスレーションテーブルの内容を一覧形式で表示するツールも作ってみました。最近は、こういうツールは普通PerlかRubyで書くものだと思うのですが、これはawkで書いてあります。(年齢がバレますね。)
awk -f natstat.awk /var/log/alias.log
として使います。出力はこんな感じになります。
Type Local Public Alias Proxy tcp 192.168.1.188:1347 219.106.255.170:80 219.63.255.49:1347 udp 219.63.255.49:1024 211.5.1.219:53 219.63.255.49:1024 udp 219.63.255.49:1024 210.142.46.155:53 219.63.255.49:1024 udp 219.63.255.49:1024 211.18.214.210:53 219.63.255.49:1024 udp 219.63.255.49:1024 210.141.108.194:53 219.63.255.49:1024
内容から考えて、表示の順番は、Type、Local、Alias、Public、Proxyという並びの方が分かりやすいと思うのですが、ここではログと同じ順にしてあります。(変に順番を入れ換えると混乱の元なので。因みに、ログがこの順なのは、libalias
が内部で使っているstruct alias_link
というデータ構造の順番に合わせたものです。)
libalias
の一部であるalias_db.c
に対するパッチです。)