ウチの自宅環境をかいつまんで説明すると、DX4-75のLinux router(HTTP,SMTP,IMAP4が同居)に、eth0, wvlan0, ppp0(PPPoE→ADSL)の混在環境がぶら下がっている。ここに、二つ目の出口であるtap0(ISDN)をぶら下げようとするのだからサァ大変。
模索していたところ、見付けたのがIPROUTE2だ。
先に断っておこう。コレはLinux kernel 2.2ベースの推奨ツールである。手持ちのLinux routerを2.4ベースに置き換えるつもりなら、iptablesを使うべきだろう(と想像する)。私の場合、メモリが24MBしかないマシンで2.4系に移行できるだけの余力がないと判断したからIPROUTE2を使ったまでで、2.4系を選ぶ余地があるのであればそのほうが望ましい(だろう)。
まずはカーネル再構築。今までdisableだった「IP: policy routing」と、ついでに「IP: large routing tables」(これは任意)を有効にして再コンパイル。
続いてIPROUTE2。rpmfindで探したら、それなりにパッケージがあったので、ざくざくとMandrakeからパチってくる。
問題なのはここからだ。とりあえず、本来のPPPクライアントが勝手に設定するdefault routeは無効にしなくてはならない(この意味すら分からない人は手を出すべきではない)。pppdなら「ifcfg-pppに"DEFROUTE=no"と記述」、PPxPなら、IP.UP及びIP.DOWNをhrouteup,hroutedownに上書きというところだろう。
続いて/etc/iproute2/rt_tablesへ、ローカルテーブルの記述を追加。ウチはこんな感じで追加した。
#
# local
#
1 livingroom
2 storeroom
テーブルlivingroomは「居間」だから、テーブルstoreroomは「物置」だから、という安直な理由。テーブル値としては、予約値である255,254,253,0以外であれば、別に1や2でなくてはいいハズだ。
で、それぞれのPPPクライアント接続が確立された状態で、routeとruleの追加を行う。
ここがIPROUTE2のキモで、一番分かりにくい部分。でも、exampleとにらめっこしつつ、例示されたものを読んでいけば、おぼろげながら仕掛けが見えてくる。
論より証拠。まずは何もしない状態で、ipコマンドを使ってruleを参照してみよう。
# ip rule show
0: from all lookup local
32766: from all lookup main
32767: from all lookup default
続いて加工後のruleを以下に示す。
# ip rule show
0: from all lookup local
15001: from 192.168.1.0/24 lookup livingroom
15001: from 192.168.0.0/24 lookup storeroom
32766: from all lookup main
32767: from all lookup default
…分からない?うん、自分も分からなかった(--;
答えはこうだ。「単一I/F時のrouteテーブルは、mainテーブルただ一つのみ。IPROUTE2は、これに任意の複数テーブルを追加し、優先順位(preference)に応じて複数のテーブルを参照する」のである。
どういうことかは、以下のコマンドを使えば分かる。
# ip route show table main
従来のrouteコマンド(もしくはnetstat -r)で見られるような、通常のrouting tableが確認できることだろう。つまりこれがmainテーブル。
特定のケースにおいてのみ、これとは異なるrouting tableを使用するには、rt_tablesへの記述をした上でip route addコマンドをtableオプションを併用して使う。たとえばこんな感じ。
# ip route add default via 210.136.1.49 dev eth0 table storeroom
続いてpreferenceつきでruleを追加する。
# ip rule add from 192.168.0.0/24 pref 15001 table storeroom
こうすることで、source addressが192.168.0.0/24に収まる場合には、通常の(=テーブルmainの)routingよりも先に、テーブルstoreroomのroutingが参照されるようになるのだ。
ここでもうひとつ落とし穴がある。このままでは「add default via 210.136.1.49」に従って、全てのパケットは210.136.1.49へ向いてしまうのだ。これでは、192.168.0.0/24のホストからは、どうがんばっても192.168.1.1/24のネットワークに到達できない。つまり、優先するruleが存在する場合、そのruleが示すテーブルで、mainテーブルと同じroutingを明示的に書く必要がある。以下は例。
# ip route add 192.168.1.0/24 via 192.168.1.1 table storeroom
default routeは最後に参照されるので、192.168.1.0/24の経路はdefault gwに優先される。これは通常のrouteと同様である。
無事に設定が完了したら、ip route showコマンドで確認する。たとえばこんな感じ。
# ip route show table livingroom
192.168.1.0/24 via 192.168.1.1 dev eth0
192.168.0.0/24 via 192.168.0.1 dev eth1
default via 61.200.36.8 dev ppp0 proto static
# ip route show table storeroom
192.168.1.0/24 via 192.168.1.1 dev eth0
192.168.0.0/24 via 192.168.0.1 dev eth1
default via 210.136.1.49 dev tap0 proto static
storeroom(物置)に置いてある192.168.0.0/24のサーバ群は、210.136.1.49を通じて外部へ出る。
livingroom(居間)に置いてある192.168.1.0/24のクライアント群は、61.200.36.8を通じて外部へ出る。
自分自身のネットワークに対するrouteが必要なのは、これが無いとLinux router自身がパケットを受け付けないため。
これでとりあえず、ホストごとに出口を振り分ける第一歩が完成だ。やれやれ、オツカレサマ。
えっ、Linux router自身はどうやって外に出ていくのかって?それは(もちろん)通常どおり(mainテーブル)ですがな。これですよ、これ。
# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
(中略)
0.0.0.0 210.136.1.49 0.0.0.0 UG 0 0 0 tap0
p.s.
この手法は、まだふたつ課題を残している。
動的IP割当のPPP接続において、いったん切断されてしまったあとの経路更新はどうする?
また、ポートごとに経路を指定するにはどうする?
以下次号。
|