Я смог настроить сетевое пространство имен, установить туннель с openvpn и запустить приложение, которое использует этот туннель внутри пространства имен. Пока все хорошо, но к этому приложению можно получить доступ через веб-интерфейс, и я не могу понять, как перенаправлять запросы на веб-интерфейс внутри моей локальной сети.
Я следовал руководству от @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>
Приложение запущено, я использую потоп для этого примера. Я попробовал несколько приложений с веб-интерфейсом, чтобы убедиться, что это не проблема, связанная с потопом.
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
Я могу получить доступ к веб-интерфейсу через порт 8112 из пространства имен и извне, если я укажу ip veth vpn1.
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 с моего сервера на приложение в пространстве имен. Цель состоит в том, чтобы открыть браузер на компьютере в моей локальной сети и получить веб-интерфейс с 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 и бросил MASQUERADE для хорошей меры, но так как я не знаю, что я делаю, мои попытки тщетны. Возможно, кто-то может помочь мне собрать эту конструкцию.
РЕДАКТИРОВАТЬ: выход tcpdump tcpdump -nn -q tcp port 8112
. Неудивительно, что первая команда возвращает HTTP 200, а вторая команда завершается с отклоненным соединением.
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 сам указал мне на статью администрации Debian, объясняющую универсальный TCP-прокси iptables . Применительно к рассматриваемой проблеме их сценарий будет выглядеть следующим образом:
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, но моя проблема решена сейчас.
veth
устройствами (нахожу это очень интересным, хотя ... ;-)). Вы использовалиtcpdump
для проверки, как далеко зашли входящие пакеты? Еслиtcpdump -i veth0
ничего не показывает, тоtcpdumo -i lo
может понадобиться.