########## File: openvpn_lan_guide.rtfm ##########
Всем привет, с вами fffu, и сегодня мы сделаем виртуальную локалку для сетевых игр по LAN. Традиционно, делать будем не совсем прямым и простым путём, зато бесплатно, без регистрации на левых сайтах, рекламы и посредников.
Вместо объяснений "зачем это тут, если есть <ProgramName>", расскажу о своём опыте работы (да-а-а, работы..) с некоторыми программами, предназначенными для этой же цели. Важным дополнением будет то, что играю в такие игры как правило только с друзьями и знакомыми, в основном кооп.
Первой такой прогой у меня была Hamachi. Работала стабильно, регулярно обновлялась, денег не просила. Потом в какой-то момент кардинально сменила свой внешний вид, стала называться LogMeIn Hamachi2, какие-то подвижки в плане коммерции стали появляться - не помню, то ли появились ограничения для бесплатного использования, то ли что-то ещё. Пропадала и появлялась снова полноценная поддержка UDP, часть игр перестала работать - помогал откат на более древнюю версию. Потом что-то поменяли, и старые версии перестали коннектиться. В топку.
Следующим был Wippien. Куча настраиваемых опций, авторизация и обмен сообщениями через Jabber, можно было использовать аккаунт на gmail для авторизации. Работал несколько лет без нареканий, но в один прекрасный момент все сервера-посредники надолго перестали работать. Разумеется, случилось это тогда, когда в планах было зарубиться компанией по сети. В топку.
Положение спас Tunngle. Сервис замечательный практически во всех отношениях: можешь сделать приватную локалку, с паролем или без, есть общественные локалки с разбиением по играм, встроенная справка о том, какую игру и как заточить под локалку, со ссылками на патчи и прочее. И сидел бы я на нем до сих пор, если бы не одно обстоятельство, становившееся всё более и более назойливым.
Реклама.
В начале я с пониманием относился к нижнему баннеру в окне приложения. Затем появилась колонка справа. Потом сверху. Потом баннер на всё окно по центру при входе. Всё это мигает и переливается - привет эпилептикам. Забил на этот Лас-Вегас. Не то, чтобы в топку, но перестал пользоваться.
Преимущества нашего варианта в том, что мы в дальнейшем ни от кого не зависим. В этой виртуальной локалке весь трафик будет зашифрован, причем ключи с самого начала гарантированно будут только у нас. Для того, чтобы подключиться к настроенному vpn, нам не нужны посредники, находящиеся неизвестно где и работающие тогда, когда это удобно им. Не нужна регистация в ещё одном сервисе, не надо постоянно качать обновления клиента - будучи настроенным один раз, наш vpn будет работать тогда, когда это надо именно нам.
Из недостатков - нууу... придётся сделать всё самому.
Итак, виртуальная локалка через OpenVPN: сервер + клиенты.
Гайд рассчитан на то, что ваш инет быстрый и комп будет выступать в роли сервера, у вас есть внешний IP (желательно статичный, но и динамичный тоже сойдёт, если на сервере настроить DDNS), вы знаете, как пробрасывать порты на роутере внутрь сети (если у вас есть роутер), умеете создавать файлы с нужным расширением и хорошо понимаете, о чём вообще говорится в этом абзаце.
Если же представляете слабо - то в любом поисковике по любому из этих вопросов есть подробные ответы, я гарантирую это. Пожалуйста, перед тем, как задавать тут вопрос по этим темам - загуглите и почитайте, инфа там подробно разжёвана.
########## Установка OpenVPN ##########
Забираем инсталлятор с официального сайта НЕ с главной страницы, а из раздела Community → Community Downloads: https://openvpn.net/index.php/open-source/downloads.html
На данный момент там выложена версия 2.4.1, но гайд почти полностью был написан и оттестирован более года тому назад по версии 2.3.8 на Windows 7. Начиная с версии 2.4, инсталляторы OpenVPN не работают на Windows XP, если кому-то это ещё актуально.
Для клиентов: дополнительно убираю галки OpenSSL Utilities, OpenVPN RSA Certificate Management Scripts и Add OpenVPN to PATH. Они нужны только для генерации сертификатов, а делается это на сервере.
Дальше лезем в свойства протокола TCP/IPv4, нажимаем на "Дополнительно", снимаем галку с Автоматического назначения метрики и указываем там вручную число 5.
Если эти проверки пропустить, то может получиться так, что потом вы не сможете сконнектиться в игре.
Цель манипуляций с метриками в том, чтобы после запуска vpn сессии (неважно, на сервере или на клиенте), у сетевого интерфейса "OpenVPN TAP" была бы минимальная метрика. Это означает, что все широковещательные запросы (такие, как поиск игровых серверов) будут отправляться через этот интерфейс. Позже мы сделаем проверку этих настроек.
########## Сертификаты и ключи для авторизации ##########
Эта часть гайда делается только на сервере. С помощью скриптов создаём все необходимые файлы авторизации как для сервера, так и для клиентов. Текста много, но по сути всё сводится к выполнению нескольких простых команд. По умолчанию скрипты создаются и работают в папке C:\Program Files\OpenVPN\easy-rsa, и нам потребуется запуск командной строки от имени администратора или доступ на запись и изменение файлов в этой папке и её подпапках. Выбирайте что вам удобнее.
Дополнительно мы немного поменяем входные данные для генерации сертификатов и настройки по умолчанию, а в остальном будем делать как сказано в README.txt
Первая часть операций (пункты c 1 по 6) выполняется только один раз при первичной настройке.
1. Запускаем командную строку и переходим в рабочую папку.
> cd C:\Program Files\OpenVPN\easy-rsa
2. Отключаем запрос адреса электронной почты при создании сертификатов. Для этого открываем файл openssl-1.0.0.cnf в блокноте, ищем секцию [ req_distinguished_name ] и в ней закомментируем параметры emailAddress и emailAddress_default (добавим # в начало строки).
#emailAddress = Email Address
#emailAddress_default = $ENV::KEY_EMAIL
3. Подготавливаем служебные переменные, которые будут использоваться при генерации сертификатов.
> init-config.bat
В папке появился файл vars.bat, открываем его в блокноте и редактируем нижний блок переменных.
set KEY_COUNTRY=RU
set KEY_PROVINCE=RU
set KEY_CITY=Pikabu
set "KEY_ORG=League Of Gamers"
rem set KEY_EMAIL=mail@host.domain
set KEY_CN=login
set "KEY_NAME=User Name"
set "KEY_OU=Virtual LAN"
set PKCS11_MODULE_PATH=.
set PKCS11_PIN=1234
Строку с KEY_EMAIL можно просто удалить.
Замечание 1: если в значении переменной есть пробелы, то в кавычки нужно брать всю пару "имя=значение", как в KEY_ORG, KEY_NAME и KEY_OU на примере выше. Если же открывающая кавычка будет стоять после знака равенства, то обе кавычки будут считаться частью значения переменной. Такой вот Microsoft way.
Замечание 2: в общем случае, значения переменных могут состоять из латинских букв, подчёркивания, минуса, точки и @.
Файл vars.bat необходимо и достаточно запускать один раз в каждой новой сессии командной строки перед тем, как начинаем генерить или отзывать сертификаты. Впрочем, ничего плохого не случится, если он будет запущен несколько раз в одной сессии.
4. Инициализируем новую папку для ключей
> vars.bat
> clean-all.bat
> openvpn --genkey --secret keys\hmac.key
А вот и первое отличие от инструкций из README. Последней командой мы создаем ключ, который будет известен только серверу и клиентам. В итоге все левые попытки подключения будут сразу и без ответа проигнорированы на ранней стадии, ещё до авторизации. Это значительно снижает нагрузку на наш сервер в случае DoS атаки.
5. Теперь создаём корневой сертификат, которым будем подписывать все остальные сертификаты (сервера и клиентов). Доступ к приватному ключу корневого сертификата должен быть только у того, кто генерит сертификаты, и нужен он только для генерации сертификатов.
Во время генерации нам предложат указать несколько полей (значения по умолчанию для них мы задали в vars.bat). Важными для нас будут только Common Name (также известный как CN), и Name. Для всех наших сертификатов значения CN должны быть уникальными, т.е. относитесь к нему как к логину. Другое поле, Name, используем как место для ФИО или описания логина. Все остальные поля оставляем по умолчанию (жмём Enter вместо ввода текста).
> build-ca.bat
При создании корневого сертификата в Common Name я пишу ca_root, и соответственно заполняю поле Name:
Country Name (2 letter code) [RU]:
State or Province Name (full name) [RU]:
Locality Name (eg, city) [Pikabu]:
Organization Name (eg, company) [League Of Gamers]:
Organizational Unit Name (eg, section) [Virtual LAN]:
Common Name (eg, your name or your server's hostname) [login]:ca_root
Name [User Name]:CA Root
6. Создаём файл с параметрами Диффи-Хеллмана. Он используется для безопасного обмена ключами при подключении к серверу. Это может занять некоторое время, в общем случае - нескольких секунд.
> build-dh.bat
Первоначальная подготовка завершена. Все последующие операции можно делать неограниченное количество раз в любой момент. Единственное, что надо помнить: нужно запускать vars.bat в каждом новом сеансе командной строки. Далее генерим один серверный и один или несколько клиентских сертификатов, которые будут использоваться для беспарольной авторизации при подключении.
В зависимости от настроек сервера (которые будут показаны дальше в посте) можно позволить клиентам использовать один и тот же общий сертификат, или же создавать сертификаты индивидуально. Я использую второй вариант, поскольку играю со знакомыми и мне несложно создать для каждого индивидуальный сертификат. Впрочем, первый вариант тоже имеет право на существование, если цель - создать открытую локалку для произвольного числа участников, только в этом случае мы фактически не имеем контроля над отдельными участниками. Если необходимо, то клиентский сертификат можно забанить на сервере - в первом случае доступа к серверу лишается вся группа, а во втором - только один человек. Опять же, выбирайте, какой вариант вам более удобен.
7. Создаём сертификат для сервера. В качестве параметра для build-key-server.bat рекомендую использовать то же значение, которое будет указано как логин. Это необязательно, но помогает не запутаться потом в файлах.
> vars.bat
> build-key-server.bat server
Почти все значения оставляем по умолчанию (жмём Enter вместо ответа), кроме необходимых: логин, имя, и двух подтверждений на подпись и выпуск сертификата.
Common Name (eg, your name or your server's hostname) [login]:server
Name [User Name]:VPN Server
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
В папке C:\Program Files\OpenVPN\easy-rsa\keys должны появиться файлы server.crt, server.key и server.csr
8. Создаём сертификат для клиента. Позднее, при добавлении новых клиентов пункты с 1 по 7 включительно пропускаем.
> vars.bat
> build-key.bat user1
Отвечаем на вопросы по тому же принципу, как и при создании серверного сертификата:
Common Name (eg, your name or your server's hostname) [login]:user1
Name [User Name]:Username 1
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
На выходе имеем комплект файлов user1.crt, user1.key и user1.csr. Файлы *.csr - промежуточные, нам они без надобности и при желании их можно смело удалять.
Кстати, немного о файлах и безопасности. В текущем виде секретными файлами являются *.key - они должны быть только у того, кому предназначены. Думайте о них как о файлах, содержащих пароль. Самым же оберегаемым файлом должен быть ключ к корневому сертификату, так как любой человек, заполучивший этот ключ, сможет наклепать сколько угодно сертификатов, которые подойдут к нашему серверу. В нашем случае мы генерим сертификаты на будущем сервере, но ничто не мешает создавать их на отдельном компе, чтобы даже серверу был неизвестен ключ от корневого сертификата.
Файлы *.crt, созданные нами, наоборот, не несут никакой секретной инфы и без соответствующего ключа спокойно могут быть обнародованы в инете.
########## Создаём конфиги ##########
Теперь начинается самая мякотка: создание собственной конфигурации OpenVPN. По умолчанию файлы конфигураций должны находиться в папке C:\Program Files\OpenVPN\config, её надо создать вручную. Конфиги сервера и клиентов будут немного различаться. Постараюсь дать более-менее внятное описание к каждой строчке конфига. А вообще, все доступные опции подробно расписаны в документации, находящейся в C:\Program Files\OpenVPN\doc\openvpn.8.html
Возьмём самую типичную схему: подключение к инету через роутер, наш сервер OpenVPN находится за NATом. При создании конфига примем, что:
- Служба будет запущена на порту 1194
- Роутеру выдан внешний IP адрес 9.9.9.9; если IP динамический, то мы заранее получили DDNS имя (например, my-vpn.example.org)
- Роутеру присвоен внутренний статичный IP адрес 192.168.0.1 (для ясности, в конфигах не используется)
- Серверу присвоен внутренний статичный IP адрес 192.168.0.2
- На роутере входящие TCP соединения к порту 1194 перенаправляются на адрес 192.168.0.2, порт 1194. Да, UDP передаётся немного быстрее, но нет гарантированной доставки пакетов и порядка их доставки, так что мой выбор был в пользу TCP. На практике же всё зависит от инета, и пинг в 17 мс на расстоянии более 200 км и разных провайдеров для меня вполне приемлимо.
- Наши IP адреса в виртуальной локалке будут лежать в диапазоне 172.27.10.1 - 172.27.10.254 с маской 255.255.255.0
### Конфигурация сервера ###
Создаем файл server.ovpn, открываем его в блокноте и начинаем заполнять конфиг. В конце поста будет секция для копипастинга, а здесь - подробно про каждую используемую опцию. Готовый файл кладём в папку C:\Program Files\OpenVPN\config
port 1194
Порт, на котором будет запущена служба. 1194 - это порт по умолчанию, так что время от времени всякие левые личности будут пробовать подключиться к этому порту. Чтобы значительно снизить количество таких "проверок", можно запустить сервис на другом свободном порту, например, из диапазона 2048 - 65535. Для этого придется соответственно изменить конфиги сервера и клиентов, и перенастроить проброс порта на роутере. Добавлю, что сам по себе перенос сервиса на нестандартный порт не может считаться хоть какой-то защитой. Скорее - это первичный фильтр от пионеров и быстрых сканирований.
dev tap
Тип сетевого интерфейса, используемого при создании тоннеля. В данном случае указывает на наш сетевой интерфейс, который мы назвали "OpenVPN TAP". Оставьте как есть.
keepalive 30 120
Настройки таймаутов. Если в течении 30 секунд по тоннелю не было ничего отправлено, то принудительно отправляется контрольный пинг. Если ответа на пинг нет в течении 240 секунд (для сервера это значение автоматически удваивается, чтобы аналогичный таймаут сработал сначала на клиенте), то производится автоматическое переподключение.
persist-key
При перезапуске тоннеля ключи не будут читаться заново из файлов, а будут использован кэш в памяти.
persist-tun
При перезапуске тоннеля сетевой интерфейс ("OpenVPN TAP") не будет выключаться и включаться, что уменьшит время на переподключение.
verb 1
Управляет количеством и типом инфы, которое будет выводиться в лог. 0 - полное отключение логирования, чем больше число (вплоть до 11), тем больше инфы будет валиться. Как правило, больше 4 имеет смысл разве что при продвинутой отладке. С 1 в логе будет видны попытки подключения/отключения, логины подключающихся и прочая мелочь.
mute 3
Ограничивает вывод в лог последовательных однотипый сообщений. В данном случае, максимум три похожих сообщения подряд будут записаны.
comp-lzo no
Отключает сжатие передаваемых по тоннелю данных. Абсолютно ненужное для нашего случая действо, так как в основном игры передают друг другу бинарные данные, которые при сжатии даже могут увеличиваться в размерах в итоге. Так что незачем тратить на это время. Да и в общем случае, сейчас доля текстовой инфы в трафике крайне мала, а картинки или видео как правило уже сжаты, так что польза от компрессии тоннеля весьма сомнительна.
proto tcp-server
Используем протокол TCP для поднятия тоннеля в режиме сервера.
server 172.27.10.0 255.255.255.0
Присваиваем серверу локальный IP 172.27.10.1, автоматически раздаём IP адреса всем подключающимся клиентам из диапазона 172.27.10.2 - 172.27.10.254 и соответственно настраиваем маршрутизацию.
local 192.168.0.2
Сервер будет принимать vpn подключения только на этом адресе/интерфейсе. Можно эту опцию не указывать, тогда сервер будет запущен на всех доступных ему локальных IP адресах.
client-to-client
По умолчанию все клиенты изолированы друг от друга и видят только сервер. С этой опцией становится возможна передача данных между клиентами.
tcp-nodelay
Отключает буферизацию TCP на сервере и клиентах, что позволяет пихать пакеты в тоннель как можно быстрее.
tcp-queue-limit 256
При отправке пакетов от сервера к клиентам может произойти так, что виртуальный сетевой интерфейс "OpenVPN TAP" будет генерить пакеты быстрее, чем они отправляются к клиентам через TCP соединение. Если очередь заполнится, то новые пакеты будут дропаться, пока не появится место в очереди отправки. Эта опция увеличивает размер очереди отправки (по умолчанию - 64).
#duplicate-cn
По умолчанию (и сейчас) отключенная опция, которая, будучи задействованной, позволяет нескольким клиентам использовать один общий сертификат. Без этой опции новый клиент с таким же сертификатом выкинет с сервера старого клиента.
#crl-verify "crl.pem"
Также закомментированная опция. Используется для отзыва (бана) сертификатов. Параметром является специально сформированный файл, содержащий инфу об отозванных сертификатах. О том, как этим пользоваться, будет рассказано далее в посте.
tls-auth "hmac.key" 0
Используем ключ, который мы сгенерили в 4 шаге для быстрой отбраковки левых попыток авторизации. Второй параметр ставим 0 для серверного конфига или 1 для клиентского.
ca "ca.crt"
Указываем корневой сертификат, которым подписаны серверный и клиентский сертификаты.
cert "server.crt"
Указываем сертификат, используемый для авторизации. В данном случае - сертификат сервера.
key "server.key"
Указываем на ключ к сертификату из предыдущей опции.
dh "dh1024.pem"
Указываем на файл с параметрами Диффи-Хеллмана, который мы создали в 6 шаге. Требуется только для сервера.
### Конфигурация клиента ###
Для каждого клиента создаем отдельный файл конфигурации. Различаться эти файлы будут только параметрами для опций cert и key. К примеру, для логина user1 создадим файл user1.ovpn со следующими опциями:
port 1194
dev tap
keepalive 30 120
persist-key
persist-tun
verb 1
mute 3
comp-lzo no
Несколько общих одинаковых опций, уже описаных выше.
proto tcp-client
Используем протокол TCP для поднятия тоннеля в режиме клиента.
client
Принимаем настройки маршрутизации от сервера и включаем TLS шифрование в режиме клиента.
remote 9.9.9.9
Указываем адрес vpn сервера. Можно указать доменное имя, например, my-vpn.example.org из наших предположений в начале секции.
connect-retry-max 2
Количество попыток переподключения в случае обрыва соединения. Если опцию не указывать, то клиент будет пытаться подключиться до бесконечности.
nobind
Использовать динамический порт для исходящего подключения. Порт будет выбираться на усмотрение ОС. Если не указать эту опцию, то для исходящих подключений будет использован порт, указанный в опции port.
remote-cert-tls server
Защита от MitM-атак: проверяет, что другой сертификат "с той стороны тоннеля" подписан и используется как серверный сертификат. Аналогичная проверка со стороны сервера (remote-cert-tls client) тоже может быть указана в серверном конфиге, но так как атака направлена на исходящее соединение от клиента к серверу (подмену сервера на злоумышленника с клиентским сертификатом), то от опции remote-cert-tls client будет мало пользы в нашем случае.
tls-auth "hmac.key" 1
Используем ключ, который мы сгенерили в 4 шаге для быстрой отбраковки левых попыток авторизации. Второй параметр ставим 0 для серверного конфига или 1 для клиентского.
ca "ca.crt"
Указываем корневой сертификат, которым подписаны серверный и клиентский сертификаты.
cert "user1.crt"
Указываем сертификат, сгенеренный для пользователя.
key "user1.key"
Указываем ключ от пользовательского сертификата.
Конфиги готовы. Для остальных клиентов копипастим имеющийся клиентский конфиг и меняем значения опций cert и key.
########## Собираем все нужные файлы вместе ##########
В папке C:\Program Files\OpenVPN\easy-rsa\keys находится всё, что было создано консольными командами. Забираем оттуда всё, что используется в конфиге. В конечном итоге, в папке C:\Program Files\OpenVPN\config должны быть следующие файлы:
На сервере
ca.crt
dh1024.pem
hmac.key
server.ovpn
server.crt
server.key
На клиенте
ca.crt
hmac.key
user1.ovpn
user1.crt
user1.key
Не забываем, что в файлах *.key содержится приватная информация, поэтому передаём ключи клиенту по возможности по безопасному каналу.
########## Подключение и проверка ##########
Запускаем OpenVPN-GUI с правами администратора (неактуально в версии 2.4.), в трее на иконке нажимаем правую кнопку мыши и в меню выбираем "Подключиться". В зависимости от типа конфига, запустится сервер или клиент vpn. После успешного подключения иконка сменит цвет на зелёный.