Debian GNU/Linux + iproute2 + 複数ISP

最新の情報を追いかける訳でもなく、ただひたすら必要な情報だけを仕入れたいと思っているだけである。それなのに、なかなか必要な情報を web で手に入れることができない。昔は今よりはマシだった。かなりの情報を手に入れることができた。ところがこうなってしまったのは、どうしたことか。これは困ったことである。おそらく原因のひとつは、こうした情報に詳しい人は、仕事がいっぱい降ってきて、なかなかホームページを書いている暇が無いからだ。そうした余裕の無さは、昨今の社会の風潮を考えると致し方ないのかもしれない。しかし、それはユーザーのハッキング精神を著しく低下させ、長い目でみると、日本のソフトウエア生産性を低下させることになるだろう。ちなみに、私が言っているのは、Googlegoogle:iproute2 "ip route add" table 複数 eth0:0 で検索してヒットした量である。今日の時点で わずか 10 件。

閑話休題

家の事情で専用光回線が引けない。その一方で怪しい共同の光回線がある。高速通信の必要性があるので、しかたなく、ADSL 回線を維持したまま、共用の光回線も使うことにする。こうした契約をするのは、ややお金がもったい。しかし、申し込んでいながら新しい光回線を十分に利用できていなかったので、もっとお金がもったいない。実は、二つの回線を上手に使い分ける方法を知らないまま申し込んでいたのだ。当初は、2台のサーバを立てることを考えていた。しかし、家庭内環境に与える騒音の影響を考えると、2つ立てるのもためらってしまっていた。そんなこんなを考えながら、早3ヶ月も無駄にお金を払ってしまっていた。しかし、原因は私の不明だけでは無く、こうした情報が極端に web 上に少ないからだ。おっと、また話題が逸れた。

さて、やりたいことを具体的に書くと、次のようになる。

  1. 1. 複数のプロバイダ(ISP)と契約する。
  2. 2. それぞれのプロバイダには、それぞれのルータで接続する。
  3. 3. 上記のルータ(2つ)とサーバを家庭内LANで接続する。
  4. 4. ルータの NAT (iptable) 機能を用いて、外部からの通信(例えば httpd の 80番ポートへの通信)をサーバに向ける。
  5. 5. サーバには、どちらの ISP からもアクセスできるようにする。

ここで、1〜4 は、それぞれルータやプロバイダの説明書を読めばよい。問題は 5 である。簡単そうに見えて、実は難しい。古い方法では解決できない。なぜかというと、default の通信経路を指定すると、どちらのプロバイダからの通信も、default の通信経路で返事をしようとしてしまうからだ。これを解決するために、iproute2 を用いることにする。なお、このように二つのプロバイダを使うことを「マルチホーミング」と言うらしい。また、複数のプロバイダに接続する機能を「マルチセッション」と言うらしい。

○ 接続

        ISP1  -- ルータ1 (192.168.0.1)---+
                                         |  192.168.0.80(eth0)
                                         +--                    サーバ  (ppp0) -- VPN(おまけ) --
                                         |  192.168.0.81(eth0:0)
                                         |
                                         |
                                         +----192.168.0.201 client (おまけ)
                                         |
        ISP2  -- ルータ2 (192.168.0.2)---+x

○ 設定

  1. 1. kernel 2.6.x で CONFIG_IP_ADVANCED_ROUTER が組み込まれているようにする。
  2. 2. iproute2 を導入( apt-get install iproute )
  3. 3. カーネルにルータ機能を持たせる。
	echo 1 > /proc/sys/net/ipv4/ip_forward
  1. 4. eth0 に IPアドレスを二つ持たせる(IPaliasing と以前は言っていた)。例えば、/etc/network/interfaces に次のように書く。
	auto eth0
	iface eth0 inet static
	        address 192.168.0.80
		netmask 255.255.255.0
		broadcast 192.168.0.255
		gateway 192.168.0.1

	auto eth0:0
	iface eth0:0 inet static
	        address 192.168.0.81
		netmask 255.255.255.0
		broadcast 192.168.0.255
  1. 5. ルータの機能で、ポート転送を設定する際、二つのルータに対して、それぞれ別の IPアドレスを指定する。例えば、ISP1 は、ルータ1 経由で、192.168.0.80 へ転送し、ISP2 は、ルータ2 経由で 192.168.0.81 へ転送する。
  2. 6. 旧来のコマンドで、ルータ2経由の経路も作る。(root で) 既に /etc/network/interfaces で、192.168.0.1 が default の経路であると指定されていることに注意。
      route add default gw 192.168.0.2 dev eth0:0 metric 1
  1. 7. ここから iproute2 を利用する。まず、通信についての「テーブル」を作成する。192.168.0.2 を経由した通信を table 1 とする。(root で)
      ip route add table 1 default via 192.168.0.2
  1. 8. 次に、どのような条件の時にそのテーブルに沿った通信をするか指定する。ここでは、192.168.0.81 からの(〜 ISP2からの)通信は、table 1 で通信するように指定する。
      ip rule add from 192.168.0.81 table 1 pref 30001
  1. 9. (optional) ちなみに、サーバが VPN を張っているとし、client(192.168.0.201) は ISP2 を利用し、VPN も利用したいとする。 Windows のように、client で細かな制御ができない場合には、次のようにする…(未完成。これではダメだった)。
    1. 9.1 client の default の gateway を サーバ(192.168.0.80)にする。
    2. 9.2 サーバ上で次のようにする。
      ip rule add from 192.168.0.201 table 1 pref 30002

これで(8.までは)うまくいくように思う。なお、この記事は、ド素人が書いているので、自己責任でお試しください。

○ 参考にした URL (感謝)