контекст
Я использовал очень хороший контейнер 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
tap
, гайкаtun
, я работал над этим более 12 часов безуспешно до сих пор.