Linuxで特定のIPへの通信に特定のインタフェースを使う

Rasberry PiでEthernetで繋いだネットワークとUSB Ethernetアダプタで繋いだネットワークを別々のセグメントに接続し、いざ通信しようとするとうまく行かないことがありました。

状況は、

  • eth0はグローバルへ出るためのIFでIPはDHCPで取得
  • eth1は特定機器との通信用でありIPは静的かつグローバルに出られない

この状態でブートすると、ping 8.8.8.8等グローバルの通信ができず。eth1がホストに到達できないと答える。 route -nで調べてみるとデフォルトゲートウェイがeth1とその所属するセグメントに取られていた。

調べてみると解決法はいくつかあるようですがディストリビューション特有のものもある……、今回は自分の機材ではないのでわかりやすくしたい。 ということで、一つのファイルを見ればわかるよう/etc/network/interfacesをいじって解決しました。

sudo vim /etc/network/interfaces

auto lo eth0

iface io inet loopback

iface default inet dhcp

iface eth0 inet dhcp

allow-hotplug eth1
iface eth1 inet static
address 172.31.40.24
netmask 255.255.255.0
network 172.31.40.0
broadcast 172.31.40.255
gateway 172.31.40.254
up route add -net 172.31.40.19/32 gw 172.31.40.19 dev eth1
up route del default gw 172.31.40.254

下2行が問題解決のために記述した設定です。

up route add -net XXX.XXX.XXX.XXX/ZZ gw YYY.YYY.YYY.YYY dev [Interface]

1行で特定機器への通信のためにeth1を使用するようにしました。XXX/ZZはどのnetwork宛の通信にInterfaceを使うかで、YYYはそのInterfaceのデフォルトゲートウェイのIPです(自分の場合はeth1)。

up route del default gw QQQ.QQQ.QQQ.QQQ

2行でおそらくdhcpでIPをもらう前に定義されてしまったであろうデフォルトゲートウェイを削除しました。 完璧にデフォルトゲートウェイを更新するのであれば新しいデフォルトゲートウェイを書いてやる必要があるかと思いますが、今回はせっかくDHCPでIPを取得しているので、放置することで正しいルートを見つけ出してくれることを期待して祈りながらリブートしました。 無事eth0がデフォルトゲートウェイとして使われるようになり問題は解決。やったぜ。