How To Guide: Set Up & Configure OpenVPN client/server VPN | OpenVPN

Как настроить OpenVPN — скрытые возможности!

В документации к OpenVPN отыщется и много других интересных возможностей. К примеру, если указать несколько опций remote в конфиге клиента, клиент автоматически переключится на следующий адрес сервера, если не сможет подключиться к первому.

Именно гибкость настройки и разнообразие опций позволяют OpenVPN успешно конкурировать с другими похожими проектами.

How To Guide: Set Up & Configure OpenVPN client/server VPN | OpenVPN

OpenVPN был и остается одним из самых популярных средств для построения виртуальных частных сетей. Он не лишен недостатков: для него нет встроенного клиента в Windows, macOS и мобильных устройствах, а пропускная способность туннелей не слишком высока. Зато способность работать поверх TCP позволяет ему проходить даже через самые безумные сети с многократным NAT и прочим издевательством.

В интернете полно статей о настройке сервера OpenVPN для подключения пользовательских компьютеров к удаленной сети, и создается впечатление, что это его единственное применение. Кто-то даже считает, что с появлением WireGuard он вовсе утратил свою актуальность. Действительно, встроенный роуминг и другие возможности WireGuard создают старым проектам серьезную конкуренцию.

Однако в OpenVPN есть много менее известных возможностей, и он все еще остается одним из самых гибких, многофункциональных и простых в настройке решений.

 

Я предполагаю, что у тебя уже есть опыт настройки OpenVPN, поэтому пропустим основы и сразу перейдем к малоизвестным полезным фичам.

 

Site to site

OpenVPN обычно ассоциируется с настройками типа клиент — сервер. Большинство статей посвящены именно этому варианту, и многие сетевые дистрибутивы вроде OpenWRT и OPNSense предоставляют пользовательский интерфейс только для него. Но это большое упущение! OpenVPN — очень простой способ соединить два хоста или сети безопасным туннелем типа точка — точка.

Еще менее известный факт: в этом режиме OpenVPN может работать со статическими ключами (pre-shared key), без сертификатов. Более того, чтобы сгенерировать такой ключ, тебе не понадобится никаких инструментов, кроме самого OpenVPN.

Предположим, что мы хотим постоянное подключение к удаленной машине с адресом 203.0.113.100. Сгенерируем ключ:

$ openvpn --genkey --secret /etc/openvpn/shared.key

Настроим локальную сторону:

dev-type tun
dev tun0 
ifconfig 192.168.0.2 192.168.0.1
rport 1194
remote 203.0.113.100
secret /etc/openvpn/shared.key

Теперь скопируем файл ключа на удаленную машину и напишем там противоположный конфиг:

dev-type tun
dev tun0 
ifconfig 192.168.0.1 192.168.0.2 
lport 1194
local 203.0.113.100
secret /etc/openvpn/shared.key

По желанию можно добавить туда опции для работы в режиме демона:

daemon openvpn-tun0
writepid /var/run/openvpn-tun0.pid 

Осталось сохранить конфиг в файл вроде /etc/openvpn/s2s.conf и запустить openvpn --config /etc/openvpn/s2s.conf.

Идентификация соединений происходит только по ключу, адреса хостов никак не учитываются. Указать опцию remote нужно только на одной стороне — «клиенте». Сторона без опции remote будет ждать подключения. Из-за этого OpenVPN удобен для соединений site to site с хостами, у которых нет статического адреса, и даже хостами за NAT.

Опция local не обязательна, но полезна для маршрутизаторов с несколькими внешними интерфейсами. Если ее не указывать, OpenVPN будет слушать на 0.0.0.0.

OpenVPN работает поверх UDP, если не указано обратное. Если хочешь использовать TCP, на стороне «клиента» нужно добавить в конфиг proto tcp-client, а на стороне «сервера» — proto tcp-server.

Насколько плохо использование статических ключей? С одной стороны, утечка такого ключа куда более опасна, поскольку злоумышленник сможет расшифровать весь перехваченный трафик, и в прошлом, и в будущем. TLS решает эту проблему использованием сессионных ключей. Но с другой стороны, такой трафик сложнее идентифицировать как зашифрованный туннель.

Режим site to site можно использовать с TLS и сертификатами, но настройка этого сложнее и требует больше времени. Если тебе нужно поднять соединение между двумя машинами с минимальными затратами усилий, OpenVPN site to site со статическим ключом — оптимальный вариант.

 

Раздаем разные настройки разным клиентам

Динамическая маршрутизация — это здорово, но совершенно непрактично для клиентских соединений. Даже для туннелей к маршрутизаторам это может быть непрактично, если они работают на какой-нибудь OpenWRT, где нет удобного механизма для ее настройки. Вручную настроить FRRouting или BIRD можно на любой UNIX-подобной ОС, но нужно ли?

С OpenVPN решить эту проблему просто. Все слышали про опции push в конфиге самого сервера, вроде push "route 172.16.20.0 255.255.255.0". Меньше людей знают, что эти настройки могут быть не только глобальными. Более того, почти любые опции можно указать на уровне клиентов.

Чтобы иметь возможность задавать настройки отдельным клиентам, нужно указать каталог для файлов с этими настройками:

client-config-dir /etc/openvpn/client-configs/

Для идентификации клиентов используется поле CN (Common Name) из их сертификатов. Предположим, у тебя есть клиент с CN=jrandomuser и ему нужен доступ к сети 172.16.19.0/24.

Достаточно создать файл /etc/openvpn/client-configs/jrandomuser и прописать туда опцию

push "route 172.16.19.0 255.255.255.0"

Таким же образом можно избирательно отключить split tunneling для некоторых клиентов, если прописать им push "route 0.0.0.0 0.0.0.0".

Кроме маршрутов, можно раздавать множество других опций. Например, задать клиентам свой сервер DNS: push "dhcp-option DNS 172.16.0.10". Можно указать и сервер WINS, если клиенту нужен доступ к SMB: push "dhcp-option WINS 172.16.0.10".

Возможность указывать все это как глобально, так и для отдельных клиентов позволяет весьма гибко управлять доступом пользователей к внутренней сети без особых усилий.

OpenVPN читает файлы клиентских настроек при каждом их подключении. Перезапускать его, чтобы добавить новых клиентов или поменять настройки, не нужно.
 

Подключаем удаленные сети

Режим site to site хорош для небольшого числа соединений. Если у тебя десятки или сотни удаленных сетей, настраивать туннель к каждой крайне утомительно. Можно автоматизировать этот процесс с помощью Ansible или чего-то еще, но в OpenVPN есть встроенный механизм для этой задачи.

Предположим, что сеть твоей организации — 10.0.0.0/16, а для удаленных клиентов у тебя выделена 10.0.0.0/21. Пусть твой сервер OpenVPN использует сетевой интерфейс tun0.

Прежде всего нужно создать маршрут ко всей сети через этот интерфейс. В Linux команда будет такой:

$ sudo ip route add 10.0.0.0/21 dev tun0

Тонкий момент: ядро Linux удаляет маршруты, когда интерфейс исчезает или уходит в down. По этой причине нужно сделать, чтобы этот маршрут создавался при перезапуске OpenVPN. Самое чистое решение — использовать демон маршрутизации вроде Quagga/FRRouting или BIRD, который сам следит за состояниями сетевых интерфейсов и пересоздает маршруты по необходимости. Самое простое — добавить команду в скрипт запуска.

Одну подсеть мы выделим для клиентских интерфейсов и укажем ее в опции server. Кроме того, нужно указать в конфиге topology subnet. Чтобы указывать, какая сеть какому клиенту принадлежит, нам снова понадобится client-config-dir.

Разумеется, клиентам потребуется доступ к корпоративной сети, поэтому мы выдадим им маршрут к 10.0.0.0/16 с помощью push.

Добавим следующее в конфиг сервера:

server 10.0.0.0 255.255.255.0
topology subnet
persist-tun

client-config-dir /etc/openvpn/client-configs/

push "route 10.0.0.0 255.255.0.0"

Теперь создадим конфиг клиента. Предположим, ты хочешь подключить офис с сетью 10.0.1.0/24 и ты создал для его маршрутизатора сертификат с CN=my-remote-office.

Пропиши следующее в /etc/openvpn/client-configs/my-remote-office:

iroute 10.0.1.0 255.255.255.0

Теперь, когда этот клиент подключится, OpenVPN ассоциирует сеть 10.0.1.0/24 с его подключением.

 

Храним все настройки клиента в одном файле

Очень часто можно получить от удаленной стороны конфиг OpenVPN для подключения к серверу и отдельные файлы с CA, клиентским сертификатом и ключом. Это приемлемо для админов, но крайне неудобно для конечных пользователей.

К счастью, ключи и сертификаты можно хранить вместе с настройками. Например:

client
dev tun
proto udp
remote 203.0.113.20 1194
<ca>
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
</ca>
<cert>
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
</key>

Пользователю достаточно сохранить этот файл (к примеру, в my-vpn.ovpn) и запустить openvpn --config my-vpn.ovpn или указать этот файл в графическом интерфейсе клиента.

 

Общаемся с процессом OpenVPN через сокет

OpenVPN предоставляет интерфейс, через который ты можешь просмотреть информацию о подключениях и выполнить ряд административных задач. Взаимодействовать с ним можно через сокет: либо TCP/IP, либо UNIX.

Есть вариант подключаться к сокету IP через Telnet. Это удобно, но нужно следить за безопасностью доступа к этому сокету. Обеспечить безопасность UNIX domain socket куда проще, поэтому мы выберем именно этот способ.

Нужно добавить в конфиг сервера следующее:

management /tmp/openvpn-mgmt unix

Подключиться к этому сокету можно с помощью утилиты socat:

$ sudo socat - UNIX-CONNECT:/tmp/openvpn-mgmt
>INFO:OpenVPN Management Interface Version 1 -- type 'help' for more info

В выводе help ты найдешь целый ряд полезных команд. К примеру, kill jrandomuser принудительно разорвет все подключения клиента с CN=jrandomuser. В выводе команды status можно увидеть информацию о всех текущих подключениях.

Если тебя интересует именно информация о клиентских туннелях и ты хочешь получать ее без необходимости каждый раз подключаться к сокету, можешь добавить вот эту опцию в конфиг:

status /tmp/openvpn.status

Данные в файл /tmp/openvpn.status будут писаться в таком же формате, как вывод команды status, вроде:

OpenVPN CLIENT LIST
Updated,Tue Apr 21 12:45:47 2020
Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since
jrandomuser,192.0.2.57:56422,51036248,505028963,Tue Apr 21 08:04:02 2020
 

 

Click to rate this post!
[Total: 0 Average: 0]

Специалист в области кибер-безопасности. Работал в ведущих компаниях занимающихся защитой и аналитикой компьютерных угроз. Цель данного блога - простым языком рассказать о сложных моментах защиты IT инфраструктур и сетей.

Leave a reply:

Your email address will not be published.