Как использовать namespaced-openvpn для VPN для каждого приложения?

Как использовать namespaced-openvpn для VPN для каждого приложения?

Это, вероятно, вопрос новичка, но...

Я использую Ubuntu 18.04.3 LTS и у меня естьVPNкоторый я хочу использовать для нескольких приложений. Я проверилnamespaced-openvpnи это работает! Проблема в том, что я не могу подключиться к этому приложению локально (в целях управления).

Есть ли способ перенаправить определенный порт внутри VPN-туннеля на локальный хост?без использования VPN-туннеля в других целях и, таким образом, утечки слишком большого количества информации?

Что я уже умею:

  • бегатьnamespaced-openvpn-скрипт:sudo ./namespaced-openvpn --namespace vpn --config /etc/openvpn/vpn-xxxxx.ovpn
  • выполнить приложение внутри сетевого пространства имен:sudo ip netns exec vpn application

Чего я хочу добиться:

  • подключиться к приложению, запущенному внутри VPN-туннеля (например, на порту 1234), с реального локального хоста ( enp3s0адаптера Ethernet)
  • перенаправить этот порт таким образом, чтобы я мог получить к нему доступ с других компьютеров в моей локальной сети

решение1

С опозданием на много лет, но на случай, если кто-то наткнется на это, как я хотел бы сделать в последние пару дней или около того.
Надеюсь, это кому-то поможет.

Во-первых, вот namespaced-vpn, который делает 90% работы по запуску всего этого.
https://github.com/slingamn/namespaced-openvpn

И вот ответ на вопрос, почти такой же, как этот, который мне очень помог, хотя я и не понимал, что и зачем делается. https://unix.stackexchange.com/questions/391193/how-to-forward-traffic-between-linux-network-namespaces

Я попытаюсь объяснить, что я понял после многих проб и ошибок, используя крупицы информации, которые я нашел в своих поисках.
Наиболее важной частью для перенаправления соединений к вашей службе (не с ПК, на котором запущена служба), я считаю, является эта (обратите внимание на восклицательный знак после PREROUTING):

iptables -t nat -A PREROUTING ! -s 10.0.0.0/24 -p tcp -m tcp --dport 80 -j DNAT --to-destination 10.0.0.2

Где, 10.0.0.0/24представляет собой диапазоны IP-адресов, которые НЕ ХОТИТЕ пересылать.
Это в основном необходимо для предотвращения петли маршрутизации, когда любые службы, доступные с использованием 10.0.0.0/24подсети, направляются обратно к себе.
--dport 80 — только для пересылки пакетов, ищущих порт 80, т. е. подключение к веб-серверу
10.0.0.2. — это интерфейс veth, который был перемещен ВНУТРИ пространства имен, на котором работает ваш сервер.
Это позволяет пакетам, поступающим НЕ из 10.0.0.0/24подсети, которые ищут службу порта 80, получать IP-адрес назначения, преобразованный в 10.0.0.2. Пример: 192.168.1.200:80становится 10.0.0.2:80, который предположительно является интерфейсом внутри пространства имен, в котором находится ваш сервер.

У меня есть несколько vpn-туннелей, работающих в нескольких пространствах имен. Если я не добавлю правило PREROUTING в свои iptables, я не смогу получить доступ к ресурсу из-за пределов моего ПК в моей локальной сети.

Если вы хотите, чтобы он был доступен с вашего ПК, вам нужно добавить правило, например:
iptables --table nat --append OUTPUT --destination 192.168.1.2 -p tcp -m tcp --dport 80 -j DNAT --to-destination 10.0.0.2
Таким образом, если вы вводите в браузере на ПК, на котором установлен сервер, 192.168.1.2чтобы получить доступ к своему серверу, он будет перенаправлен на 10.0.0.2.

Я попытаюсь объяснить часть моей установки...

Пример пространства имен:ip netns add ns_example

Создайте пару veth. Одна сторона останется в пространстве имен root/normal (я называю это host), другая сторона перейдет в пространство имен с VPN.
ip link add dev ihost type veth peer name ivpn

Переместите сторону vpn пары veth в целевое пространство имен:
ip link set dev ivpn netns ns_example

Назначьте IP-адреса созданной вами паре veth.

Я использую /32, потому что я хочу назначить только этот точный IP, а не диапазон. В противном случае, когда я поднимаю устройства, некоторые маршруты автоматически вставляются в мою ip routeтаблицу, и это портит мою маршрутизацию для моих других пространств имен.

Для назначения принимающей стороне.
ip addr add 10.0.0.1/32 dev ihost

Чтобы назначить сторону vpn, которая была перемещена в пространство имен, необходимо добавить к команде префикс ..
ip netns exec TARGET_NAMESPACE

Итак, чтобы назначить IP для VPN-стороны:
ip netns exec ns_example ip addr add 10.0.0.2/32 dev ivpn

Теперь поднимите интерфейсы.

ip link set dev ihost up

ip netns exec ns_example ip link set dev ivpn up

Здесь я добавляю маршруты и iptables, чтобы трафик шел между ними.
Из корневого пространства имен, чтобы попасть на сторону VPN( 10.0.0.2), используйте интерфейс ihost и перепишите исходный адрес на сторону корневого пространства имен( 10.0.0.1).
ip route add 10.0.0.2/32 dev ihost src 10.0.0.1

Сделайте то же самое, но с противоположной точки зрения внутри пространства имен VPN.
ip netns exec ns_example ip route add 10.0.0.1/32 dev ivpn src 10.0.0.2

Теперь я добавляю те же операции, iptablesкоторые являются отдельными, ip routeно выполняют схожие задачи.

Любой пакет, отправляемый на 10.0.0.2адрес источника, переписывается на10.0.0.1
iptables --table nat --append POSTROUTING --destination 10.0.0.2/32 --jump SNAT --to-source 10.0.0.1

То же самое, но с противоположной точки зрения и внутри пространства имен.
ip netns exec ns_example iptables --table nat --append POSTROUTING --destination 10.0.0.1/32 --jump SNAT --to-source 10.0.0.2

Если я правильно понимаю, перезапись исходного адреса нужна только для того, чтобы пакет знал, как выйти из пространства имен и наоборот.

Теперь, например: чтобы получить доступ к torrent webui в пространстве имен на порту 8080, я делаю это.
Любой пакет, идущий на мой LAN IP (пример: я ввожу 192.168.1.2:8080в браузере). Он перепишет пункт назначения на пространство имен, на котором работает мой torrent-клиент (пример: 10.0.0.2).
iptables --table nat --append OUTPUT --destination 192.168.1.2/32 --protocol tcp --match tcp --dport 8080 --jump DNAT --to-destination 10.0.0.2
Это правило специально перенаправляет только порт 8080, и это правило предназначено для вас, чтобы получить доступ к службе НА ПК, на котором она работает. Любому другому ПК в сети, получающему доступ, 192.168.1.2:8080нужно правило PREROUTING, которое я упомянул в начале ответа (просто измените --dport 80 на --dport 8080 или любой другой нужный вам порт/протокол).

Для тех, кто использует этот метод и скрипт namespaced-vpn.py. У вас могут возникнуть проблемы, если вам когда-либо придется сбросить vpn. Namespaced vpn выдает исключение, когда обнаруживает интерфейсы внутри вашего целевого пространства имен, отличные от loинтерфейса loopback.
Вот часть, которая выдает исключения для меня, когда я использую namespaced-vpn.py, когда мое целевое пространство имен уже существует и в нем есть мои пары veth.

if os.path.exists(os.path.join('/var/run/netns', namespace)):
        adapters = _adapter_names(namespace)
        if adapters != [b'lo']:
            LOG.error('Namespace %s already has adapters %s, exiting.' % (namespace, adapters))
            raise Exception

Вот пример модификации, которую я использовал.
allowed_adapters = [b'lo', b'ivpn']
if os.path.exists(os.path.join('/var/run/netns', namespace)):
     adapters = _adapter_names(namespace)
     # Iterate and ensure all are in allowed list
     for a in adapters:
         if not a.split(b'@')[0] in allowed_adapters:
            LOG.error('Namespace %s has non-whitelisted adapters %s, exiting.' % (namespace, adapters))
            raise Exception

Просто не забудьте добавить такой вызов для каждого интерфейса, который, как вы ожидаете, уже существует в нижней части функции `def setup_namespace(namespace)`. Замените LO на имя устройства.
subprocess.check_call(_enter_namespace_cmd(namespace) + [IP_CMD, 'link', 'set', 'LO', 'up'])

Пример:
subprocess.check_call(_enter_namespace_cmd(namespace) + [IP_CMD, 'link', 'set', 'ivpn', 'up'])

Для тех, кто использует клиент BitTorrent, подключенный к интерфейсу VPN, вы можете столкнуться с проблемой случайного прерывания соединения вашего клиента по любой причине. Например, вы просыпаетесь утром и видите, что все ваши прекрасные загрузки заморожены через 10 минут после того, как вы ушли.
Я считаю, что эта проблема возникает из-за программного обеспечения VPN IE OpenVPN, которое повторно подключается к провайдеру VPN по какой-либо причине (ошибка, перезапуск ping и т. д.) и получает новый IP-адрес. Интерфейс VPN может быть переведен в автономный режим на долю секунды, чтобы сбросить конфигурацию, и это приводит к сбоям в работе клиента (qBittorrent точно это делает). «Исправление», которое я начал изучать, заключается в написании скрипта, который определяет, когда интерфейс VPN получает новый IP-адрес или отключается по какой-либо причине. Скрипт должен корректно (важно: корректно, чтобы избежать повреждения чего-либо/ошибки файловой системы) выходить из клиента Torrent, а затем перезапускать его. У меня пока нет рабочего скрипта, но, похоже, это неплохой вектор для решения этой проблемы.

решение2

Ладно. Кажется, этот вопрос слишком сложен для того, чтобы на него кто-то мог ответить, или, возможно, на него уже отвечали, но никто не удосужился ответить.

В любом случае: я работал над этим еще один день и решил, что поскольку я заинтересован только в предоставлении доступа к одному порту для веб-интерфейса приложения, я могу также использоватьsocat. Так я и сделал.

После создания соединения namespaced-openvpn и запуска приложения внутри этого сетевого пространства имен я выполнил следующую команду в выделенном терминале:

sudo socat tcp-listen:PORT-TO-FORWARD-TO,fork,reuseaddr exec:'ip netns exec vpn socat STDIO tcp-connect\:127.0.0.1\:PORT-TO-LISTEN-TO',nofork

Примечания:

  • PORT-TO-FORWARD-TOэто порт, на который я хочу перенаправить порт (в корневом сетевом пространстве имен)
  • PORT-TO-LISTEN-TOэто порт приложения, который я хочу выставить в корневом пространстве имен
  • 127.0.0.1Мне пришлось использовать настоящий локальный IP-адрес (а не localhostимя, потому что он, похоже, не разрешается должным образом)
  • обязательно экранируйте символ двойной точки ( :) внутри одинарных кавычек
  • Я не уверен, приводит ли это к утечкам DNS; судя по тому, что я проверил, это не так, но я не могу быть в этом уверен, так как не знаю, как это проверить.

Что осталось сделать:

  • автоматизировать все команды для запуска приложения и переадресации порта при запуске: в данный момент мне это не нужно, но если/когда я узнаю, как это сделать, я добавлю это сюда

Связанный контент