Я смог настроить сетевое пространство имен, установить туннель с 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
может понадобиться.Ответы:
У меня всегда были проблемы с перенаправлениями iptables (возможно, моя вина, я уверен, что это выполнимо). Но для случая, подобного вашему, IMO проще сделать это в пользовательской среде без iptables.
По сути, вам нужно, чтобы в вашей рабочей области «по умолчанию» был демон, прослушивающий TCP-порт 8112 и перенаправляющий весь трафик на порт 8112.10.2.2. Так что это простой TCP-прокси.
Вот как это сделать с помощью socat :
(
fork
Опция необходима, чтобы избежатьsocat
остановки после закрытия первого прокси-соединения).РЕДАКТИРОВАТЬ : добавлено,
reuseaddr
как предлагается в комментариях.Если вы абсолютно хотите сделать это с помощью iptables, на сайте администрирования Debian есть руководство . Но я все еще предпочитаю
socat
более сложные вещи, такие как проксирование IPv4 в IPv6 или удаление SSL, чтобы старые программы Java могли подключаться к защищенным сервисам ...Однако помните, что все соединения в Deluge будут с IP вашего сервера, а не с реального IP-адреса клиента. Если вы хотите избежать этого, вам потребуется использовать реальный обратный прокси-сервер HTTP, который добавляет исходный IP-адрес клиента к прокси-запросу в заголовке HTTP.
источник
socat
и это в точности соответствует тому, что я пытался сделать с iptables уже довольно давно. Я протестировал несколько приложений, и все они работают безупречно, подключаясь к внешнему миру через tun0, и в то же время предоставляя доступ к их веб-интерфейсу через veth1.reuseaddr
флаг. Это предотвращаетport already in use
ошибки при запуске и остановке socat в быстрой последовательности:socat -4 TCP-LISTEN:8112,reuseaddr,fork TCP:10.200.200.2:8112
Соединение сетевого пространства имен с основным пространством имен меня всегда беспокоит. Причина, по которой я обычно создаю пространство имен, заключается в том, что я хочу, чтобы оно было изолированным. В зависимости от того, чего вы пытаетесь достичь с помощью пространств имен, создание межсоединений может победить эту цель.
Но даже в одиночестве я все еще хочу выложить его по сети, для удобства.
Это решение позволяет вам сохранять изоляцию и пересылать некоторые соединения к нему в любом случае. Вам не нужно создавать всю эту сеть между двумя сетевыми пространствами имен только для переадресации одного порта. Запустите это в пространстве имен, где вы хотите принимать соединения. Должен быть запущен как root для
ip netns exec
работы.Он прослушивает соединения в одном сетевом пространстве имен, где вы его запускаете, на порту 8112, затем подключенный клиент
exec
запускаетсяip netns exec myvpn ...
для выполнения остальных внутриmyvpn
сетевого пространства имен, а затем, оказавшись внутриmyvpn
сетевого пространства имен, он снова создает второе соединение с другимsocat
.источник
:
символа заключены в одинарные кавычки, иначе вы можете столкнуться с ошибкой... wrong number of parameters (2 instead of 1)
(2 или 3). В противном случае: отлично работает! Огромное спасибо!Для потопа вот мое решение. Нет необходимости в iptables. Вот шаги:
Вуаля! Вы защищены deluge за VPN, а ваш deluge-web свободно доступен в вашей домашней сети.
источник
@ AndrDevEK ответ полезен. Чтобы расширить это, вы можете не захотеть устанавливать
socat
. В этом случае вы можете добиться того же с помощью немного запутанной настройки переадресации порта SSH. В частности, здесь полезна функция переадресации портов в / из сокета unix-домена, поскольку сокеты unix-домена работают независимо от пространств имен сети:Очистка:
Первый
ssh -N -L
запускается в пространстве имен myvpn. Это создает сокет unix-домена/tmp/myunixsock
и прослушивает его. Входящие соединения пересылаются на localhost: 8112 (внутри пространства имен myvpn). Второйssh -N -L
запускается в пространстве имен по умолчанию. Это создает прослушивающий TCP-порт и перенаправляет входящие соединения в сокет домена unix.Следует отметить, что для того, чтобы это работало,
ssh
внутреннее пространство имен сети должно работать, если это еще не сделано (и операция pubkey без пароля полезна):источник