Назад | Перейти на главную страницу

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

У меня следующая установка:

Как я могу позволить контейнерам докеров в сети моста докеров взаимодействовать с клиентами openvpn в сети tun0?

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

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

Контекст

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

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

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

VPN-сервер должен иметь client-to-client, topology subnet, dev tun0 (или другое устройство tun) и 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> где 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