そのため、構成では、最初に発信元としてネットワークに送信しようとするすべてのパケット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
次に、SNATiptables -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.1IPアドレスに注意してください-それは異なります。ここでは任意の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