web-dev-qa-db-ja.com

複数のアップリンク/プロバイダーのルーティング

私は2つのインターネット接続を備えたPCを持っています。 1つ目は、ローカルネットワークに接続し、ルーター経由でインターネットにアクセスするためのイーサネットインターフェイスです。 2つ目は、GSMモデムを使用してpppに接続します。

インターフェースを指定するときに、各接続を個別に使用できるようにしたいと思います。例:

ping -I eth0 www.google.com
ping -I ppp0 www.google.com

また、インターフェースが選択されておらず、eth0を介した接続が機能する場合はデフォルトでeth0を使用できますが、eth0を介した接続が機能しない場合はppp0を使用できます。

これを読んで 記事 そして次のルールを作成しました:

# Main table
ip route add 10.0.0.0/24 dev eth0 src 10.0.0.100
ip route add 10.64.64.64 dev ppp0 src 10.123.122.101
ip route add default via 10.0.0.1

# Specific tables
ip route add 10.0.0.0/24 dev eth0 src 10.0.0.100 table eth0
ip route add default via 10.0.0.1 table eth0
ip route add 10.64.64.64 dev ppp0 src 10.123.122.101 table ppp0
ip route add default via 10.64.64.64 table ppp0

# Rules
ip rule add from 10.0.0.100 table eth0
ip rule add from 10.123.122.101 table ppp0

最初はうまくいくようです。ただし、eth0テーブルは使用されていないようです。私は次のことが起こると思っていました:

ping -I eth0 www.google.ch    # Use default gateway in table eth0
ping -I ppp0 www.google.ch    # Use default gateway in table ppp0
ping www.google.ch            # Use default gateway (main)

ただし、デフォルトゲートウェイ(メイン)を削除すると、eth0インターフェイスがまったく機能しなくなります。明らかに私にはわからないことがあります。私が望むことを達成する方法を説明してもらえますか?

@derobertの回答に従って編集:

次の構成をテストしましたが、同じエラーが発生します(ppp0では問題ありませんが、eth0では機能しません)。

ルート:

# ip rule list
0:      from all lookup local
1500:   from 10.0.0.100 lookup eth0
1501:   from 10.123.122.101 lookup ppp0
2000:   from all fwmark 0x1 lookup eth0
2001:   from all fwmark 0x2 lookup ppp0
32766:  from all lookup main
32767:  from all lookup default

# ip route list table eth0
10.0.0.0/24 dev eth0  src 10.0.0.100
default via 10.0.0.1 dev eth0

# ip route list table ppp0
10.64.64.64 dev ppp0  src 10.123.122.101
default via 10.64.64.64 dev ppp0

# ip route list table main
10.64.64.64 dev ppp0  src 10.123.122.101
192.168.1.0/24 dev eth1  src 192.168.1.1
10.0.0.0/24 dev eth0  src 10.0.0.100

ファイアウォール:

# iptables -L
Chain INPUT (policy DROP)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

# iptables -L -t mangle
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
CONNMARK   all  --  anywhere             anywhere            CONNMARK restore
RETURN     all  --  anywhere             anywhere            mark match !0x0
MARK       all  --  anywhere             anywhere            MARK set 0x1
MARK       all  --  anywhere             anywhere            MARK set 0x2

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
MARK       all  --  anywhere             anywhere            MARK set 0x1
MARK       all  --  anywhere             anywhere            MARK set 0x2
CONNMARK   all  --  anywhere             anywhere            CONNMARK save

# iptables -L -t nat
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
SNAT       all  --  10.0.0.1             anywhere            to:10.0.0.100
SNAT       all  --  10.64.64.64          anywhere            to:10.123.122.101

他のすべてのファイアウォールルールを削除して、干渉しないようにしました。私はこの結果を得る:

# ip route get 8.2.1.1 from 10.0.0.100
8.2.1.1 from 10.0.0.100 via 10.0.0.1 dev eth0

# ip route get 8.2.1.1 from 10.123.122.101
8.2.1.1 from 10.123.122.101 via 10.64.64.64 dev ppp0

# ping -I ppp0 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: seq=0 ttl=45 time=350.108 ms
64 bytes from 8.8.8.8: seq=1 ttl=45 time=349.768 ms
64 bytes from 8.8.8.8: seq=2 ttl=45 time=329.671 ms
^C
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 329.671/343.182/350.108 ms

128# ping -I eth0 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
^C
--- 8.8.8.8 ping statistics ---
5 packets transmitted, 0 packets received, 100% packet loss

ルールは問題ないようですが、明らかに別の問題があります。ここでのSNATの役割はよくわかりません。間違っているかもしれないので、答えの構成を反映するルールを追加しました。

5
slepasteur

私はもう少し複雑な構成を持っています。これには、マシン上のNATおよび動的(内部)ルーティングも含まれます。

それにはいくつかの部分があります。ルールから始めましょう:

Maginot:~# ip rule ls
0:      from all lookup local 
1000:   from all lookup main 
1500:   from 173.167.51.136/29 lookup comcast 
1501:   from 76.160.165.106/29 lookup cavtel 
1502:   from 151.200.251.90/31 lookup vzdsl 
1502:   from 151.200.251.92/31 lookup vzdsl 
1502:   from 151.200.251.94 lookup vzdsl 
2000:   from all fwmark 0x1 lookup comcast 
2001:   from all fwmark 0x2 lookup cavtel 
2002:   from all fwmark 0x3 lookup vzdsl 
2500:   from all lookup comcast 
2501:   from all lookup cavtel 
2502:   from all lookup vzdsl 
32767:  from all lookup default 

(テーブルには/etc/iproute2/rt_tablesで名前が付けられています)

ご覧のとおり、現在3つのISPがあり、それぞれに2つの静的IPアドレスがあります。ルール1500〜1502は、これらの送信元IPアドレスからのトラフィックを適切なインターフェイスに送信します。ルール2000〜2002は、特定のファイアウォールマーク(これについては説明します)を使用してトラフィックを適切なインターフェイスに送信します。ルール2500〜2502は、まだISPに割り当てられていないトラフィックについて、ISPの優先順位を示しています。 1つがダウンした場合は、そのルールを削除し、リストの次のルールが使用されます。

各ルーティングテーブルは非常に簡単です。

Maginot:~# ip route ls table comcast
default via 173.167.51.142 dev comcast 

(ローカルルートとメインルートにはさらに多くのものがありますが、それぞれ直接接続ルートと内部ルートです。テーブルのデフォルトは空です)。

次に、接続がISPに割り当てられると、そこにとどまることが重要です(着信接続を含む)。インターフェイスごとに異なるIPアドレスがあり、ISPには実際にはリバースパスフィルタリングがあるため、移動しようとすることは不可能です。ファイアウォールルールを使用して、それらを同じISPに保持します。

SNATが実行されることを忘れないでくださいルーティングなので、ip ruleポリシーは役に立ちません。あなたは何か他のものを使わなければなりません(多分これはあなたの問題ですか?)

iptables -t mangle -A PREROUTING -j CONNMARK --restore-mark
iptables -t mangle -A PREROUTING -m mark ! --mark 0 -j RETURN # if already set, we're done
iptables -t mangle -A PREROUTING -i wan                                       -j MARK --set-mark $MARK_CAVTEL
iptables -t mangle -A PREROUTING -i comcast                                   -j MARK --set-mark $MARK_COMCAST
iptables -t mangle -A PREROUTING -i vz-dsl                                    -j MARK --set-mark $MARK_VZDSL

iptables -t mangle -A POSTROUTING -o wan     -j MARK --set-mark $MARK_CAVTEL
iptables -t mangle -A POSTROUTING -o comcast -j MARK --set-mark $MARK_COMCAST
iptables -t mangle -A POSTROUTING -o vz-dsl  -j MARK --set-mark $MARK_VZDSL
iptables -t mangle -A POSTROUTING -j CONNMARK --save-mark

これは、それを設定するシェルスクリプトからのものです。 $MARK_…変数は、上記のルールに表示されるマークと一致します。かなり単純です:接続マークを復元します(マークはパケットごとであることを忘れないでください)。 (接続マークから)現在マークがあれば、完了です。それ以外の場合は、関連するインターフェースに基づいたマークにマークを設定します。

マークbeforeルーティングを復元し、後でのみ保存することに注意してください。そして、マークは関係なく発信インターフェイスに設定されます(これは議論の余地があります)。

最後に、実際のNATルールがあります。いくつかのローカルプレフィックスがあります。このコードは、$localがそれぞれに設定されたforループで実行されます。

iptables -t nat -A POSTROUTING -s $local -o wan     -j SNAT --to-source 76.160.165.106
iptables -t nat -A POSTROUTING -s $local -o comcast -j SNAT --to-source 173.167.51.137
iptables -t nat -A POSTROUTING -s $local -o vz-dsl  -j SNAT --to-source 151.200.251.90

(注:DMZサーバーなどのいくつかのDNATを含む、さらに多くのルールがあります。.関連するすべてのルールをコピーしたと思います。)

3
derobert

Eth0デバイスの重みをppp0デバイスよりも高い優先度に設定する必要があります。

例:

ip route append default scope global nexthop via 10.0.0.1 dev eth0 weight 2 nexthop via 10.64.64.65 dev ppp0 weight 3
0
harrijs