Pritunl – VPN-сервер с пачкой дополнительных возможностей по безопасности и управлению доступами.
По сути – является просто обёрткой над OpenVPN, добавляя к нему такие себе Access Control Lists в виде Организаций, юзеров и роутов.
Задача – развернуть тестовый инстанс Pritunl в Kubernetes, что бы потрогать его изнутри.
Пока использовать будем бесплатную версию, попозже глянем платную. Различия и стоимость можно посмотреть вот тут>>>.
Запускать будем в Minikube, а для установки используем Helm-чарт от Dysnix.
Содержание
Запуск Pritunl в Kubernetes
Создаём неймспейс:
[simterm]
$ kubectl create ns pritunl-local namespace/pritunl-local created
[/simterm]
Добавляем репозиторий:
[simterm]
$ helm repo add dysnix https://dysnix.github.io/charts
[/simterm]
И устанавливаем чарт с Pritunl:
[simterm]
$ helm -n pritunl-local install pritunl dysnix/pritunl ... 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}"
[/simterm]
Проверяем поды:
[simterm]
$ 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
[/simterm]
Получаем логин-пароль из мастер-пода:
[simterm]
$ kubectl exec -t -i --namespace pritunl-local pritunl-54dd47dc4d-672xw pritunl default-password ... Administrator default password: username: "pritunl" password: "zZymAt1tH2If"
[/simterm]
Находим Сервисы:
[simterm]
$ kubectl -n pritunl-local get svc 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
[/simterm]
Тут LoadBalancer pritunl – для доступа клиентов к серверу ВПН, а сервис pritunl-web ClusterIP – для доступа к веб-интерфейсу.
Пробрасываем порт к Веб:
[simterm]
$ kubectl -n pritunl-local port-forward svc/pritunl-web 8443:443 Forwarding from 127.0.0.1:8443 -> 443 Forwarding from [::1]:8443 -> 443
[/simterm]
Открываем https://localhost:8443:
Логинимся, и попадаем в начальные настройки:
Тут в Public Address будет автоматом задан публичный адрес хоста, на котором запущен сам Притунл, и потом будет подставляться в клиентские конфиги как адрес хоста VPN.
Так как Pritunl у нас работает в Kubernetes, который работает в VirtualBox, который работает на Linux на обычном домашнем PC – то нам он не подходит, но к нему вернёмся позже. Пока можно оставить, как есть.
Остальные настройки нам пока не интересны.
Настройка Pritunl VPN
Organization, Users
См. Initial Setup.
Для объединения юзеров есть Группы – но они в полной версии, её увидим потом.
Также, юзеров можно сгруппировать через Organizations.
Переходим в Users, добавляем Organization:
Добавляем юзера:
PIN, email – опциональны, сейчас не нужны.
Pritunl Server и роуты
См. Server configuration.
Переходим в 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 (см. Proxy)
- пойдёт на LoadBalancer в сети Кубера 10.96.0.0/12
- а LoadBalancer отроутит запрос в Kubernetes Pod, в котором у нас OpenVPN слушает TCP порт 1194
Проверяем сам LoadBalancer:
[simterm]
$ kubectl -n pritunl-local get svc pritunl NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE pritunl LoadBalancer 10.104.33.93 <pending> 1194:32350/TCP 22m
[/simterm]
Port 1194 – TCP. Со статусом Pending разберёмся чуть позже.
Указываем Virtual Network, порт и протокол для Server:
Далее, подключаем Организацию со всеми её пользователями:
Стартуем сервер:
Проверяем процесс и порт в Kubernetes Pod – видим наш OpenVNP Сервер на порту 1194:
[simterm]
$ kubectl -n pritunl-local exec -ti pritunl-54dd47dc4d-672xw -- netstat -anp | grep 1194 Defaulted container "pritunl" out of: pritunl, alpine (init) tcp6 0 0 :::1194 :::* LISTEN 1691/openvpn
[/simterm]
И идём фиксить LoabBalancer.
minikube tunnel
См. Kubernetes: Minikube, та LoadBalancer в статусі “Pending” для полной информации, сейчас просто вызываем minikube tunnel
:
[simterm]
$ minikube tunnel [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 ...
[/simterm]
Проверяем Loadbalancer:
[simterm]
$ kubectl -n pritunl-local get svc pritunl NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE pritunl LoadBalancer 10.104.33.93 10.104.33.93 1194:32350/TCP 139m
[/simterm]
Появился EXTERNAL-IP
– проверяем подключение:
[simterm]
$ telnet 10.104.33.93 1194 Trying 10.104.33.93... Connected to 10.104.33.93. Escape character is '^]'.
[/simterm]
Возвращаемся к основным Settings, указываем Public Address == LoadBalancer IP :
OpenVPN – подключение к серверу
Переходим в Users, кликаем Download profile:
Распаковываем архив:
[simterm]
$ tar xfp local-user.tar
[/simterm]
И подключаемся с помощью обычного OpenVPN клиента:
[simterm]
$ sudo openvpn --config local-org_local-user_local-server.ovpn [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
[/simterm]
Но сейчас сеть работать не будет:
[simterm]
$ traceroute 1.1.1.1 traceroute to 1.1.1.1 (1.1.1.1), 30 hops max, 60 byte packets 1 * * * 2 * * * 3 * * * ...
[/simterm]
Так как у нас в ВПН роут в 0.0.0.0/0 направлен через тот же хост, на котором собственно ВПН и работает – получается “кольцо”.
Переходим в Servers, останавливаем сервер и удаляем Default route:
Кликаем Add Route – добавим маршрут к 1.1.1.1 через наш ВПН, а все остальные запросы с клиента будут идти обычными маршрутами:
Запускаем подключение заново:
[simterm]
$ sudo openvpn --config local-org_local-user_local-server.ovpn
[/simterm]
Проверяем роуты на хост-машине, локально:
[simterm]
$ 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 ...
[/simterm]
И проверяем сеть – запрос пошёл через VPN:
[simterm]
$ 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 * * * ...
[/simterm]
“It works!” (с)
Готово.