新しいVPN接続のルーティングとiptablesを設定して、ポート80と443のみ**をリダイレクトする**


8

新しいVPN接続(openvpnを使用)があり、ISPの制限を迂回できるようになっています。正常に動作している間、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

今、これは機能しているようです。違います!

ブロックされたウェブサイトへの接続はされている、いないポート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

上記のスクリプトは期待どおりに動作します。10. netstatのアドレスから発信されるトラフィックが表示されることを期待していました。ただし、すべてのトラフィックは192から発信されますが、ポート80および443はVPN経由で送信されます。解決策全体を回答に入れますが、@ routetにiproute2とfwmarkを提案することを提案します。私はそれらに遭遇していませんでした、そしてそれらなしで私はまだレンガの壁に頭を叩いていました!
スティーブ

回答:


4

つまり、これのほとんどは上にありますが、解決策全体は次のとおりです:

/ 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つのデフォルトゲートウェイを作成します。VPNはVPNを経由し、インターネットはローカルネットワークを経由します。

次の2行が必要であるとは思いませんが、iptablesで使用するためにIP転送を有効にします。

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

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

最後のiptables PREROUTINGは、タグがトラフィックにタグを付ける部分であり、ポート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%完成していなくても!)


1
最後の追加sleep 20として、openvpn接続が時間内に完了しなかったため、スクリプトの先頭にを追加しました。echo 2 > /proc/sys/net/ipv4/conf/tun0/rp_filtertun0のリバースパケットフィルターを無効にする必要があるため、スクリプトにも追加しました。送信元アドレスSのtun0から応答が返されると、リバースパケットフィルターは、「アドレスSにパケットをルーティングする場合、tun0を通過しない場合、パケットをドロップします」をチェックします。これを行うと、有効なfwmarkが存在しないことを検索すると、ルートが通常のデフォルトルートになると判断され、パケットがドロップされます。
Steve

スクリプトを編集して機能させる必要がありました。最後の行route add default gw 192.168.0.1 eth0は、意図したとおりにtun0ではなく、ローカルゲートウェイを介してポート80/443トラフィックをルーティングするように見えました。最後の行をに変更すると、route add default tun0私にとってはうまくいくようです。

1

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

たとえば、VPNのもう一方の端にSquid httpプロキシを設定し、プロキシを使用するようにブラウザを設定する方が簡単です。

iptablesを使用しないでください。HTTP接続の宛先IPが変更され、機能しなくなります。

VPNエンドポイントに設定されたデフォルトルートを使用して新しいルーティングテーブル(/ etc / iproute2 / rt_tables)を作成し、iptables fwmark(-j MARK)を使用してすべてのHTTPパケットにマークを付け、次にipルールを使用して新しいルーティングテーブルを使用するようにマークされたパッケージ。


ご協力いただきありがとうございます。私は確かにそれらを見ていきます。サーバー側を制御できないため、私の側だけが少しトリッキーです。また、接続経由でhttpsトラフィックをルーティングする必要があるため、Squidを使用できません。Squidは、Squidでうまく機能しません。
Steve

VPNを介していくつかのIPだけをルーティングし、VPNの外の残りの部分をルーティングするのはどうですか?
AnttiRytsölä11年

ルーティングするIPはほんの数個と考えましたが、サイトが移動するとリストが変わるので、PCの他のユーザーがこれを使いやすくする必要があります。新しいルーティングテーブルの設定とパケットのマーキングを検討し始めました。パケットのマーキングは簡単なビットでした、それは私がよくわからないルーティングテーブルです。正しく見えるVPN用に1つ設定し、他のすべてに適切に見えるように設定することもできますが、mainをどうすればよいかわかりません。それでも...演奏
スティーブ

linux-ip.net/html/adv-multi-internet.html ip rule showおよびip rule add fwmark 4 table 4 priority 10000
AnttiRytsöläNov

これまでのところを詳しく説明しているオリジナルにアップデートを追加しました!ああ!私の質問ではなく、あなたの回答を編集したことに気づきました。ごめんなさい!これほど使ったことはなく、他の人の答えを編集できることに気づきませんでした。
Steve
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.