web-dev-qa-db-ja.com

3.6以降のカーネルでのマルチパスルーティング

ご存知のとおり、マルチパスルーティングに深刻な影響を与えていた3.6 Linuxカーネルシリーズでは、ipv4ルートキャッシュが削除されています。 IPv4ルーティングコード(IPv6とは異なり)は、ラウンドロビン方式でネクストホップを選択するため、特定の送信元IPから特定の宛先IPへのパケットが常に同じネクストホップを経由するわけではありません。 3.6より前は、ルーティングキャッシュがその状況を修正していました。ネクストホップは、一度選択されるとキャッシュにとどまり、同じ送信元から同じ宛先へのすべてのパケットがそのネクストホップを通過するためです。これで、パケットごとにネクストホップが再選択されるため、奇妙な事態が発生します。ルーティングテーブルに2つの等しいコストのデフォルトルートがあり、それぞれが1つのインターネットプロバイダーをポイントしているため、TCP =接続。これは、初期SYNと最終ACKが異なるルートを経由するため、およびNATのため、各パスで、異なる送信元からのパケットとして宛先に到着します。

パケットごとではなくフローごとにネクストホップが選択されるように、マルチパスルーティングの通常の動作を復元する比較的簡単な方法はありますか? IPv6の場合のように、IPv4ネクストホップ選択をハッシュベースにするためのパッチはありますか?または、どのように対処しますか?

16
Eugene

可能であれば、Linuxカーネル> = 4.4 ...にアップグレードしてください。

ハッシュベースのマルチパスルーティング が導入されました。これは、3.6より前の動作よりも多くの点で優れています。これはフローベースであり、ソースと宛先のIP(ポートは無視されます)のハッシュを取得して、個々の接続のパスを安定させます。欠点の1つは、3.6より前のバージョンではさまざまなアルゴリズム/構成モードが利用可能であったと私は信じているが、今ではあなたが与えられたものを手に入れる!ただし、weightによってパスの選択に影響を与えることができます。

私の状況 にいる場合、実際には3.6 >= behaviour < 4.4がサポートされなくなりました。

> = 4.4にアップグレードする場合、他のすべてのコマンドなしでこれでうまくいくはずです。

ip route add default  proto static scope global \
nexthop  via <gw_1> weight 1 \
nexthop  via <gw_2> weight 1

別の方法として:

ip route add default  proto static scope global \
 nexthop  dev <if_1> weight 1 \
 nexthop  dev <if_2> weight 1
8
bao7uo

「比較的簡単」は難しい用語ですが、

  1. リンクごとにルーティングテーブルを設定する-リンクごとに1つのテーブル、単一のデフォルトゲートウェイ
  2. netfilterを使用して、単一のストリームのすべてのパケットに同一のマークを付ける
  3. iPルールテーブルを使用して、マークに応じて異なるルーティングテーブル経由でパケットをルーティングします
  4. マルチネクストホップの加重ルートを使用して、ゲートウェイ/リンク上でセッション内の最初のパケットのバランスをとります。

このトピックについて netfilterメーリングリストでの議論 があり、ここからリストを盗んでいます:

1。ルーティングルール(RPDBおよびFIB)

ip route add default via <gw_1> lable link1
ip route add <net_gw1> dev <dev_gw1> table link1
ip route add default via <gw_2> table link2
ip route add <net_gw2> dev <dev_gw2> table link2

/sbin/ip route add default  proto static scope global table lb \
 nexthop  via <gw_1> weight 1 \
 nexthop  via <gw_2> weight 1

ip rule add prio 10 table main
ip rule add prio 20 from <net_gw1> table link1
ip rule add prio 21 from <net_gw2> table link2
ip rule add prio 50 fwmark 0x301 table link1
ip rule add prio 51 fwmark 0x302 table link2
ip rule add prio 100 table lb

ip route del default

2。ファイアウォールルール(ipsetを使用して「フロー」LBモードを強制する)

ipset create lb_link1 hash:ip,port,ip timeout 1200
ipset create lb_link2 hash:ip,port,ip timeout 1200

# Set firewall marks and ipset hash
iptables -t mangle -N SETMARK
iptables -t mangle -A SETMARK -o <if_gw1> -j MARK --set-mark 0x301
iptables -t mangle -A SETMARK -m mark --mark 0x301 -m set !
--match-set lb_link1 src,dstport,dst -j SET \
          --add-set lb_link1 src,dstport,dst
iptables -t mangle -A SETMARK -o <if_gw2> -j MARK --set-mark 0x302
iptables -t mangle -A SETMARK -m mark --mark 0x302 -m set !
--match-set lb_link2 src,dstport,dst -j SET \
          --add-set lb_link2 src,dstport,dst

# Reload marks by ipset hash
iptables -t mangle -N GETMARK
iptables -t mangle -A GETMARK -m mark --mark 0x0 -m set --match-set
lb_link1 src,dstport,dst -j MARK --set-mark 0x301
iptables -t mangle -A GETMARK -m mark --mark 0x0 -m set --match-set
lb_link2 src,dstport,dst -j MARK --set-mark 0x302

# Defining and save firewall marks
iptables -t mangle -N CNTRACK
iptables -t mangle -A CNTRACK -o <if_gw1> -m mark --mark 0x0 -j SETMARK
iptables -t mangle -A CNTRACK -o <if_gw2> -m mark --mark 0x0 -j SETMARK
iptables -t mangle -A CNTRACK -m mark ! --mark 0x0 -j CONNMARK --save-mark
iptables -t mangle -A POSTROUTING -j CNTRACK

# Reload all firewall marks
# Use OUTPUT chain for local access (Squid proxy, for example)
iptables -t mangle -A OUTPUT -m mark --mark 0x0 -j CONNMARK --restore-mark
iptables -t mangle -A OUTPUT -m mark --mark 0x0 -j GETMARK
iptables -t mangle -A PREROUTING -m mark --mark 0x0 -j CONNMARK --restore-mark
iptables -t mangle -A PREROUTING -m mark --mark 0x0 -j GETMARK

上記のいくつかのバリエーションについては、netfilterメーリングリストのディスカッションをフォローすることをお勧めします。

6
the-wabbit