Как использовать 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) с реального localhost (enp3s0 адаптер Ethernet)
  • перенаправить этот порт таким образом, чтобы я мог получить к нему доступ с других моих компьютеров в моей локальной сети

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 Мне пришлось использовать фактический localhost-IP (не localhost или имя, потому что оно, кажется, не решается должным образом)
  • убедитесь, что вы экранировали двойной знак (:) внутри одинарных кавычек
  • Я не уверен, вызывает ли это утечку DNS; из того, что я проверил, это не так, но я не могу быть уверен, так как не знаю, как это проверить

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

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

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

Во-первых, вот namespace-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

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

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

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

Создайте вет-пару. Одна сторона останется в корневом/обычном пространстве имен (я называю это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 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(), используйте интерфейс ihost и перезапишите исходный адрес на сторону корневого пространства имен().
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.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

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

Теперь например: чтобы получить доступ к торрент вебуи в пространстве имён по порту 8080, я делаю так.
Любой пакет, идущий на мой IP-адрес в локальной сети (пример: я печатаю в браузере). Он перезапишет место назначения в пространство имен, в котором работает мой торрент-клиент (Пример: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. VPN с пространством имен выдает исключение, когда обнаруживает интерфейсы внутри вашего целевого пространства имен, отличные отloпетлевой интерфейс.
Вот та часть, которая выдает мне исключения, когда я использую 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, которое по какой-либо причине (ошибка, перезапуск ping и т. д.) повторно подключается к провайдеру VPN и получает новый IP-адрес. Интерфейс VPN, возможно, придется отключить на долю секунды, чтобы сбросить конфигурацию, и это приведет к сбою клиента (qBittorrent наверняка делает это). «Исправление», над которым я начал работать, — это написать сценарий, который определяет, когда интерфейс VPN получает новый IP-адрес или по какой-либо причине отключается от сети. Скрипт должен корректно (важно: корректно, чтобы избежать повреждения чего-либо/ошибки файловой системы) выйти из торрент-клиента, а затем перезапустить его. У меня пока нет рабочего скрипта, но это кажется достойным вектором решения данной проблемы.
Другие вопросы по тегам