Некоторое время я искал вебморду для openvpn-сервера. Чуть было не написал «не простую, а золотую», но на самом деле ничего особенного — из хоть каких-то требований у меня было только 2:
— полноценное управление пользователями (хотя бы отзыв сертификата) — вот тут-то почти все морды и отсеивались
— деплой самого openvpn-сервера (минорно) и CA-шки, чтобы VPN можно было поднять побыстрее.
И я нашел почти идеальный вариант — называется pritunl. В общем-то дальше статью особого смысла читать нет =)
Пара картинок для понимания, как оно выглядит:
— раз
— два
Ладно, расскажу всё же, что умеет бесплатная версия (и потом — как её побыстрее поставить).
— умеет openvpn/wireguard-сервер (сама их запускает, по умолчанию — openvpn, про него и будет идти речь)
— умеет дополнительно спрашивать логин+пароль у клиента при подключении (пароль у них называется PIN).
— умеет 2 factor auth через google authenticator — не пробовал, но заявлено. Имейте в виду, что 2FA включается для всех аккаунтов сразу, и если у вас среди клиентов есть те, кто не поддерживает 2FA (банальный пример — сервер, который подключается к этой VPN), то они не смогут подключаться
— у всех клиентов — статические IP-адреса (удобно). client2client включен по умолчанию, имейте в виду — с одной стороны можно подцепить сервер в VPN и ходить на него напрямую по всем портам с других клиентов, с другой — на клиентах что-то может лишнее торчать в сеть
— маршруты можно выдавать кастомные, с default или без него.
— ну и самое главное — есть рубильник, отключающий пользователя (без удаления). Само собой, есть и удаление.
В принципе, у pritunl есть и платная версия (и нет, денег мне за статью они не платили — а жаль хД), она умеет какие-то интересные вещи. Но версия за $10/month не умеет ничего такого, чего нельзя настроить руками. Самая полезная фича там, пожалуй, возможность мышкой в вебе настроить роутинг в сеть через подключенного клиента (например, ваш шлюз в офисе подключается к VPN серверу, остальные клиенты VPN маршрутизируются через этот шлюз в локалку офиса). Удобно (серьёзно), но, повторюсь, такое и вручную делается без проблем. Ещё из полезных фич за $10 — отключение 2FA для отдельных клиентов.
Версия же за $50/month представляет из себя какой-то адовый комбайн, на котором можно наворотить любой сложности виртуальную сеть с failover-маршрутами, кластером VPN-серверов, пирингом с облачными сетями и хер его знает чем ещё — я там не все слова понял в описании, честно говоря.
Если строите корпоративную VPN-сеть и заколебались воротить openvpn-конфигами и ip ro add — можете попробовать, если денег выделят.
Дальше речь пойдет о бесплатной версии — всё же я больше рассматриваю здесь случай, когда нужно за 5 минут поднять VPN-сервер для пары-тройки человек. Да и даже если для одного — всё равно будет быстрее, чем самому ковырять easy-rsa. Ну и писать я буду про вариант с openvpn — wireguard на сервере в общем-то настраивается абсолютно также, нужно только галочку в вебе поставить и порт второй пробросить.
Так же стоит понимать, что особой паранойи в статье описано не будет. В конце я в общих чертах напишу, что я делаю для хоть какой-то безопасности, но без подробностей.
Итак, вам понадобится:
— KVM-виртуалка или железный сервер, минимум 1 штука
— любой дистрибутив, где есть docker и compose (да-да, скатился)
— какой-нибудь домен для вебморды, чтобы получить на него сертификат
В идеальном случае нам нужна чистая система, но совсем не обязательно, просто читайте комментарии в compose-файле (копипастом сработает только если у вас порты 80/443 не заняты).
Ставим docker и compose:
Создадим пару необходимых каталогов:
Создаём compose.yml, например /etc/vpn/docker-compose.yml с примерно таким содержимым (не забудьте, что у yml важны пробелы/табуляция):
services:
mongo:
image: mongo:4.4
container_name: pritunldb
hostname: pritunldb
networks:
vpcbr:
ipv4_address: 172.17.0.2
volumes:
- /var/lib/vpn/db:/data/db
pritunl:
# следующие 2 строки нужны только в том случае, если вы собираетесь использовать отдельный nginx поверх вебморды
environment:
- REVERSE_PROXY: true
image: goofball222/pritunl:latest
container_name: pritunl
hostname: pritunl
depends_on:
- mongo
networks:
vpcbr:
ipv4_address: 172.17.0.3
privileged: true
sysctls:
- net.ipv6.conf.all.disable_ipv6=0
links:
- mongo
volumes:
- /etc/localtime:/etc/localtime:ro
ports:
# будущий порт vpn-сервера
- 1194:1194
- 1194:1194/udp
# 80-й порт пробрасываем только если собираетесь использовать letsencrypt внутри панели
# ну то есть, скорее всего, если у вас нет отдельного nginx-а на хосте и letsencrypt рядом
- 80:80
# 443 порт - порт самой вебморды.
# если на хосте нет nginx и нужно побыстрее - пробрасывайте прямо здесь.
- 443:443
environment:
- TZ=UTC
networks:
vpcbr:
driver: bridge
ipam:
config:
- subnet: 172.17.0.0/24
#gateway: 172.17.0.1
Делаем пробный запуск:
Если что-то ругается про iptables — рестартните docker.
Если начало активно гадить в консоль — всё хорошо, можно продолжать. Через полминуты-минуту запустится вебморда на https://server. Только повесьте туда домен какой-нибудь, чтобы сертификат валидный получить.
Если всё пошло хорошо, то на вебморде вы увидите надпись «Use «sudo pritunl default-password» to get default login information». Давайте сделаем:
...
Administrator default password:
username: "pritunl"
password: "..."
Используем эти данные для входа в вебморду.
После первого входа по default-паролю откроется форма «Initial Setup». В целом там всё понятно, спросят username и пароль (для входа в вебморду), внешний ipv4, внешний ipv6 (будут фигурировать в конфигах vpn для клиентов), web-console порт (не забудьте поменять его и в docker-compose.yml, если поменяете здесь) и домен, на который панель попытается получить сертификат в letsencrypt (сработает только если публично доступен 80-й порт из контейнера).
Заполняем, жмём save, идём покурить.
Ну и осталось понажимать кнопки в вебморде. Я постараюсь описать всё без скриншотов (лень же верстать статью потом, ну), там в начале была парочка для понимания.
Итак, в вебморде закрываем глаза и жмём по очереди:
— Users -> Add Organization, добавляем
— Servers -> Add server. Здесь порт обязательно должен совпадать с портом в compose.yml (у нас был 1194). Остальное сами решайте
— На той же странице жмём Attach Organisation — выбирать там будет особо не из чего, просто добавляем связь
— по вкусу удаляем маршрут для 0.0.0.0/0 внизу, добавляем другие маршруты
— жмем «Start server»
— Возвращаемся в Users и жмем либо «Bulk Add Users», либо «Add user»
— жмём кнопку «Download profile» у нужных пользователей, скачается tar-ник с .ovpn-файлом внутри, раздаём ovpn-ы пользователям
Дальше всем всё должно быть понятно, думаю.
Теперь в консоли, где запускали docker-compose жмите ctrl-c.
Создаём systemd-unit (дада, compose через systemd, я больной ублюдок и всё такое, но а что делать?), например /etc/systemd/system/vpn.service
Description=Some usefull text
After=docker.service
BindsTo=docker.service
[Service]
Type=simple
ExecStart=/usr/bin/docker-compose -f /etc/vpn/docker-compose.yml up
ExecStop=/usr/bin/docker-compose -f /etc/vpn/docker-compose.yml down
Restart=on-failure
RestartSec=10s
User=root
Group=root
[Install]
WantedBy=multi-user.target
Стопаем корректно compose до конца:
Пинаем systemctl, включаем автозапуск, запускаем сервис:
(кстати, на тестовой машинке что-то было поломано и здесь опять понадобилось делать docker restart — у вас тоже такое может случиться).
Всё, можно ребутаться, проверять, пользоваться и тыды.
Теперь о безопасности.
В первую очередь, конечно же, стоит каталог /var/lib/vpn/db убрать в зашифрованный раздел или LUKS image file (так и гуглится). Сам каталог будет занимать около пятисот мегабайт, хотя может со временем и вырастет — логи и вот это вот всё. Но стопнуть service vpn и перекинуть все данные в image побольше не проблема в общем-то.
Возможно, и в /var/lib/docker останется что-то, что не мешало бы зашифровать, но тут уже сами смотрите — в базе-то точно есть сертификаты, логины, хеши паролей и так далее.
Второй момент — я бы всё же рекомендовал использовать отдельно стоящий nginx c proxy_pass в https://172.17.0.3 (если адреса не меняли). Таким образом вы сможете настроить дополнительную авторизацию — по basic_auth или адресам, или ещё как.
Можно поступить ещё проще — вообще не пробрасывать наружу 443-порт, если лень ставить nginx. Ходить в саму вебморду можно при помощи sshuttle (во время изначальной настройки), а потом она и так будет доступна внутри VPN по серому адресу https://172.17.0.3 (маршрут только добавьте сюда клиентам, если дефолтный удалили). Ну или ещё проще вариант — сначала пробросить 443-порт, настроить VPN, подключиться к VPN, убрать проброс порта наружу (и сертификат не будет смысла получать, его на серый IP lets не выдаст, если только сами на DNS что-то нагородите с вьюхами — но зачем тогда вам вообще читать мои смешные рассуждения о том, как обезопасить вебморду?).
Как-то так.
Да достойный продукт. Не без ляпов, конечно. Много что разработчика годами не исправляют.
Но тоже на нем остановился.
Непонравилось, что с Mikrotik его никак не подружить.
Остальное решаемо, много чего в монге можно по настройкам подправить, да и сам движок на pyton часть настроек там запрятана.
> Непонравилось, что с Mikrotik его никак не подружить.
У микрота openvpn не настоящий, к сожалению )
Но вообще — почему не получилось-то? Pritunl вроде TCP openvpn умеет
А я консольку больше люблю: https://github.com/angristan/openvpn-install и не надо с easy-rsa возиться, ccd конфиги для каждого клиента, управление доступом череp firewall ufw в файле /etc/ufw/before.rules
Уже слишком часто списком пользователей стали рулить не-технари вообще.
У меня одна инсталляция крутится, там вообще ген. директор пользователями рулит. В таких случаях лучше всё же вебморду натянуть)