サーバーに2つのパブリックネットワークアドレスがあるとします。1つはISPを介したNAT(192.168.99.0/24)で、もう1つは別のISPを介したVPN(192.168.1.0/24)で、すでにper- ISPを介したVPNサーバーへのホストルート。
これが私の最初のルーティングテーブルです。現在、サブネット192.168.99.0/24のISPを介してルーティングしています。
$ route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.99.1 0.0.0.0 UG 0 0 0 eth1
55.66.77.88 192.168.99.1 255.255.255.255 UGH 0 0 0 eth1
192.168.99.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 tap0
ここで、新しいTCP接続を192.168.1.0/24に切り替えたいので、次のように入力します。
$ route add -net 0.0.0.0 gw 192.168.1.1 dev tap0
これを行うと、長年のTCP接続がハングします。既存のTCP接続が古いルートを使用できるようにしながら、新しい接続のデフォルトインターフェイスを安全に変更する方法はありますか(つまり、ある種のステートフルルーティングテーブルを有効にする必要がありますか)?
私は確立されたTCP接続でのみ機能するソリューションで大丈夫です、そしてそれがどれほどハックであるかは気にしません。たとえば、既存の接続に一時的なiptablesルールを追加して、それらを古いルートに強制する方法がある場合です。しかし、これを行うにはsome方法が必要です。
編集:既存の接続の単純な「routeadd -Host ...」についてのメモ:このソリューションは、古いインターフェイスにIPのサブセットを残して問題がなければ機能します。ただし、私のアプリケーションでは、ソースIPが同じであっても、新しいインターフェイスで新しい接続を許可したいので、これでは実際には問題は解決しません。現在、「iproute」コマンドを使用してソースベースのルーティングルールを設定することを検討しています。
次のコマンドは、開いているtcp接続を調べ、ローカルネットワーク外の宛先を一覧表示します。
$ netstat -4ntu | tail -n +3 | cut -c45-65 | cut -d: -f1 | grep -v '192.168.99' | grep -v '192.168.1'
214.236.220.101
63.171.235.16
174.63.61.132
159.47.216.178
62.59.197.29
139.47.218.150
56.4.17.22
204.63.49.5
155.9.79.196
144.31.207.66
したがって、このリストを繰り返し処理し、デフォルトルートを変更する前に、メインルーターに向けて特定のルートを設定する必要があります。
for i in $(netstat -4nt | tail -n +3 | cut -c45-65 | cut -d: -f1 |grep -v '192\.168\.99' | grep -v '192\.168\.1') ; do echo route add -Host $i gw 192.168.1.99; done
(私はそこに「echo」コマンドを残しているので、それが何をするのかを見ることができます。実際にやりたいときにこれを削除できます。
次に、デフォルトルートを変更します。
$ route add -net 0.0.0.0 gw 192.168.1.1 dev tap0
追加されたルートはより具体的であるため、デフォルトルートよりも優先されます。明らかに、これをスクリプトに入れて簡単にすることができます。