web-dev-qa-db-ja.com

新しいVPN接続のルーティングとiptablesをセットアップして、**ポート80と443のみ**をリダイレクトします

ISPの制限を回避するための新しいVPN接続(openvpnを使用)があります。それが正常に機能している間、それはall VPN上のトラフィックを取っています。これにより、ダウンロード(インターネット接続はVPNで許可されているよりもはるかに高速です)、およびリモートアクセスで問題が発生しています。私はsshサーバーを実行していて、電話を介してダウンロードをスケジュールできるデーモンを実行しています。

Eth0に既存のイーサネット接続があり、tun0に新しいVPN接続があります。

192.168.0.0/24ネットワーク上の既存のeth0接続を使用するためにデフォルトルートを設定し、デフォルトゲートウェイを192.168.0.1に設定する必要があると思います(これを何年も行っていないため、私の知識は不安定です)。それが正しければ、私はそれをどのように行うのか正確にはわかりません!。私の現在のルーティングテーブルは次のとおりです。

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface    MSS   Window irtt
0.0.0.0         10.51.0.169     0.0.0.0         UG    0      0        0 tun0     0     0      0
10.51.0.1       10.51.0.169     255.255.255.255 UGH   0      0        0 tun0     0     0      0
10.51.0.169     0.0.0.0         255.255.255.255 UH    0      0        0 tun0     0     0      0
85.25.147.49    192.168.0.1     255.255.255.255 UGH   0      0        0 eth0     0     0      0
169.254.0.0     0.0.0.0         255.255.0.0     U     1000   0        0 eth0     0     0      0
192.168.0.0     0.0.0.0         255.255.255.0   U     1      0        0 eth0     0     0      0

ルーティングを修正した後、iptablesを使用して、事前ルーティングまたはマスカレードを構成し、tun0を介して宛先ポート80または443のすべてを強制する必要があると思います。繰り返しますが、これを行う方法が正確にはわかりません!

私がインターネットで見つけたものはすべて、はるかに複雑なことをしようとしており、木から木を選別しようとすることは困難であることが証明されています。

どんな助けでも大歓迎です。

[〜#〜]更新[〜#〜]

これまでのところ、さまざまな情報源から、私は次のことをまとめました。

#!/bin/sh

DEV1=eth0
IP1=`ifconfig|Perl -nE'/dr:(\S+)/&&say$1'|grep 192.`
GW1=192.168.0.1
TABLE1=internet
TABLE2=vpn
DEV2=tun0
IP2=`ifconfig|Perl -nE'/dr:(\S+)/&&say$1'|grep 10.`
GW2=`route -n | grep 'UG[ \t]' | awk '{print $2}'`

ip route flush table $TABLE1
ip route flush table $TABLE2
ip route show table main | grep -Ev ^default | while read ROUTE ; do
    ip route add table $TABLE1 $ROUTE
    ip route add table $TABLE2 $ROUTE
done
ip route add table $TABLE1 $GW1 dev $DEV1 src $IP1
ip route add table $TABLE2 $GW2 dev $DEV2 src $IP2
ip route add table $TABLE1 default via $GW1
ip route add table $TABLE2 default via $GW2

echo "1" > /proc/sys/net/ipv4/ip_forward
echo "1" > /proc/sys/net/ipv4/ip_dynaddr

ip rule add from $IP1 lookup $TABLE1
ip rule add from $IP2 lookup $TABLE2
ip rule add fwmark 1 lookup $TABLE1
ip rule add fwmark 2 lookup $TABLE2

iptables -t nat -A POSTROUTING -o $DEV1 -j SNAT --to-source $IP1
iptables -t nat -A POSTROUTING -o $DEV2 -j SNAT --to-source $IP2

iptables -t nat -A PREROUTING           -m state --state ESTABLISHED,RELATED          -j CONNMARK --restore-mark
iptables        -A OUTPUT               -m state --state ESTABLISHED,RELATED          -j CONNMARK --restore-mark
iptables -t nat -A PREROUTING -i $DEV1  -m state --state NEW                          -j CONNMARK --set-mark 1
iptables -t nat -A PREROUTING -i $DEV2  -m state --state NEW                          -j CONNMARK --set-mark 2
iptables -t nat -A PREROUTING           -m connmark --mark 1                          -j MARK --set-mark 1
iptables -t nat -A PREROUTING           -m connmark --mark 2                          -j MARK --set-mark 2
iptables -t nat -A PREROUTING           -m state --state NEW -m connmark ! --mark 0   -j CONNMARK --save-mark

iptables -t mangle -A PREROUTING -i $DEV2 -m state --state NEW -p tcp --dport  80 -j CONNMARK --set-mark 2
iptables -t mangle -A PREROUTING -i $DEV2 -m state --state NEW -p tcp --dport 443 -j CONNMARK --set-mark 2

route del default
route add default gw 192.168.0.1 eth0

これでは機能しているようです。そうでないことを除いて!

ブロックされたWebサイトへの接続は通過し、ポート80および443以外の接続は非VPN接続を使用します。

ただしブロックされたWebサイトへの接続ではないポート80および443接続も非VPN接続を使用しています!

一般的な目標が達成されたので、私は比較的満足していますしかしそれが正確に正しく機能していない理由を知っておくといいでしょう。

何か案は?

参考までに、main、internet、vpnの3つのルーティングテーブルがあります。それらのリストは次のとおりです...

メイン:

default via 192.168.0.1 dev eth0 
10.38.0.1 via 10.38.0.205 dev tun0 
10.38.0.205 dev tun0  proto kernel  scope link  src 10.38.0.206 
85.removed via 192.168.0.1 dev eth0 
169.254.0.0/16 dev eth0  scope link  metric 1000 
192.168.0.0/24 dev eth0  proto kernel  scope link  src 192.168.0.73  metric 1 

インターネット:

default via 192.168.0.1 dev eth0 
10.38.0.1 via 10.38.0.205 dev tun0 
10.38.0.205 dev tun0  proto kernel  scope link  src 10.38.0.206 
85.removed via 192.168.0.1 dev eth0 
169.254.0.0/16 dev eth0  scope link  metric 1000 
192.168.0.0/24 dev eth0  proto kernel  scope link  src 192.168.0.73  metric 1 
192.168.0.1 dev eth0  scope link  src 192.168.0.73

VPN:

default via 10.38.0.205 dev tun0 
10.38.0.1 via 10.38.0.205 dev tun0 
10.38.0.205 dev tun0  proto kernel  scope link  src 10.38.0.206 
85.removed via 192.168.0.1 dev eth0 
169.254.0.0/16 dev eth0  scope link  metric 1000 
192.168.0.0/24 dev eth0  proto kernel  scope link  src 192.168.0.73  metric 1
8
Steve

したがって、これのほとんどは上記のとおりですが、全体的な解決策は次のとおりです。

/ etc/iproute2/rt_tablesを編集し、下部に2行追加します。

101 internet
102 vpn

これらのテーブルには、一貫性を保つために、より意味のある他の名前を付けることができます。

次に、/ etc/init.dにスクリプト(私はrt_setupと呼びます)を作成する必要があります。

#!/bin/sh

DEV1=eth0
IP1=`ifconfig|Perl -nE'/dr:(\S+)/&&say$1'|grep 192.`
GW1=192.168.0.1
TABLE1=internet
TABLE2=vpn
DEV2=tun0
IP2=`ifconfig|Perl -nE'/dr:(\S+)/&&say$1'|grep 10.`
GW2=`route -n | grep 'UG[ \t]' | awk '{print $2}'`

ip route flush table $TABLE1
ip route flush table $TABLE2
ip route show table main | grep -Ev ^default | while read ROUTE ; do
    ip route add table $TABLE1 $ROUTE
    ip route add table $TABLE2 $ROUTE
done
ip route add table $TABLE1 $GW1 dev $DEV1 src $IP1
ip route add table $TABLE2 $GW2 dev $DEV2 src $IP2
ip route add table $TABLE1 default via $GW1
ip route add table $TABLE2 default via $GW2

echo "1" > /proc/sys/net/ipv4/ip_forward
echo "1" > /proc/sys/net/ipv4/ip_dynaddr

ip rule add from $IP1 lookup $TABLE1
ip rule add from $IP2 lookup $TABLE2
ip rule add fwmark 1 lookup $TABLE1
ip rule add fwmark 2 lookup $TABLE2

iptables -t nat -A POSTROUTING -o $DEV1 -j SNAT --to-source $IP1
iptables -t nat -A POSTROUTING -o $DEV2 -j SNAT --to-source $IP2

iptables -t nat -A PREROUTING           -m state --state ESTABLISHED,RELATED          -j CONNMARK --restore-mark
iptables        -A OUTPUT               -m state --state ESTABLISHED,RELATED          -j CONNMARK --restore-mark
iptables -t nat -A PREROUTING -i $DEV1  -m state --state NEW                          -j CONNMARK --set-mark 1
iptables -t nat -A PREROUTING -i $DEV2  -m state --state NEW                          -j CONNMARK --set-mark 2
iptables -t nat -A PREROUTING           -m connmark --mark 1                          -j MARK --set-mark 1
iptables -t nat -A PREROUTING           -m connmark --mark 2                          -j MARK --set-mark 2
iptables -t nat -A PREROUTING           -m state --state NEW -m connmark ! --mark 0   -j CONNMARK --save-mark

iptables -t mangle -A PREROUTING -i $DEV2 -m state --state NEW -p tcp --dport  80 -j CONNMARK --set-mark 2
iptables -t mangle -A PREROUTING -i $DEV2 -m state --state NEW -p tcp --dport 443 -j CONNMARK --set-mark 2

route del default
route add default gw 192.168.0.1 eth0

次に、明らかに/etc/rc2.dからリンクします(私はubuntuを使用していますが、ランレベルは異なる場合があります)。 openvpnリンクよりも高いS番号を指定してください!

スクリプトは多くのことを行います。上部は変数を設定し、動的IPとゲートウェイアドレスを取得するためにいくつかのPerlおよびawkステートメントを使用します.2番目のセクションは、ipruote2で設定したテーブルをクリーンアップし、現在のルーティングテーブルをそれらにコピーします。次に、2つの新しいルートとそれらの2つのデフォルトゲートウェイを作成します。1つはVPNを経由し、もう1つはローカルネットワークを経由します。

次の2行が必要かどうかはわかりませんが、iptablesで使用するためにip転送が有効になります。

次に、スクリプトは、関連するIPアドレスから発信されたトラフィックを探す場所、およびトラフィックが明確にマークされているかどうかを調べる場所に関するいくつかのルールを作成します。

POSTROUTINGとPREROUTINGは、アドレスから発信されたトラフィックが確実に応答を受け取るようにします。

最後のiptablesPREROUTINGは、トラフィックにタグを付ける部分であり、ポート80または443に送信されるすべてのものが表2(VPN)を使用するようにマークされていることを確認します。

最後の2行は、デフォルトのルーティングテーブルからVPNゲートウェイを削除し、ローカルネットワークゲートウェイを追加し直します。

現状では、プロセスは見事に機能します。マシンが起動するとVPNが開始され、このスクリプトは数秒後に実行されます(このスクリプトを実行する前に、VPNが完全に初期化されていることを確認するためにsleepステートメントを追加する場合があります)。私のリモートアクセス接続(sshなど)はうまく機能します。ポート80または443に接続しない接続は、ローカル接続を使用していますが、すべてのWebトラフィックはVPNを経由しており、ISPによって設定された制御をバイパスしています。

私の質問の下で私のコメントで言ったように、私は@anttirの提案なしにこのルートを見始めさえしなかっただろう。その提案の裏側で、​​サイト http://blog.khax.net/2009/11/28/multi-gateway-routing-with-iptables-and-iproute2/ および http://linux-ip.net/html/adv-multi-internet.html 非常に便利です(コードが100%完全でなくても!)

4
Steve

プロトコルごとのルーティングは少し複雑です。通常、ルーティングテーブルは、宛先IPに従ってゲートウェイをチェックし、openvpnまたは192.168.0.1のデフォルトゲートウェイのいずれかを使用するために使用されます。

設定が簡単になります。 VPNのもう一方の端にあるSquidhttpプロキシを使用し、プロキシを使用するようにブラウザを設定します。

HTTP接続の宛先IPを変更し、機能しないため、iptablesは使用しません。

デフォルトルートをVPNエンドポイントに設定して新しいルーティングテーブル(/ etc/iproute2/rt_tables)を作成し、iptables fwmark(-j MARK)を使用してすべてのHTTPパケットをマークしてから、ip ruleを使用できます。マークされたパッケージのカスタムルールを作成して、新しいルーティングテーブルを使用します。

1
Antti Rytsölä