Примеры проблем
Кто виноват?
И что делать?
Выбор реализации VPN
Выбор способа запуска и использования
— Вручную
Наш вариант
Архитектура сервера
Результат
Запуск сервера
Под капот
Конфиг клиента
Запуск
Не панацея
Выводы
Главная особенность современного Интернета — его постоянная доступность. Нет нужды сохранять локально данные, быстро доступные по сети. Тем больше проблем возникает, если эти данные вдруг становятся недоступны в непредсказуемый момент.
Все разработчики в WB—Tech работают удаленно и могут находиться в различных частях России и мира. На различных территориях некоторые ресурсы могут быть недоступны по разным причинам.
В статье расскажем, как и почему мы используем связку OpenVPN + ansible для решения подобных проблем.
Что практически означает недоступность интернет-ресурса?
Это не все возможные примеры, но даже они существенно сокращают производительность команды.
Описанные выше ограничения на практике, как правило, реализует интернет-провайдер. И винить провайдера в них нет смысла, потому что ограничения введены административными актами государств. Провайдер должен заниматься бизнесом, а не политической борьбой.
Но иногда и провайдер может оказаться негодяем. Например, по неведомой причине заблокировать трафик на определенные TCP порты.
Или модифицировать нешифрованный http трафик и изменять html код страницы, добавлять рекламу. Такого ожидаешь от каких-нибудь мошенников, но точно не от крупной федеральной компании, поэтому вдвойне неприятно (если интересно, гуглите «реклама поверх чужих сайтов»).
Однажды масштаб проблемы дал понять, что нужно решать ее на уровне компании, а не отдавать на откуп членам команды. Мы решили использовать технологию VPN.
VPN (Virtual Private Network) — виртуальная частная сеть. Это название группы технологий, которые позволяют создать виртуальную, несуществующую физически (оверлейную) компьютерную сеть на основе существующей физической компьютерной сети.
Это дает дополнительные возможности по увеличению приватности. В физической сети, в первом приближении, ваш трафик доступен всем участникам сетевого обмена, всем маршрутизаторам и тд. В виртуальной сети нет дополнительных участников, только вы и точка, к которой вы подключаетесь. В нашем случае это VPN сервер. Между вами двумя прокладывается зашифрованный туннель.
На машине клиента и на сервере создаются виртуальные сетевое интерфейсы tun. Зашифрованный обмен данным происходит напрямую между ними. Ваши данные фактически защищены от атаки man-in-the-middle (MITM). Никто из имеющих физический доступ к оборудованию, через которое идет ваш трафик, не может перехватить или подменить вашу информацию.
Также это позволяет получить доступ к ресурсам, которые недоступны в домашней сети, но доступны с VPN сервера.
Схематически изменение доступности сетевого ресурса выглядит так.
Внедрение в эту схему VPN сервера может выглядеть так.
В данном случае пользователь устанавливает логическое точка-точка соединение поверх существующей сети, при этом трафик логического соединения зашифрован от провайдера, а целевой сетевой ресурс доступен пользователю.
При помощи технологии VPN клиент становится частью подсети, частью которой является сервер. И может получить доступ к ресурсам этой подсети. Это может использоваться не только для обхода ограничений, но и для решения любых других задач, требующих удаленно и безопасно подключаться к подсети.
Решить — не значит сделать. Существует несколько распространенных свободных реализаций VPN технологии.
Мы выбрали OpenVPN по следующим причинам:
Что еще можно было выбрать:
Самый очевидный способ — арендовать VPS, подключиться по SSH и создать сервер, следуя руководству. Это довольно длительный процесс, что связано с большим количеством команд и файлов, которые нужно вручную перемещать.
При данном способе каждый раз при создании нового сервера придется делать все заново. Чтобы сэкономить время, можно воспользоваться системами управления конфигурациями или системами контейнеризации.
Системы управления конфигурациями — это программное обеспечение, позволяющее автоматизировать конфигурирование удаленных серверов (puppet, ansible и др). Преимущество данного подхода в том, что можно в пару команд настроить удалённый VPN сервер. А все конфиги, шаблоны конфигов в явном виде в текстовом формате размещены на управляющей машине. Сценарий развертывания можно создать самостоятельно или взять готовый, например, на github.
Немного другой подход применяется в системах контейнеризации. Самая распространенная подобная система виртуальной контейнеризации — docker. Также, как и для системы управления конфигурациями, для docker в сети доступны готовые образы с OpenVPN. Установка контейнера docker c VPN на удаленном сервере может быть еще более быстрой, чем установка сервера через ansible, что плюс. Однако список доступных конфигураций может быть ограничен разработчиками образа. Образы представляют собой бинарные файлы, поэтому при необходимости исправить какой-нибудь экзотический конфиг, это может не получиться.
Мы решили создать собственный проект OpenVPN в связке с ansible. Самая главная причина — любознательность. Так случилось, что я не имел дела ни с OpenVPN, ни с ansible. Хотелось научиться, а подобный проект очень хорош для данной цели.
Если вы хотите сразу получить готовое решение, можете взять наш проект или найти любой другой из описанных выше.
Во-первых, как уже было сказано, технологию VPN можно использовать для подключения, например, к закрытой подсети через компьютер, который является частью этой подсети и, одновременно, VPN сервером. Если в вашей подсети есть очень ценные ресурсы, хотелось бы, чтобы к VPN серверу не подключался абы кто. Для этого центр сертификации OpenVPN обычно делает отдельной машиной, вообще не подключенной ни к одной сети, возможно, в сейфе (без шуток). А запросы на подпись и подписанные сертификаты переносят на съемном носителе.
В нашем варианте центр сертификации и сервер размещаются на одной машине. Мы сделали выбор в пользу возможности быстро развернуть новую пару сервер+центр сертификации, поскольку требования к безопасности и потенциальные риски для наших задач не перевешивают удобства.
Для управления доступом к сервису решили использовать создание и отзыв пользовательских сертификатов, а не парольный доступ. Это удобнее, так как и параметры доступа, и настройки клиента можно разместить в одном файле.
Наше решение абсолютно не претендует на эталон — оно линейное, не предполагает гибкости и изменения конфигов VPN с помощью команд. Однако оно стабильно работает, и его просто установить и использовать. Иногда нет смысла использовать более сложные в конфигурировании системы.
Если вы хотите впервые использовать ansible или OpenVPN (или обе технологии вместе), рекомендую создать подобный проект самостоятельно в качестве учебного полигона.
Для создания ansible-скрипта мы взяли за основу существующий гайд по OpenVPN.
Для запуска ansible скрипта вам понадобится установить ansible на компьютер, арендовать виртуальный сервер с Debian/Ubuntu и настроить доступ к серверу по ssh.
При аренде сервера учтите, что некоторые сервисы не позволяют создавать tun интерфейс или осуществлять форвардинг пакетов. Уточните это до покупки.
Скопируйте наш проект с github и замените в файле hosts.yml конфигурацию hosts — вставьте публичный ip адрес своего арендованного сервера.
Все взаимодействие с сервером осуществляется тремя командами:
ansible-playbook create_ca_and_server.yml
ansible-playbook create_client.yml --extra-vars
"client_name=<client_name>"
ansible-playbook revoke_client.yml --extra-vars
"client_name=<client_name>"
Предлагаю кратко пройтись по основным частям ansible скрипта.
Playbook создания сервера:
- hosts: all become: true tasks: - import_tasks: tasks/server_preparation.tasks.yml - import_tasks: tasks/server_net.tasks.yml - import_tasks: tasks/ca_pki.tasks.yml - import_tasks: tasks/server_pki.tasks.yml - import_tasks: tasks/server_registration.tasks.yml - import_tasks: tasks/server_gathering_files.tasks.yml - import_tasks: tasks/server_daemons.tasks.yml - import_tasks: tasks/server_client_infrastructure.tasks.yml
server_preparation.tasks.yml
Устанавливаем нужные пакеты, непосредственно openvpn и файервол ufw, через который в дальнейшем будем управлять переадресацией трафика на сервере.
Создаем из шаблона конфиг для сервера. Для передачи трафика на сервер используем протокол TCP и порт 443 вместо дефолтного UDP/1194, так как трафик с дефолтными настройками не пропускал провайдер.
Несколько раз встречал обсуждение, что провайдер применяет различные методы анализа трафика и может блокировать соединения по ip адресу, если обмен идет постоянно на один и тот же адрес. Мы с таким пока не встречались, наше решение не предполагает обхода подобных блокировок.
server_net.tasks.yml
Включаем форвардинг пакетов, настраиваем NAT. А также разрешаем подключения к серверу только на порт 22 (для управления) и 443.
ca_pki.tasks.yml
В таске создается сертификационный центр — CA (Certification authority). Сначала при помощи easy-rsa создается инфраструктура публичных ключей (PKI), затем генерируется сертификат CA и список отозванных сертификатов пользователей (Certificate Revocation List – CRL).
server_pki.tasks.yml
По аналогии с предыдущим, только для сервера создаем PKI и сертификат. Дополнительно создаем приватный ключ.
server_registration.tasks.yml
Регистрируем сервер в центре сертификации. Обратите внимание, что файлы не перемещаются, так как центр сертификации и сервер находятся на одной машине. Для команды регистрации и подобных команд используются абсолютные пути.
server_gathering_files.tasks.yml
На данном этапе в папку демона сервера (не PKI) копируются все созданные файлы.
server_daemons.tasks.yml
Перезапускаем OpenVPN сервер с новым конфигом, включаем файервол.
server_client_infrastructure.tasks.yml
Создаем PKI для клиентов. После этого сервер запущен и готов для внешних подключений. Осталось создать клиентов.
Плейбуки создания и отзыва сертификатов клиентов состоят из одного таска и основаны на соответствующих командах командной строки. При отзыве сертификата генерируется новый CRL и перезапускается сервер.
После запуска скрипта создания клиента в директории.
./client_configs_from_remote/<server_ip>/openvpn/client-configs/files/
Появится файл конфигурации клиента следующего вида.
<client_name>.ovpn
В данной реализации все криптографические данные в виде тегов добавлены в конец файла. Поэтому клиенту достаточно передать один файл для доступа к серверу.
Кроссплатформенность — важное преимущество OpenVPN. Файл конфига можно использовать на всех популярных системах: Linux, iOS, Windows, Andorid.
Для запуска на Linux используется команда.
sudo openvpn --config <client_name>.ovpn
Предварительно необходимо установить openvpn клиент. После запуска внешние сервисы будут видеть вас под другим ip, чем ip, выданный вашим провайдером.
Как мы уже говорили, при помощи VPN можно стать частью подсети сервера на машине клиента. В случае OpenVPN это реализуется созданием виртуального сетевого интерфейса tun на компьютере клиента.
Развитие способов обхода блокировок во многом схоже с отношением хищников и жертв в природе. На каждый новый прием находится контрприем. Соединения VPN не исключение.
При использовании VPN вы фактически можете пользоваться различными сетевыми ресурсами. Но, поскольку, все данные идут до вас через туннель от VPN сервера, для провайдера это выглядит, как будто вы обмениваетесь данными только с одним ip адресом.
Хотя технологии VPN не запрещены в России, системы анализа трафика провайдеров могут ограничивать скорость при подобного рода распределении трафика. Причины этого неясны.
OpenVPN — распространенное ПО, у которого есть много мануалов и комьюнити, всегда готовое помочь. Подходит для решения большинства «бытовых» задач.
Лучше использовать OpenVPN не саму по себе, а вместе с docker или, как мы, с ansible. Благодаря ansible скрипту можно развернуть сервер за несколько минут. Основная часть времени уходит на аренду VPS.
Существует большое количество готовых подобных реализаций на github, bitbucket, docker.hub или других площадках. У всех свои плюсы и минусы.
Наша реализация ansible+OpenVPN простая и линейная, зато понятная. Работать с ней удобно. Конфигурация легко настраивается через шаблоны конфигурационных файлов.
Настроить собственный VPN дешевле, чем использовать готовые сервисы. Для наших целей под сервер VPN подходит самая слабая конфигурация VPS, стоимость аренды 200-300 рублей в месяц. При этом можно создать большое количество клиентов. Стоимость подключения к готовому сервису обычно в 2-2,5 раза выше для одного клиента. Бесплатные сервисы не рассматриваются из-за их серьезных ограничений по скорости/трафику, а также возможных проблем с безопасностью.
Если хотите убедиться, что все делаете правильно, или проконсультироваться по поводу разработки вашего проекта, напишите нам.
Никакого спама, только анонсы новых статей
ИП Гришанин Кирилл Олегович
ИНН 774313842609
Б. Новодмитровская ул., 36, стр. 12, вход 6,
Москва, Россия, 127015
Ahad Ha'am 54,Tel Aviv-Yafo,Израиль