Как настроить VPN для команды веб-разработки

Как настроить VPN для команды веб-разработки

Главная особенность современного Интернета — его постоянная доступность. Нет нужды сохранять локально данные, быстро доступные по сети. Тем больше проблем возникает, если эти данные вдруг становятся недоступны в непредсказуемый момент.

Все разработчики в WB—Tech работают удалённо и могут находиться в различных частях России и мира. На различных территориях некоторые ресурсы могут быть недоступны по разным причинам.

В статье расскажем, как и почему мы используем связку OpenVPN + ansible для решения подобных проблем.

Примеры проблем

Что практически означает недоступность интернет-ресурса?

  • Не скачиваются библиотеки ЯП — не собирается development окружение проекта. Это самая главная и большая проблема!
  • Не работают Zoom, Slack  или Telegram — не получится связаться с коллегами.
  • Недоступны некоторые сайты, например, github — невозможно опубликовать свою работу.

Это не все возможные примеры, но даже они существенно сокращают производительность команды.

Кто виноват?

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

Но иногда и провайдер может оказаться негодяем. Например, по неведомой причине заблокировать трафик на определенные TCP порты.

Или модифицировать нешифрованный http трафик и изменять html код страницы, добавлять рекламу. Такого ожидаешь от каких-нибудь мошенников, но точно не от крупной федеральной компании, поэтому вдвойне неприятно (если интересно, гуглите «реклама поверх чужих сайтов»).

И что делать?

Однажды масштаб проблемы дал понять, что нужно решать её на уровне компании, а не отдавать на откуп членам команды. Мы решили использовать технологию VPN.

VPN (Virtual Private Network) — виртуальная частная сеть. Это название группы технологий, которые позволяют создать виртуальную, несуществующую физически (оверлейную) компьютерную сеть на основе существующей физической компьютерной сети.

Это даёт дополнительные возможности по увеличению приватности. В физической сети, в первом приближении, ваш трафик доступен всем участникам сетевого обмена, всем маршрутизаторам и тд. В виртуальной сети нет дополнительных участников, только вы и точка, к которой вы подключаетесь. В нашем случае это VPN сервер. Между вами двумя прокладывается зашифрованный туннель.

На машине клиента и на сервере создаются виртуальные сетевое интерфейсы tun. Зашифрованный обмен данным происходит напрямую между ними. Ваши данные фактически защищены от атаки man-in-the-middle (MITM). Никто из имеющих физический доступ к оборудованию, через которое идёт ваш трафик, не может перехватить или подменить вашу информацию.

Также это позволяет получить доступ к ресурсам, которые недоступны в домашней сети, но доступны с VPN сервера.

Схематически изменение доступности сетевого ресурса выглядит так.

В ситуации А сетевой ресурс доступен для пользователя
В ситуации Б — уже недоступен

Внедрение в эту схему VPN сервера может выглядеть так.

Схема доступа к сетевому ресурсу с использованием VPN-сервера

В данном случае пользователь устанавливает логическое точка-точка соединение поверх существующей сети, при этом трафик логического соединения зашифрован от провайдера, а целевой сетевой ресурс доступен пользователю.

При помощи технологии VPN клиент становится частью подсети, частью которой является сервер. И может получить доступ к ресурсам этой подсети. Это может использоваться не только для обхода ограничений, но и для решения любых других задач, требующих удалённо и безопасно подключаться к подсети.

Выбор реализации VPN

Решить — не значит сделать. Существует несколько распространённых свободных реализаций VPN технологии.

Мы выбрали OpenVPN по следующим причинам:

  • данная реализация достаточно проста в настройке — в сети есть большое количество мануалов по настройке,
  • широко используется — большой опыт использования в интернет-коммьюнити, первый выпуск состоялся в 2002 году,
  • распространяется по лицензии GNU GPL,
  • кроссплатформенная реализация — есть клиенты для всех распространённых операционных систем, в том числе мобильных.

Что ещё можно было выбрать:

  • IPsec — набор протоколов для безопасной передачи данных. Появился в середине 90-х. Это большая и гибкая, но сложная в настройке низкоуровневая штука. Для наших целей избыточно сложно.
  • WireGuard — молодой проект (2015 год), нацеленный на быструю подготовку к работе. Потенциально более быстрый при передаче данных, чем OpenVPN, использует более современные протоколы шифрования. Кроссплатформенный, доступен на всех основных системах. Недостаток тот же, что и достоинство. Чтобы обеспечить быструю и простую установку много низкоуровневых решений принято в ядре программы. Например, использование протокола UDP, что нам, например, не подошло.
  • Freelan, GoVPN и другие возможно интересные проекты, но они обладают существенно меньшим коммьюнити. А их потенциальные преимущества перед 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 адрес своего арендованного сервера.

Всё взаимодействие с сервером осуществляется тремя командами:

1. Запуск сценария создания сервера и центра сертификации.

ansible-playbook create_ca_and_server.yml

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

2. Регистрация нового пользователя.

ansible-playbook create_client.yml --extra-vars
"client_name=<client_name>"

Создаёт новый ключ и сертификат нового пользователя, регистрирует его в в центре сертификации, обновляет список валидных сертификатов на сервере и перезапускает сервер.

3. Отзыв сертификата по имени клиента.

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, выданный вашим провайдером.

Внешний ip-адрес до и после запуска VPN клиента

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

tun0 интерфейс в выводе команды ip a (последний в списке)

Не панацея

Развитие способов обхода блокировок во многом схоже с отношением хищников и жертв в природе. На каждый новый приём находится контр-приём. Соединения 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 раза выше для одного клиента. Бесплатные сервисы не рассматриваются из-за их серьёзных ограничений по скорости/трафику, а также возможных проблем с безопасностью.


Другие статьи серии о о программных решениях, которые мы используем в своей работе:

Если хотите убедиться, что всё делаете правильно, или проконсультироваться по поводу разработки вашего проекта, напишите нам.