Разрешить контейнерам Docker подключаться к клиентам OpenVPN через интерфейс туннеля хоста

12

У меня есть следующие настройки:

  • Хост CentOS, на котором запущена служба Docker
  • Пользовательская сеть Docker Bridge
  • 2 Docker-контейнера, подключенных к этой определенной пользователем мостовой сети
  • Установка OpenVPN (в настоящее время выполняется на хосте. Может также выполняться в контейнере Docker)
  • Некоторые клиенты подключены к OpenVPN

Как можно разрешить Docker-контейнерам в сети Docker Bridge взаимодействовать с клиентами openvpn в сети Tun0?

Я хотел бы иметь возможность иметь основанную на tcp связь между docker1 (10.10.0.3) и клиентами, подключенными к vpn (диапазон 172.19.0.x) прозрачным способом.

Что мне нужно настроить на стороне докера (network / iptables / ...) и на хосте (iptables?)

ddewaele
источник
1
Может быть, поздно, но в вашем случае я считаю, что вам нужно tap, гайка tun, я работал над этим более 12 часов безуспешно до сих пор.
Мухаммед Нурельдин
@MohammedNoureldin, ребята, вы нашли решение? Я также собираюсь сейчас нажать на устройство. Что расстраивает, так это то, что из контейнера ovpn я могу получить доступ к клиентам vpn. И из клиентов VPN я могу получить доступ к другим контейнерам в той же сети Docker. Но пересылка между «eth0» и tun0 внутри контейнера ovpn не работает. Я полагаю, это связано с природой tun0 и касанием.
Гюйгенс
@Huygens, да, я решил это, пожалуйста, задайте отдельный вопрос и дайте мне ссылку, и я сделаю все возможное, чтобы помочь вам.
Мохаммед Нурельдин
1
Привет @MohammedNoureldin Я нашел 2 недостающие инструкции для его работы. Они были в man-страницах openvpn 👍. Я скоро выложу ответ на этот вопрос для других.
Гюйгенс
1
@Huygens, приятно знать, на самом деле у меня еще не было времени опубликовать ответ, но мне интересно посмотреть, что сработало для вашего случая.
Мухаммед Нурельдин

Ответы:

7

контекст

Я использовал очень хороший контейнер Docker от Kyle Manna ( https://github.com/kylemanna/docker-openvpn ). Я использую так называемую «параноидальную» документацию для настройки моего сервера OpenVPN, но, на мой взгляд, это должен быть стандартный, а не параноидальный способ.

конфигурация

Чтобы разрешить двунаправленное соединение между выбранными контейнерами Docker и клиентами VPN, необходимо создать сеть Docker, к которой вы собираетесь присоединить контейнер, к которому VPN-клиенты должны иметь доступ. Сервер VPN будет одним из таких контейнеров.

Сервер VPN должен иметь client-to-client, topology subnet, dev tun0(или другое устройство тун) и push "route <docker net IP> <docker net mask>"сконфигурирован.

Хост VPN-сервера должен быть настроен на поддержку пересылки IP-пакетов из одной подсети в другую. Это означает, что для sysctl ip_forward необходимо установить значение 1 (это должно иметь место при установке Docker), разрешить пакетам с устройства tun проходить через цепочку iptables FORWARD и настроить правильную маршрутизацию. Это можно суммировать с помощью следующих команд:

$ sudo sysctl -w net.ipv4.ip_forward=1
$ sudo iptables -A FORWARD -i tun+ -j ACCEPT
$ sudo ip route add 192.168.255.0/24 via <IP address of OpenVPN server container>

В любом случае, вот параметры, которые я использовал для настройки сервера:

$ docker run --rm --net=none -it -v $PWD/files/openvpn:/etc/openvpn kylemanna/openvpn:2.4 ovpn_genconfig -u udp://<FQDN> -N -d -c -p "route <docker net IP> <docker net range>" -e "topology subnet"

Это должно создать файл конфигурации сервера, похожий на:

server 192.168.255.0 255.255.255.0
verb 3
key /etc/openvpn/pki/private/vpn.example.com.key
ca /etc/openvpn/pki/ca.crt
cert /etc/openvpn/pki/issued/vpn.example.com.crt
dh /etc/openvpn/pki/dh.pem
tls-auth /etc/openvpn/pki/ta.key
key-direction 0
keepalive 10 60
persist-key
persist-tun

proto udp
# Rely on Docker to do port mapping, internally always 1194
port 1194
dev tun0
status /tmp/openvpn-status.log

user nobody
group nogroup
client-to-client

### Push Configurations Below
push "dhcp-option DNS 8.8.8.8"
push "route 172.20.20.0 255.255.255.0"

### Extra Configurations Below
topology subnet

Конкретный пример

Сейчас я приведу конкретный пример. В этом примере я буду запускать упомянутый выше сервер OpenVPN внутри Docker на хосте vpn.example.com. Этот контейнер подключен к Docker-сети docker-net-vpn. Вот команды (в этом примере я генерирую конфигурацию сервера непосредственно на сервере и пропускаю генерацию CA, пожалуйста, следуйте документации по параноику вышеупомянутого проекта):

$ docker network create --attachable=true --driver=bridge --subnet=172.20.20.0/24 --gateway=172.20.20.1 docker-net-vpn
$ docker run --rm --net=none -it -v $PWD/files/openvpn:/etc/openvpn kylemanna/openvpn:2.4 ovpn_genconfig -u udp://vpn.example.com -N -d -c -p "route 172.20.20.0 255.255.255.0" -e "topology subnet"
$ docker run --detach --name openvpn -v $PWD/files/openvpn:/etc/openvpn --net=docker-net-vpn --ip=172.20.20.2 -p 1194:1194/udp --cap-add=NET_ADMIN kylemanna/openvpn:2.4
$ sudo sysctl -w net.ipv4.ip_forward=1
$ sudo iptables -A FORWARD -i tun+ -j ACCEPT
$ sudo ip route add 192.168.255.0/24 via 172.20.20.2

Первая команда создает выделенную новую сеть Docker, которая определяет новую подсеть. Мы подключим сервер OpenVPN к этой сети.

Второй создает конфигурацию OpenVPN, используя ту же подсеть, как определено в 1-й команде.

Третий создает сервер OpenVPN. Он подключен к недавно созданной сети Docker и использует фиксированный IP.

Четвертая и пятая команды настраивают переадресацию IP.

Последняя команда добавляет новый маршрут к конфигурации VPN-клиента через фиксированный IP-адрес контейнера OpenVPN.

Запись

Я не пробовал, но должно быть возможно ограничить правило FORWARD для iptables. Создание сети Docker создало новое мостовое устройство. Этот мост назван br-<ID>с идентификатором, являющимся первыми 12 символами идентификатора сети Docker. Этот идентификатор можно получить с помощью docker network inspect -f '{{.Id}}' docker-net-vpn | cut -b-12. Поэтому следующая команда может быть более строгой (поэтому лучше с точки зрения безопасности), но все же должна позволять маршрутизировать наш трафик:

$ NET_VPN_BRIDGE="br-$(docker network inspect -f '{{.Id}}' docker-net-vpn | cut -b-12)"
$ sudo iptables -A FORWARD -i tun+ -o ${NET_VPN_BRIDGE} -j ACCEPT
Гюйгенс
источник
Эй, не могу заставить это работать, я могу отследить до 192.168.255.6, и я получаю:, 1 gnet (172.20.20.1) 1966.269 ms !H 1966.248 ms !H 1966.239 ms !Hно я не могу пропинговать или достигнуть открытых портов.
GuySoft
Привет @GuySoft, что traceroute сообщает, что ваш последний прыжок (172.20.20.1) не может достичь хоста 192.168.255.6. Таким образом, это означает, что ваша таблица маршрутизации, вероятно, неверна. Можем ли мы поболтать, чтобы увидеть, где проблема?
Гюйгенс
Это начало работать, я думаю, что случилось то, что на обеих машинах был установлен докер, и на обеих были подсети 172.20.20.1, которые делали вещи конфликтующими, мне нужно найти способ заставить докер не создавать подсеть, которая конфликтовала бы на клиентском компьютере ,
GuySoft
Если вы используете Docker Compose, вы можете указать диапазон IP-адресов, который должна использовать сеть. Смотрите документацию Compose. Это также возможно сделать из командной строки docker network….
Гюйгенс
Я думаю, что я не получаю часть, где соединение с хостом (хост ip + порт openvpn) маршрутизируется в контейнер openvpn (172.20.20.2)
jtomasrl