同じサブネットに属するIPアドレスを持つ複数のNICを扱う方法
(How to configure routing tables for multiple NICs assigned IP addresses on the same subnet)
なんでそんなことしたかったかというと
アホな例
ネットワークのことはなんも知らないので、とりあえず昔の記憶を頼りに次のように設定してみた。ネットワークインターフェイスのエイリアスというやつです。
ちなみに以下のような環境となっています。
ネットワーク: 10.0.0.0/24
ゲートウェイ: 10.0.0.1
ブロードキャストアドレス: 10.0.0.255
ENI #1 | primary | 10.0.0.128 |
~ | secondary | 10.0.0.129 |
ENI #2 | primary | 10.0.0.130 |
~ | secondary | 10.0.0.131 |
/etc/network/interfaces:
auto lo iface lo inet loopback auto eth0 iface eth0 inet static address 10.0.0.128 netmask 255.255.255.0 gateway 10.0.0.1 auto eth0:0 iface eth0:0 inet static address 10.0.0.129 netmask 255.255.255.0 auto eth1 iface eth1 inet static address 10.0.0.130 netmask 255.255.255.0 gateway 10.0.0.1 auto eth1:0 iface eth1:0 inet static address 10.0.0.131 netmask 255.255.255.0
これして、
$ service networking restart
をやってみると、まあ応答がなくなるわけです。
仕方ないので、EBSボリュームを同じリージョンの別のインスタンスに attach してサルベージしました。
何が悪いか、どうすればいいか
同じルーティングテーブル上で、同じネットワークやデフォルトのルートは当然の事ながら 1 つしか許可されません。なので、inbound については区別がつきますが、outbound については区別をしてあげる必要があります。
eth0 の IP address を source とする outbound の場合は、eth0、 eth1 の IP address を source とする outbound の場合は、eth1 を使うように設定します。
結局どうしたか
いろいろ検索してみても、ぴったりの回答が得られなかったのですが、いろいろな情報をもとに試行錯誤した結果です。基本的には、ip コマンドフル活用でpolicy-based routingします。
まず eth1 の IP アドレスですが、エイリアスを使うのはやめて ip コマンドでやってしまいましょう。
# ip addr add 10.0.0.130/24 broadcast 10.0.0.255 dev eth1 # ip addr add 10.0.0.131/24 broadcast 10.0.0.255 dev eth1
eth0 の場合はデフォルトで設定されるので、eth1 の場合のみ別のルーティングテーブルを作り対処します。
まずはルーティングテーブルに手頃な名前をつけるために /etc/iproute2/rt_tables を編集します。
/etc/iproute2/rt_tables:
# # reserved values # 255 local 254 main 253 default 0 unspec # # local # 1 sibling_eth1
ルーティングテーブルにはそれぞれ 1〜255 の番号がついていて、253〜255 はシステムで予約されています。1〜252 のうちで使っていない番号を選んで、sibling_eth1 という名称にします。
次に、 sibling_eth1 をクリアします。
# ip route flush table sibling_eth1
sibling_eth1 に、ルートを足します
# ip route add table sibling_eth1 10.0.0.0/24 dev eth1 proto kernel scope link # ip route add table sibling_eth1 default via 10.0.0.1 dev eth1
main のテーブルに eth1 用のルールが足されているといけないので、これを消します
# ip route del 10.0.0.0/24 dev eth1
最後に、source が 10.0.0.130 か 10.0.0.131 だった場合にこのルーティングテーブルを代わりに使うようにルールを設定します。
# ip rule add from 10.0.0.130 table sibling_eth1 # ip rule add from 10.0.0.131 table sibling_eth1
これで OK なはず。
リブート後も有効になるようにしたければ、
/etc/network/interfaces で eth1 の設定については
auto eth1 iface eth1 inet manual up /etc/network/configure_sibling_eth1
として、
/etc/network/configure_sibling_eth1 に適当に上記の内容をシェルスクリプトにして書いておきます。
本当は
down /etc/network/deconfigure_sibling_eth1
として、設定をもとに戻すのを書いておくべきなんだけど、そこは適当に。