運用NICを持つLinuxサーバなどでは、非対称ルーティングを回避するためにPBR(Policy-Based Routing: ポリシーベースルーティング)を設定する場合がある。Dockerコンテナ宛通信もPBR対象とするためには、単純なソースIFでのPBRだけでは制御できないため、fwmarkにより通信を識別し、応答IFを固定する。
OS:CentOS7
NIC構成
eth0が通常NICで、こちらをデフォルトGWに設定している。eth1は運用用として、特定宛先との通信に使用する。運用セグメントからはeth0, eth1ともにアクセスするが、通常ルーティングでは応答パケットはeth0から送信される。
# ip a 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether <MAC1> brd ff:ff:ff:ff:ff:ff inet <IP0> brd <BRD0> scope global noprefixroute eth0 valid_lft forever preferred_lft forever 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether <MAC1> brd ff:ff:ff:ff:ff:ff inet <IP1> brd <BRD1> scope global noprefixroute eth1 valid_lft forever preferred_lft forever
複数NIC時のPBR
通常の複数NIC構成時のPBRは以下の記事の通り設定できる。 blog.serverworks.co.jp
Docker宛通信を制御可能にする
しかし、Docker宛通信は上記では制御できない。そのため、以下の通り設定する。
NetworkManagerのdispatcher機能を有効にする。
yum install NetworkManager-config-routing-rules systemctl enable NetworkManager-dispatcher.service systemctl start NetworkManager-dispatcher.service
ルーティングテーブルを追加する。ここではeth1という名前で作成する。
# vi /etc/iproute2/rt_tables --- # # reserved values # 255 local 254 main 253 default 0 unspec # # local # #1 inr.ruhep 100 eth1 ###Add###
運用NICのruleを作成する。通常はここはfrom
でeth1
のIPアドレスを設定するが、fwmark
で設定する。
※eth1
はサーバのIF名に合わせて要調整。
# vi /etc/sysconfig/network-scripts/rule-eth1 fwmark 0x1 table eth1
運用NICからの通信用ルートを作成する。
# vi /etc/sysconfig/network-scripts/route-eth1 0.0.0.0/0 via <GW1> table eth1
networkサービスを再起動する。
systemctl restart network.service
ルールが追加された。
# ip rule show 0: from all lookup local 32765: from all fwmark 0x1 lookup eth1 ###Added### 32766: from all lookup main 32767: from all lookup default
ルールにマッチするようfwmarkを付与するiptablesを設定する。
iptables -t mangle -A PREROUTING -m conntrack ! --ctstate NEW --ctdir REPLY -m connmark ! --mark 0x0 -j CONNMARK --restore-mark iptables -t mangle -A OUTPUT -m conntrack ! --ctstate NEW --ctdir REPLY -m connmark ! --mark 0x0 -j CONNMARK --restore-mark iptables -t mangle -A PREROUTING -i eth1 -m conntrack --ctstate NEW --ctdir ORIGINAL -j CONNMARK --set-mark 0x1
これにより、eth1で受けたリクエストはeth1から応答するようになる。
iptablesの設定を永続化する
iptablesコマンドで設定した内容は再起動時に揮発してしまうため、設定ファイルを作成して永続化する。
https://tech.godpress.net/?p=503
firewalldは停止し、iptablesサービスをインストール・有効化する。
systemctl disable firewalld systemctl stop firewalld yum install iptables-services systemctl enable iptables systemctl start iptables
起動時に読み込むiptablesのルールを作成する。個別の設定がある場合はiptables save
を使用して調整する。
# vi /etc/sysconfig/iptables.save *mangle -A PREROUTING -m conntrack ! --ctstate NEW --ctdir REPLY -m connmark ! --mark 0x0 -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff -A PREROUTING -i eth1 -m conntrack --ctstate NEW --ctdir ORIGINAL -j CONNMARK --set-xmark 0x1/0xffffffff -A OUTPUT -m conntrack ! --ctstate NEW --ctdir REPLY -m connmark ! --mark 0x0 -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff COMMIT
まとめ - Docker対応PBRで複数NICのLinuxで必ず受信IFから応答(非対称ルーティング回避)するよう設定する
fwmarkによるPBRを設定することで、Dockerコンテナ宛通信においても非対称ルーティングを回避し、受信IFから応答するようにできる。