Контекст
Я використовував дуже хороший контейнер 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 годин, не маючи успіху досі.