そのため、構成では、最初に発信元としてネットワークに送信しようとするすべてのパケット10.0.0.1
(tun0
インターフェースを経由していて、そのローカルアドレスがであるため10.0.0.1
)です。パケットをキャプチャすると、すべてはこれまでのところ問題ありません。
次に、tun0
パケットをさらに送信します。送信元アドレスはで10.0.0.1
あり、パケットは別のインターフェース(wlp2s0
あなたの場合)を通過するようにします。それがルーティングなので、最初にルーティングを有効にしましょう。
sysctl -w net.ipv4.ip_forward=1
その後、見てみると、パケットが、wlanインターフェースの送信元アドレスではなく送信元アドレスで送信されtcpdump
ているwlp2s0
ことが10.0.0.1
わかります(私が推測しているとおりです)。したがって、送信元アドレスを変更する必要があり、これを送信元NATと呼びます。Linuxでは、netfilter / iptablesを使用すると簡単です。
iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.0.1 -j MASQUERADE
また、FORWARD
チェーンにACCEPT
ポリシーがあることを確認してください。そうでない場合は、次のような転送を許可する必要があります。
iptables -A FORWARD -i tun0 -o wlp2s0 -s 10.0.0.1 -j ACCEPT
iptables -A FORWARD -i wlp2s0 -o tun0 -d 10.0.0.1 -j ACCEPT
これですべてが動作するはずです。Linuxカーネルはルーティングを行い、パケットをtun0
インターフェイスからに移動しますwlp2s0
。netfilterは、ソースIP 10.0.0.1
を、wlp2s0
出力パケット用のインターフェイス割り当てアドレスに変更する必要があります。すべての接続を記憶し、応答パケットが戻った場合(それらの場合)、アドレスをwlp2s0
割り当てられたインターフェースの宛先アドレスを変更します10.0.0.1
(「conntrack」機能)。
まあ、それはすべきですが、そうではありません。netfilterは、この複雑なルーティング構成と、同じパケットが最初にOUTPUT
チェーンを通過し、次にルーティングされてチェーンに到達するという事実と混同されているようPREROUTING
です。少なくともDebian 8ボックスでは動作しません。
netfilterの
トラブルシューティングに最適な方法は、次のTRACE
機能です。
modprobe ipt_LOG
iptables -t raw -A OUTPUT -p icmp -j TRACE
iptables -t raw -A PREROUTING -p icmp -j TRACE
ICMPパケットのトレースのみを有効にします。デバッグには他のフィルターを使用できます。
パケットが通過するテーブルとチェーンが表示されます。そして、私はパケットがFORWARD
チェーンにそれ以上行かないことを見ることができます(そしてnat/POSTROUTING
実際に実行するチェーンによってキャッチされませんSNAT
)。
以下は、これを機能させるためのいくつかのアプローチです。
アプローチ#1
netfilterを混乱させない最善の方法は、tun0.c
アプリケーションのパケットのソースIPアドレスを変更することです。それは最も自然な方法でもあります。途中で10.0.0.1から10.0.0.2に変更し、途中で10.0.0.2から10.0.0.1に変更する必要があります。ソースアドレス変更コードで
変更tun0.c
しました。ここに新しいファイルがあり、ここにパッチファイルがありますtun0.c
。IPヘッダーの変更にはチェックサム修正も含まれるため、OpenVPNプロジェクトからいくつかのコードを取得しました。クリーンな再起動と起動後に実行するコマンドの完全なリストは tun0_changeip.c
次のとおりです。
ifconfig tun0 inet 10.0.0.1/30 up
sysctl -w net.ipv4.ip_forward=1
ip route add default dev tun0 table John
ip rule add from all lookup John
ip rule add from 10.0.0.2 lookup main priority 500
iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.0.2 -j MASQUERADE
その場合、リバースパスフィルタリングをオフにする必要はありません。すべてが合法であるためです- tun0
サブネットに属するパケットのみを送受信します。また、インターフェイスベースの代わりにソースベースのルーティングを実行できます。
アプローチ#2
SNAT
パケットがtun0
インターフェイスに到達する前に行うことができます。しかし、それはあまり正しくありません。この場合は、リバースパスフィルタリングをオフにする必要があります。
sysctl -w net.ipv4.conf.tun0.rp_filter=0
# It won't work without also changing the "all" value
sysctl -w net.ipv4.conf.all.rp_filter=0
次に、SNAT
iptables -t nat -A POSTROUTING -o tun0 -s 10.0.0.1 -j SNAT --to-source ip.address.of.your.wlan.interfaceを実行します。
ここでは、パケットがデバイスに到達する直前に送信元アドレスを変更しtun0
ます。tun0.c
コードはこれらのパケットを(変更されたソースアドレスで)「そのまま」再送信し、WLANインターフェイスを介して正常にルーティングされます。ただし、wlanインターフェイスに動的IPがあり、使用したい場合がありますMASQUERADE
(インターフェイスアドレスを明示的に指定しないため)。以下が利用方法ですMASQUERADE
:
iptables -t nat -A POSTROUTING -o tun0 -s 10.0.0.1 -j SNAT --to-source 10.0.55.1
iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.55.1 -j MASQUERADE
10.0.55.1
IPアドレスに注意してください-それは異なります。ここでは任意のIPを使用できますが、問題ではありません。以前にソースIPを変更すると、パケットnat/POSTROUTING
はwlp2s0
インターフェイス上のチェーンに到達します。そして今では、WLANインターフェースの静的IPに依存していません。
アプローチ#3
を使用することもできますfwmark
。この方法では不要ですSNAT
が、送信パケットのみをキャプチャします。
まず、別のネットワークに属するパケットを転送するため、リバースパスフィルタリングを無効にする必要がありtun0
ます。
sysctl -w net.ipv4.conf.tun0.rp_filter=0
# It won't work without also changing the "all" value
sysctl -w net.ipv4.conf.all.rp_filter=0
Now let's alter the routing rules a bit:
# Delete old rules
ip rule del iif tun0 lookup main
ip rule del from all lookup John
# Packets will start going from wlan interface so they will have source address of it
iptables -t mangle -A OUTPUT -o wlp2s0 -j MARK --set-mark 1
ip rule add fwmark 0x1 lookup John
これは、私のDebian 8ボックスで機能するルーティングとネットフィルターのもう1つの「ハック」ですが、より自然でハックを使用しないため、最初のアプローチを取ることをお勧めします。
アプリケーションを透過プロキシとして構築することも検討できます。tunデバイスからのパケットを分析するよりもはるかに簡単だと思います。
-j SNAT
ませんでした-s SNAT