ネットワーク名前空間をセットアップし、openvpnでトンネルを確立し、名前空間内でこのトンネルを使用するアプリケーションを起動することができました。これまでのところ良好ですが、このアプリケーションはWebインターフェイス経由でアクセスでき、LAN内のWebインターフェイスにリクエストをルーティングする方法がわかりません。
私は@schnoukiからのガイドに従って説明しました ネットワーク名前空間を設定し、その中でOpenVPNを実行する方法
ip netns add myvpn
ip netns exec myvpn ip addr add 127.0.0.1/8 dev lo
ip netns exec myvpn ip link set lo up
ip link add vpn0 type veth peer name vpn1
ip link set vpn0 up
ip link set vpn1 netns myvpn up
ip addr add 10.200.200.1/24 dev vpn0
ip netns exec myvpn ip addr add 10.200.200.2/24 dev vpn1
ip netns exec myvpn ip route add default via 10.200.200.1 dev vpn1
iptables -A INPUT \! -i vpn0 -s 10.200.200.0/24 -j DROP
iptables -t nat -A POSTROUTING -s 10.200.200.0/24 -o en+ -j MASQUERADE
sysctl -q net.ipv4.ip_forward=1
mkdir -p /etc/netns/myvpn
echo 'nameserver 8.8.8.8' > /etc/netns/myvpn/resolv.conf
その後、意図したとおりに、外部IPをチェックして、名前空間の内外で異なる結果を取得できます。
curl -s ipv4.icanhazip.com
<my-isp-ip>
ip netns exec myvpn curl -s ipv4.icanhazip.com
<my-vpn-ip>
アプリケーションが起動し、この例では大洪水を使用しています。私はそれが大洪水の特定の問題ではないことを確認するために、Webインターフェイスでいくつかのアプリケーションを試しました。
ip netns exec myvpn Sudo -u <my-user> /usr/bin/deluged
ip netns exec myvpn Sudo -u <my-user> /usr/bin/deluge-web -f
ps $(ip netns pids myvpn)
PID TTY STAT TIME COMMAND
1468 ? Ss 0:13 openvpn --config /etc/openvpn/myvpn/myvpn.conf
9302 ? Sl 10:10 /usr/bin/python /usr/bin/deluged
9707 ? S 0:37 /usr/bin/python /usr/bin/deluge-web -f
Veth vpn1のIPを指定すると、名前空間内および外部からポート8112のWebインターフェイスにアクセスできます。
ip netns exec myvpn curl -Is localhost:8112 | head -1
HTTP/1.1 200 OK
ip netns exec myvpn curl -Is 10.200.200.2:8112 | head -1
HTTP/1.1 200 OK
curl -Is 10.200.200.2:8112 | head -1
HTTP/1.1 200 OK
しかし、サーバーからポート8112をネームスペースのアプリケーションにリダイレクトしたいのですが。目標は、LAN内のコンピューターでブラウザーを開き、Webインターフェイスを http:// my-server-ip:8112 で取得することです(my-server-ipはサーバーの静的IPです)ネットワークインターフェースをインスタンス化したもの)
編集:iptablesルールを作成する試みを削除しました。私がやろうとしていることは上記で説明されており、次のコマンドはHTTP 200を出力するはずです。
curl -I localhost:8112
curl: (7) Failed to connect to localhost port 8112: Connection refused
curl -I <my-server-ip>:8112
curl: (7) Failed to connect to <my-server-ip> port 8112: Connection refused
私はDNATとSNATのルールを試し、マスカレードを適切に投入しましたが、自分が何をしているのかわからないので、私の試みは無駄です。おそらく誰かが私がこの構造を組み立てるのを手伝ってくれるでしょう。
編集:tcpdump -nn -q tcp port 8112
のtcpdump出力。当然のことながら、最初のコマンドはHTTP 200を返し、2番目のコマンドは拒否された接続で終了します。
curl -Is 10.200.200.2:8112 | head -1
listening on vpn0, link-type EN10MB (Ethernet), capture size 262144 bytes
IP 10.200.200.1.36208 > 10.200.200.2.8112: tcp 82
IP 10.200.200.2.8112 > 10.200.200.1.36208: tcp 145
curl -Is <my-server-ip>:8112 | head -1
listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
IP <my-server-ip>.58228 > <my-server-ip>.8112: tcp 0
IP <my-server-ip>.8112 > <my-server-ip>.58228: tcp 0
編集:@schnouki自身が私に 一般的なiptablesを説明するDebian管理の記事TCPプロキシ を指摘しました。手元の問題に適用すると、スクリプトは次のようになります:
YourIP=<my-server-ip>
YourPort=8112
TargetIP=10.200.200.2
TargetPort=8112
iptables -t nat -A PREROUTING --dst $YourIP -p tcp --dport $YourPort -j DNAT \
--to-destination $TargetIP:$TargetPort
iptables -t nat -A POSTROUTING -p tcp --dst $TargetIP --dport $TargetPort -j SNAT \
--to-source $YourIP
iptables -t nat -A OUTPUT --dst $YourIP -p tcp --dport $YourPort -j DNAT \
--to-destination $TargetIP:$TargetPort
残念ながら、vethインターフェース間のトラフィックは捕捉され、他には何も起こりませんでした。しかし、@ schnoukiはsocat
をTCPプロキシとして使用することも提案しており、これは完全に機能しています。
curl -Is <my-server-ip>:8112 | head -1
IP 10.200.200.1.43384 > 10.200.200.2.8112: tcp 913
IP 10.200.200.2.8112 > 10.200.200.1.43384: tcp 1495
トラフィックがvethインターフェイスを通過しているときに奇妙なポートがシャッフルすることをまだ理解していませんが、私の問題はこれで解決しました。
私は常にiptablesのリダイレクトに関する問題を抱えてきました(おそらく私のせいです、私はそれができると確信しています)。しかし、あなたのようなケースでは、iptablesなしでユーザーランドでそれを行うほうがIMOの方が簡単です。
基本的に、TCPポート8112でリッスンし、すべてのトラフィックを10.200.200.2ポート8112にリダイレクトする「デフォルト」ワークスペースにデーモンを配置する必要があります。したがって、これは単純なTCPプロキシ。
socat でそれを行う方法は次のとおりです:
socat tcp-listen:8112,reuseaddr,fork tcp-connect:10.200.200.2:8112
(fork
オプションは、最初のプロキシ接続が閉じられた後にsocat
が停止しないようにするために必要です)。
[〜#〜] edit [〜#〜]:コメントで提案されているようにreuseaddr
を追加しました。
どうしてもiptablesを使用したい場合は、 Debian Administration サイトにガイドがあります。しかし、私はより高度なもののためにsocat
を好みます-IPv4からIPv6へのプロキシ、またはSSLを取り除いて古いJavaプログラムが安全なサービスに接続できるようにする...
ただし、Delugeでのすべての接続は、実際のクライアントIPではなくサーバーIPから行われることに注意してください。これを避けたい場合は、元のクライアントIPをHTTPヘッダーのプロキシされたリクエストに追加する実際のHTTPリバースプロキシを使用する必要があります。
ネットワークの名前空間とメインの名前空間を相互接続することは常に私を悩ませます。名前空間を通常作成するのは、それを分離したいからです。それが何であるかに応じて、相互接続を作成する名前空間で達成しようとしていることは、その目的を無効にする可能性があります。
しかし、孤立していても、便宜上、ネットワーク経由でそれを突く必要があります。
このソリューションを使用すると、分離を維持し、とにかくいくつかの接続を転送できます。 1つのポートを転送するためだけに、2つのネットワーク名前空間間にすべてのネットワークを作成する必要はありません。接続を受け入れる名前空間でこれを実行します。 ip netns exec
が機能するには、rootとして実行する必要があります。
socat tcp-listen:8112,fork,reuseaddr \
exec:'ip netns exec myvpn socat STDIO tcp-connect\:127.0.0.1\:8112',nofork
ポート8112で実行する1つのネットワーク名前空間で接続をリッスンし、接続されたクライアントはexec
を取得してip netns exec myvpn ...
を実行し、myvpn
ネットワーク名前空間内の残りを実行します。 myvpn
ネットワーク名前空間内に入ると、別のsocat
との2番目の接続が再び作成されます。
@AndrDevEKの回答が役立ちます。それを拡張するために、socat
をインストールしたくない場合があります。その場合、わずかに複雑なSSHポート転送設定で同じことを実現できます。 unix-domainソケットはネットワーク名前空間とは独立して動作するため、特にunix-domainソケットとの間のポート転送機能はここで役立ちます。
Sudo ip netns exec myvpn su -c "ssh -N -L /tmp/myunixsock:localhost:8112 localhost" $USER &
ssh_pid1=$!
ssh -N -L localhost:8112:/tmp/myunixsock localhost &
ssh_pid2=$!
掃除:
Sudo kill $ssh_pid1
kill $ssh_pid2
rm /tmp/myunixsock
最初 ssh -N -L
は、myvpn名前空間内で開始されます。これにより、UNIXドメインソケットが作成されます/tmp/myunixsock
とそれをリッスンします。着信接続は(myvpn名前空間内の)localhost:8112に転送されます。二番目 ssh -N -L
はデフォルトの名前空間で開始されます。これにより、リスニングTCP=ポートが作成され、着信接続がUNIXドメインソケットに転送されます。
これが機能するためには、ネットワークネームスペース内のssh
がまだ機能していない場合は機能している必要があります(パスワードなしのpubkey操作が役立つ)。
Sudo ip netns exec myvpn ip link set up dev lo
Sudo ip netns exec myvpn /usr/sbin/sshd -o PidFile=/run/sshd-myvpn.pid
ssh-copy-id localhost
ここで大洪水が私の解決策です。 iptablesは必要ありません。手順は次のとおりです。
ip netns add $ NS #TUNが起動するのを待ちます while [[$(ip route | grep $ TUN | wc -l)== 0]];寝る1; done MY_IP = $(ip addr show $ TUN | grep inet | cut -d '' -f6 | cut -d '/' -f1) #ゲートウェイIPを抽出する方法はopenvpn接続では異なります。 GATEWAY_IP = $ MY_IP #$ TUN(VPNインターフェース)を名前空間にジェイルします ip link set $ TUN netns $ NS #サブネットを使用してインターフェースを起動します(VPNサーバーから与えられたものと同等) ip netns exec $ NS ifconfig $ TUN $ MY_IP/24 up #ループバックを起動します ip netns exec $ NS ifconfig lo 127.0.0.1/8 up #リモートゲートウェイをセットアップします(ポイントツーポイントVPN IPアドレス) ip netns exec $ NS route add default gw $ GATEWAY_IP
#名前空間間の通信用のvethインターフェースを設定します ip link add veth0 type veth peer name veth1 #2番目のvethを名前空間に移動します ip link set veth1 netns $ NS #未使用のIP範囲から最初のvethにIPを割り当てます ifconfig veth0 10.1.1.1/24 up #そして2番目のIPは ip netns exec $ NS ifconfig veth1 10.1 .1.2/24 up #TODO:LANと通信できるようにveth1とethインターフェイスの間にブリッジをセットアップします #DNSクライアントをセットアップします。 ip netnsは、次のファイルを使用して/etc/resolv.confをエミュレートします。 mkdir -p /etc/netns/$NS echo "nameserver 8.8.4.4">/etc/netns/$ NS/resolv.conf
出来上がり! VPNの背後でセキュリティが侵害され、ホームネットワークで自由にWebにアクセスできる