Как держать 20 тысяч VPN клиентов на серверах за $5


Как держать 20 тысяч VPN клиентов на серверах за $5

Месяц назад мы с друзьями сделали бесплатный сервис для обхода блокировок сайтов в Украине Zaborona.Help. За это время сервис стал довольно популярным, аудитория выросла до 20 000 пользователей. Число одновременных подключений в пиковые часы — ≈6 000 клиентов.

Главная особенность нашего сервиса в том, что через VPN маршрутизируется трафик только к заблокированным сетям, остальные сайты работают напрямую. Это не влияет на скорость интернета и не подменяет IP-адрес для остальных сайтов.

В статье описываются тонкости настройки OpenVPN для большого числа клиентов, на дешевых VPS.

  • Как выбрать подходящий хостинг. Отличительные черты плохого хостинга. История о том, как мы долго искали и нашли хостинг в России.
  • Почему IPv6 — хорошо. Правильная настройка IPv6-адресов для VPN-клиентов.
  • Изменение конфигурации OpenVPN на лету, без перезапуска сервера и отключения клиентов.
  • Балансировка нагрузки между серверами и процессами OpenVPN
  • Тонкая настройка Linux для большого числа подключений
  • Особенности кривых операционных систем и роутеров пользователей

Хостинг

Поначалу мы использовали несколько серверов в Европе у провайдеров Scaleway, Linode, DigitalOcean. Это были самые дешевые VPS, за $3-5. Сразу же пользователи начали жаловаться, что из-за европейских IP-адресов Яндекс.Музыка и музыка VK.com недоступна. Мы начали искать подходящий хостинг в СНГ.

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

Отличительные черты убогого хостинга

    Использование термина VDS вместо VPS. Хоть в самой аббревиатуре нет ничего страшного, это своего рода черная метка, которая практически гарантирует низкий уровень сервиса и интерфейс панели управления из 90-х годов.

Наши требования к VPS-серверам

    Виртуализация XEN или KVM. OpenVZ в большинстве случаев не позволяет нормально управлять IPv6-адресами, имеет ограничения на настройку переменных ядра (sysctl). Для некоторых нужд OpenVZ вполне пригоден, но не для большого и высоконагруженного VPN-сервера.

Это звучит странно, но я готов аргументированно доказать в комментариях, что 99% отечественных хостеров — фуфло, недотягивающее до уровня Европы. Особенно буду рад пообщаться с представителями крупных компаний, вроде МастерХост, REG.ru, 1GB.ru, Timeweb.

Как мы подружились с Veesp.com

Настоящим открытием для нас стал хостер Veesp.com с датацентром в Санкт-Петербурге. Это единственный хостер, который знал как правильно готовить IPv6. На каждый VPS сервер выделяется сеть /64 и по запросу /56.

У них есть две линейки тарифов VPS. Мы используем тариф «Storage 1», с безлимитным трафиком. Сервера на этом тарифе имеют процессор Intel Xeon X5650. Также есть линейка тарифов «Compute», с SSD диском, мощным процессором Intel Xeon E5v4 и памятью DDR4.

Линейка тарифов Compute VPS провайдера Veesp.com

Линейка тарифов Compute VPS провайдера Veesp.com

Панель управления сравнима по удобству с DigitalOcean. Есть даже оплата через Bitcoin!

На текущий момент мы полностью переехали на площадку Veesp.com и используем шесть серверов Storage 1 для OpenVPN. Музыка в VK и Яндексе снова работает, пользователи довольны.

Я очень люблю IPv6. Он позволяет избавиться от кучи ненужных сущностей, вроде NAT и проброса портов. Для VPN он удобен тем, что каждый клиент ходит в интернет со своим реальным IP-адресом. К сожалению, многие хостинг-провайдеры и системные администраторы противятся и недолюбливают этот протокол, из-за этого его неправильно настраивают и используют.

Самая распространенная ошибка — выдавать один IPv6-адрес на сервер.
Сайт slash64.net посвященный этому заблуждению.

Почему нужно выделять минимум /64 на каждый конечный узел

    Для простоты. Согласно RFC 6177, сеть /64 является рекомендуемым блоком для всех конечных узлов, будь то домашний интернет или хостинг. Это 2⁶⁴, или восемнадцать квинтиллионов IP-адресов. Такой подход избавит от путаницы и угадывания, как именно настроена сеть на каждом отдельном узле.

Существует два распространенных варианта раздачи маршрутизируемах сетей.

Первый вариант: одна /64 на сетевом интерфейсе, и /56, маршрутизируемая через первую /64. Вы можете побить /56 так, как вам хочется, либо же назначить всю /56 на интерфейс VPN.

Второй вариант: одна или несколько /64 (или больше), маршрутизирутизируемая через link-local-адрес.

У большинства хостеров выделенную сеть нужно заказывать отдельно. Veesp.com выдает блок /56 на каждый сервер бесплатно. К сожалению, даже продвинутые хостеры, вроде DigitalOcean, не предоставляют такой услуги. Здесь есть список хостеров, предоставляющих данную услугу version6.ru/vps, от @rm.

NAT и Firewall

На серверах забороны больше двух сотен правил iptables, по несколько на каждый диапазон из списка запрещенных в Украине сетей.

Сложный набор правил неудобно обслуживать стандартными средствами iptables-save и iptables-restore , потому что в случае изменения одного правила, необходимо будет редактировать сотни однотипных строк.

Упрощаем написание правил файрволла с помощью ferm

Ferm — утилита для управления сложными правилами iptables со своим синтаксическим сахаром. Она позволяет создать удобочитаемую конфигурацию iptables, использовать переменные, массивы и циклы, но не ограничивает вас, в отличие от других надстроек над iptables: вы можете делать абсолютно все, использовать все возможности и модули netfilter.

Простой пример: мы хотим заблокировать входящие соединения из нескольких тысяч сетей на трех сетевых интерфейсах eth0, eth1, eth2. В обычном случае нужно было бы написать тысячи одинаковых правил для каждого интерфейса.

Вот как эта задача решается через ferm:

В результате будет создано правило для каждого адреса из $BLOCKED_NETWORKS на каждый сетевой интерфейс. Такая запись легко читается и занимает в три раза меньше строк. Ее проще редактировать.

В нашем случае iptables выполняет три функции: NAT для IPv4-соединений, ограничение доступа в другие сети и балансировка нагрузки между процессами OpenVPN. Разберем каждую задачу подробно.

NAT для IPv4-соединений

Клиентам выдается «серый» IP-адрес из диапазона 192.168.*.*, поэтому маршрутизировать его напрямую в интернет нельзя. Для того, чтобы выпустить клиентов в IPv4-интернет, нужно использовать преобразование сетевых адресов (NAT).

Тем же самым занимается ваш домашний WiFi-роутер. На каждое исходящие соединение клиента создается трансляция в памяти сервера, которая хранит информацию о том, кому какое подключение принадлежит. Несмотря на то, что эта операция требует мало ресурсов сервера, при огромном количестве подключений (десятки тысяч), это может стать ресурсоемкой задачей для слабого сервера.

Этой проблемы нет в IPv6, так как каждому VPN-клиенту выдается реальный IP-адрес, который напрямую маршрутизируется в интернет. Серверу остается только перебрасывать пакеты с одного интерфейса на другой, без создания трансляций и хранения информации о каждом подключении.

Ограничение доступа в другие сети

Любой пользователь может добавить опцию redirect-gateway в конфиг OpenVPN и использовать наши сервера как маршрут по умолчанию. Нужно закрыть доступ ко всем сетям, кроме заблокированных в Украине.

Балансировка нагрузки между процессами OpenVPN

Архитектура OpenVPN однопоточная, поэтому один процесс демона OpenVPN использует только одно ядро процессора. Для лучшей утилизации всех ядер процессора, число процессов должно равняться количеству ядер на сервере. Балансировка между процессами выполняется с помощью модуля statistic, который случайном образом перенаправляет входящие подключения на разные внутренние порты.

Балансировка между серверами

Мы используем самый простой способ балансировки — с помощью множественных А-записей DNS. Все клиенты подключаются к серверу через доменное имя vpn.zaborona.help. Этот домен имеет шесть А-записей, которые направлены на все сервера. В итоге, в момент подключения, клиент выбирает случайный сервер из доступных. Так общее число подключений равномерно распределяется между всеми серверами. Конфигурация OpenVPN на всех серверах идентична, за исключением диапазонов IPv6-адресов, выдаваемых клиентам.

image

Панель управления DNS-записями. Балансировка с помощью множественых А-записей. Малое значение TTL позволяет быстро удалять адреса из общего списка.

Можно быстро посмотреть, на какие IP-адреса резолвится домен из разных точек планеты, с помощью сервиса host-tracker.com, выбрав любой из тестов, например http или ping.

Рекурсивные DNS-резолверы

Многие украинские провайдеры блокируют DNS-запросы к запрещенным доменам, перехватывая запросы в том числе и к сторонним DNS-серверам, вроде 8.8.8.8. Поэтому важно, чтобы клиенты посылали DNS-запросы через VPN тоннель, где их не сможет модифицировать провайдер.
Это не так просто сделать, потому что в новых версиях Windows запросы могут уходить ко всем DNS-серверам в системе, и будет использоваться тот, который ответит быстрее. DNS-сервер провайдера находится физически ближе к клиенту, поэтому, с большой вероятностью, система быстрее получит подмененный ответ провайдера, а не корректный ответ DNS внутри VPN, и сайт останется заблокирован.

Для решения этой проблемы ValdikSS написал патч для OpenVPN, блокирующий утечки DNS в Windows. Он использует Windows Filtering Platform — специальный слой файрволла Windows, позволяющий блокировать запросы к сторонним DNS, пока запущен OpenVPN.

Разворачивание сервера

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

Конфиги максимально унифицированы и могут быть без изменений развернуты на сервере. Это удобно при использоватии инструментов автоматического деплоя, вроде Ansible.

Единственное уникальные данные для каждого сервера — подсеть IPv6, подписанная в конфигурационном файле OpenVPN.

На серверах используется Ubuntu 16.04 LTS с ядром 4.4.0.

Установка пакетов

В репозитории дистрибутива содержится устаревшая версия OpenVPN 2.3, поэтому добавляем официальные репозитории проекта с OpenVPN 2.4. Все остальные пакеты ставим из стандартной поставки.

Конфигурация OpenVPN

Так как все сервера настроены идентично, просто копируем конфиги вместе с файлами ключей и сертификатам в папку /etc/openvpn. Никакой генерации ключей/сертификатов не выполняется. Число процессов OpenVPN настраивает по числу ядер на сервере, в нашем случае 2. Каждый отдельный процесс имеет свой конфиг: zaborona1.conf и zaborona2.conf.

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


Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *