Thank you for reading this post, don't forget to subscribe!
Pritunl – VPN-сервер с пачкой дополнительных возможностей по безопасности и управлению доступами.
По сути – является просто обёрткой над OpenVPN, добавляя к нему такие себе Access Control Lists в виде Организаций, юзеров и роутов.
Задача – развернуть тестовый инстанс Pritunl в Kubernetes, что бы потрогать его изнутри.
для установки используем Helm-чарт от Dysnix.
Создаём неймспейс:
kubectl create ns pritunl-local
Добавляем репозиторий:
helm repo add dysnix https://dysnix.github.io/charts
И устанавливаем чарт с Pritunl:
helm -n pritunl-local install pritunl dysnix/pritunl
1 2 3 4 5 6 |
Pritunl default access credentials: export POD_ID=$(kubectl get pod --namespace pritunl-local -l app=pritunl,release=pritunl -o jsonpath='{.items[0].metadata.name}') kubectl exec -t -i --namespace pritunl-local $POD_ID pritunl default-password ... export VPN_IP=$(kubectl get svc --namespace pritunl-local pritunl --template "{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}") echo "VPN access IP address: ${VPN_IP}" |
Проверяем поды:
1 2 3 4 |
kubectl -n pritunl-local get pod NAME READY STATUS RESTARTS AGE pritunl-54dd47dc4d-672xw 1/1 Running 0 31s pritunl-mongodb-557b7cd849-d8zmj 1/1 Running 0 31s |
Получаем логин-пароль из мастер-пода:
kubectl exec -t -i --namespace pritunl-local pritunl-54dd47dc4d-672xw pritunl default-password
1 2 3 4 |
... Administrator default password: username: "pritunl" password: "zZymAt1tH2If" |
Находим Сервисы:
kubectl -n pritunl-local get svc
1 2 3 4 |
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE pritunl LoadBalancer 10.104.33.93 <pending> 1194:32350/TCP 116s pritunl-mongodb ClusterIP 10.97.144.132 <none> 27017/TCP 116s pritunl-web ClusterIP 10.98.31.71 <none> 443/TCP 116s |
Тут LoadBalancer pritunl – для доступа клиентов к серверу ВПН, а сервис pritunl-web ClusterIP – для доступа к веб-интерфейсу.
Пробрасываем порт к Веб:
1 2 |
Forwarding from 127.0.0.1:8443 -> 443 Forwarding from [::1]:8443 -> 443 |
Открываем https://localhost:8443:
Логинимся, и попадаем в начальные настройки:
Тут в Public Address будет автоматом задан публичный адрес хоста, на котором запущен сам Притунл, и потом будет подставляться в клиентские конфиги как адрес хоста VPN.
Так как Pritunl у нас работает в Kubernetes, который работает в VirtualBox, который работает на Linux на обычном домашнем PC – то нам он не подходит, но к нему вернёмся позже. Пока можно оставить, как есть.
Остальные настройки нам пока не интересны.
Настройка Pritunl VPN
Organization, Users
Для объединения юзеров есть Группы – но они в полной версии, её увидим потом.
Также, юзеров можно сгруппировать через Organizations.
Переходим в Users, добавляем Organization:
PIN, email – опциональны, сейчас не нужны.
Pritunl Server и роуты
Переходим в Servers, добавляем новый:
Тут:
- DNS Server: к какому ДНС будем отправлять клиентов
- Port, Protocol: порт и протокол для OpenVPN, который будет запущен “внутри” Притунла и будет принимать подключения от наших юзеров
- Virtual Network: сеть, из пула адресов которой будем выделять приватные IP для клиентов
Virtual Network я бы выделил 172.16.0.0 – тогда у нас домашняя сеть, сеть Кубера и клиентские IP будут различаться – удобнее будет дебажить, см. IPv4 Private Address Space and Filtering.
При этом важно, что бы порт Сервера тут совпадал с портом и протоколом на LoadBalancer – 1194 TCP.
Т.е. запрос с рабочей машины пойдет по маршруту:
- 192.168.3.0/24 – домашняя сеть
- попадёт в сеть VirtualBox 192.168.59.1/24
- пойдёт на LoadBalancer в сети Кубера 10.96.0.0/12
- а LoadBalancer отроутит запрос в Kubernetes Pod, в котором у нас OpenVPN слушает TCP порт 1194
Проверяем сам LoadBalancer:
1 2 |
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE pritunl LoadBalancer 10.104.33.93 <pending> 1194:32350/TCP 22m |
Port 1194 – TCP. Со статусом Pending разберёмся чуть позже.
Указываем Virtual Network, порт и протокол для Server:
Далее, подключаем Организацию со всеми её пользователями:
Стартуем сервер:
Проверяем процесс и порт в Kubernetes Pod – видим наш OpenVNP Сервер на порту 1194:
1 2 |
Defaulted container "pritunl" out of: pritunl, alpine (init) tcp6 0 0 :::1194 :::* LISTEN 1691/openvpn |
И идём фиксить LoabBalancer.
minikube tunnel
1 2 3 4 5 6 7 8 9 10 11 |
[sudo] password for setevoy: Status: machine: minikube pid: 1467286 route: 10.96.0.0/12 -> 192.168.59.108 minikube: Running services: [pritunl] errors: minikube: no errors router: no errors loadbalancer emulator: no errors |
Проверяем Loadbalancer:
1 2 |
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE pritunl LoadBalancer 10.104.33.93 10.104.33.93 1194:32350/TCP 139m |
Появился
EXTERNAL-IP
– проверяем подключение:
1 2 3 4 |
telnet 10.104.33.93 1194 Trying 10.104.33.93... Connected to 10.104.33.93. Escape character is '^]'. |
Возвращаемся к основным Settings, указываем Public Address == LoadBalancer IP :
OpenVPN – подключение к серверу
Переходим в Users, кликаем Download profile:

И подключаемся с помощью обычного OpenVPN клиента:
1 2 3 4 5 6 7 8 |
[sudo] password for setevoy: ... 2022-10-04 15:58:32 Attempting to establish TCP connection with [AF_INET]10.104.33.93:1194 [nonblock] 2022-10-04 15:58:32 TCP connection established with [AF_INET]10.104.33.93:1194 ... 2022-10-04 15:58:33 net_addr_v4_add: 172.16.0.2/24 dev tun0 2022-10-04 15:58:33 WARNING: this configuration may cache passwords in memory -- use the auth-nocache option to prevent this 2022-10-04 15:58:33 Initialization Sequence Completed |
Но сейчас сеть работать не будет:
1 2 3 4 5 |
traceroute 1.1.1.1 traceroute to 1.1.1.1 (1.1.1.1), 30 hops max, 60 byte packets 1 * * * 2 * * * 3 * * * |
Так как у нас в ВПН роут в 0.0.0.0/0 направлен через тот же хост, на котором собственно ВПН и работает – получается “кольцо”.
Переходим в Servers, останавливаем сервер и удаляем Default route:
Кликаем Add Route – добавим маршрут к 1.1.1.1 через наш ВПН, а все остальные запросы с клиента будут идти обычными маршрутами:
Запускаем подключение заново:
Проверяем роуты на хост-машине, локально:
1 2 3 4 5 6 |
route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 192.168.3.1 0.0.0.0 UG 100 0 0 enp38s0 1.1.1.1 172.16.0.1 255.255.255.255 UGH 0 0 0 tun0 ... |
И проверяем сеть – запрос пошёл через VPN:
1 2 3 4 5 |
traceroute 1.1.1.1 traceroute to 1.1.1.1 (1.1.1.1), 30 hops max, 60 byte packets 1 172.16.0.1 (172.16.0.1) 0.211 ms 41.141 ms 41.146 ms 2 * * * ... |