CentOS7 で policy routing する (複数のデフォルトゲートウェイを設定する)

表題でハマったのでメモ.今回はインターフェイス毎にデフォルトゲートウェイを設定して対称ルーティング(入出力インターフェイスが同じ)することが目的だった.

結論

CentOS7 で policy routing (例えば,今回のように送信元IPアドレスによってルーティングを変える) を行う場合, NetworkManager-config-routing-rules をインストールして /etc/sysconfig/network-scriptsroute-<interface-name>, rule-<interface-name> という2つのファイルを作成する. route-<interface-name> にはインターフェイス毎のルーティングルールを記述する. rule-<interface-name> にはルーティングルールの適用条件を記述する.

インターフェイス毎にデフォルトルートを設定する

サーバが2つのインターフェイス(eth0, eth1) をもっており,それぞれ次のIPアドレスをもっていたとする.

eth0 192.168.0.2/24
eth1 192.168.1.2/24

このとき,ルータでソースアドレスフィルタリングを設定している場合,このサーバからの返信パケットは破棄される可能性がある.通常デフォルトルートは一つしか設定できない.よって eth0 で受信したパケットも eth1 で受信したパケットも,返信パケットはデフォルトルートを設定したインターフェイス,例えば, eth0 から発信される.このとき,送信元アドレスが 192.168.1.2 であるパケットが 192.168.0.0/24 のサブネットに流れ,ルータのソースアドレスフィルタリングにて破棄される.

そこで, 受信したインターフェイスから返信パケットが発信されるようにソースアドレスに基づくルーティングを設定する.

一時的な設定

次のコマンドで一時的な設定ができる.まず,ルーティングテーブルを設定する.

sudo ip route add 192.168.0.0/24 dev eth0 tab 100
sudo ip route add 192.168.1.0/24 dev eth1 tab 101
sudo ip route add default via 192.168.0.1 dev eth0 tab 100
sudo ip route add default via 192.168.1.1 dev eth1 tab 101

次にルーティングテーブルの適用条件を設定する.ここではパケットの送信元アドレスが 192.168.0.2 の場合 table 100 を, 192.168.1.2 の場合 table 101 を適用するように設定している.

sudo ip rule add from 192.168.0.2/32 tab 100 priority 100
sudo ip rule add from 192.168.1.2/32 tab 101 priority 200
sudo ip route flush cache

なお,設定内容は ip rule show, ip route show table 100, ip route show table 101 で確認できる.

永続的な設定

上の設定は再起動後に消えてしまう.再起動後も有効にするには /etc/sysconfig/network-scriptsroute-<interface-name>, rule-<interface-name> に次のように先の設定を記述する.

mano@server % cat route-eth0
192.168.0.0/24 dev eth0 tab 100
default via 192.168.0.1 dev eth0 tab 100
mano@server % cat route-eth1
192.168.1.0/24 dev eth1 tab 101
default via 192.168.1.1 dev eth1 tab 101
mano@server % cat rule-eth0
from 192.168.0.2/32 tab 100 priority 100
mano@server % cat rule-eth1
from 192.168.1.2/32 tab 101 priority 200

また, NetworkManager-config-routing-rules をインストールする.このパッケージは Minimal Install には含まれない.このパッケージは Minimal Install には含まれない(重要なことなので2回書いた).なお,上のパッケージなしで,次のコマンドを実行すると問題なくルーティングテーブルが作成されるという罠.

/etc/sysconfig/network-scripts/ifup-routes eth0

sudo journalctl -u NetworkManager -p 4 して次のようなメッセージを発見してパッケージが必要であることに気がついた.

<warn> 'rule-' or 'rule6-' file is present;
install the NetworkManager-config-routing-rules package to enable these routes