- PVSM.RU - https://www.pvsm.ru -
Месяц назад мы с друзьями сделали бесплатный сервис для обхода блокировок сайтов в Украине Zaborona.Help [1]. За это время сервис стал довольно популярным, аудитория выросла до 20 000 пользователей. Число одновременных подключений в пиковые часы — ≈6 000 клиентов.
Главная особенность нашего сервиса в том, что через VPN маршрутизируется трафик только к заблокированным сетям, остальные сайты работают напрямую. Это не влияет на скорость интернета и не подменяет IP-адрес для остальных сайтов.
В статье описываются тонкости настройки OpenVPN для большого числа клиентов, на дешевых
Наш опыт будет полезен для тех, кто собирается развернуть VPN для личных нужд, и тех, кто хочет создать сервис с большим числом клиентов.
Поначалу мы использовали несколько серверов в Европе у провайдеров Scaleway, Linode, DigitalOcean. Это были самые дешевые
Оказалось, что отечественных хостеров, сравнимых по уровню услуг с европейскими, не существует. Почти всегда это низкое качество услуг при высокой цене, сложная процедура заказа, устаревшие технологии. За время поиска мы успели сформировать список отличительных черт плохого
Попробовав несколько хостингов, мы почти отчаялись. Казалось, что в России просто не существует нормального
На наш запрос откликнулось около десятка компаний, но почти все из них имели признаки убогого
Это звучит странно, но я готов аргументированно доказать в комментариях, что 99% отечественных хостеров — фуфло, недотягивающее до уровня Европы. Особенно буду рад пообщаться с представителями крупных компаний, вроде МастерХост,
Настоящим открытием для нас стал
У них есть две линейки тарифов
Линейка тарифов Compute
Панель управления сравнима по удобству с DigitalOcean. Есть даже оплата через Bitcoin!
На текущий момент мы полностью переехали на площадку Veesp.com и используем шесть серверов Storage 1 для OpenVPN. Музыка в VK и Яндексе снова работает, пользователи довольны.
Я очень люблю IPv6. Он позволяет избавиться от кучи ненужных сущностей, вроде NAT и проброса портов. Для VPN он удобен тем, что каждый клиент ходит в интернет со своим реальным IP-адресом. К сожалению, многие
Самая распространенная ошибка — выдавать один IPv6-адрес на сервер.
Сайт slash64.net [7] посвященный этому заблуждению.
Чтобы выдавать клиентам VPN IPv6-адреса напрямую без костылей, нужно иметь отдельную маршрутизируемую сеть через IPv6-адрес на сервере, то есть подсеть, из которой планируется раздавать адреса клиентам, не должна быть назначена на интерфейс сервера, но должна маршрутизироваться через какой-либо адрес на сетевом интерфейсе сервера.
Существует два распространенных варианта раздачи маршрутизируемах сетей.
Первый вариант: одна /64 на сетевом интерфейсе, и /56, маршрутизируемая через первую /64. Вы можете побить /56 так, как вам хочется, либо же назначить всю /56 на интерфейс VPN.
Второй вариант: одна или несколько /64 (или больше), маршрутизирутизируемая через link-local-адрес.
У большинства хостеров выделенную сеть нужно заказывать отдельно. Veesp.com [10] выдает блок /56 на каждый сервер бесплатно. К сожалению, даже продвинутые хостеры, вроде DigitalOcean, не предоставляют такой услуги. Здесь есть список хостеров, предоставляющих данную услугу version6.ru/vps [11], от @rm.
На серверах забороны больше двух сотен правил iptables, по несколько на каждый диапазон из списка запрещенных в Украине сетей [12].
Сложный набор правил неудобно обслуживать стандартными средствами iptables-save
и iptables-restore
, потому что в случае изменения одного правила, необходимо будет редактировать сотни однотипных строк.
Ferm [13] — утилита для управления сложными правилами iptables со своим синтаксическим сахаром. Она позволяет создать удобочитаемую конфигурацию iptables, использовать переменные, массивы и циклы, но не ограничивает вас, в отличие от других надстроек над iptables: вы можете делать абсолютно все, использовать все возможности и модули netfilter.
Простой пример: мы хотим заблокировать входящие соединения из нескольких тысяч сетей на трех сетевых интерфейсах eth0, eth1, eth2. В обычном случае нужно было бы написать тысячи одинаковых правил для каждого интерфейса.
Вот как эта задача решается через ferm:
@def $WAN_0 = eth0;
@def $WAN_1 = eth1;
@def $WAN_2 = eth2;
@def $BLOCKED_NETWORKS = (
123.123.123.123
234.234.234.234
....
);
chain INPUT {
saddr $BLOCKED_NETWORKS of ($WAN_0 $WAN_1 $WAN_2) DROP;
}
В результате будет создано правило для каждого адреса из $BLOCKED_NETWORKS на каждый сетевой интерфейс. Такая запись легко читается и занимает в три раза меньше строк. Ее проще редактировать.
В нашем случае iptables выполняет три функции: NAT для IPv4-соединений, ограничение доступа в другие сети и балансировка нагрузки между процессами OpenVPN. Разберем каждую задачу подробно.
Клиентам выдается «серый» IP-адрес из диапазона 192.168.*.*, поэтому маршрутизировать его напрямую в интернет нельзя. Для того, чтобы выпустить клиентов в IPv4-интернет, нужно использовать преобразование сетевых адресов (NAT) [14].
Тем же самым занимается ваш домашний WiFi-роутер. На каждое исходящие соединение клиента создается трансляция в памяти сервера, которая хранит информацию о том, кому какое подключение принадлежит. Несмотря на то, что эта операция требует мало ресурсов сервера, при огромном количестве подключений (десятки тысяч), это может стать ресурсоемкой задачей для слабого сервера.
Этой проблемы нет в IPv6, так как каждому VPN-клиенту выдается реальный IP-адрес, который напрямую маршрутизируется в интернет. Серверу остается только перебрасывать пакеты с одного интерфейса на другой, без создания трансляций и хранения информации о каждом подключении.
Любой пользователь может добавить опцию redirect-gateway в конфиг OpenVPN и использовать наши сервера как маршрут по умолчанию. Нужно закрыть доступ ко всем сетям, кроме заблокированных в Украине
Архитектура OpenVPN однопоточная, поэтому один процесс демона OpenVPN использует только одно ядро процессора. Для лучшей утилизации всех ядер процессора, число процессов должно равняться количеству ядер на сервере. Балансировка между процессами выполняется с помощью модуля statistic, который случайном образом перенаправляет входящие подключения на разные внутренние порты.
Мы используем самый простой способ балансировки — с помощью множественных А-записей DNS. Все клиенты подключаются к серверу через доменное имя vpn.zaborona.help. Этот домен имеет шесть А-записей, которые направлены на все сервера. В итоге, в момент подключения, клиент выбирает случайный сервер из доступных. Так общее число подключений равномерно распределяется между всеми серверами. Конфигурация OpenVPN на всех серверах идентична, за исключением диапазонов IPv6-адресов, выдаваемых клиентам.
Панель управления DNS-записями. Балансировка с помощью множественых А-записей. Малое значение TTL позволяет быстро удалять адреса из общего списка.
Можно быстро посмотреть, на какие IP-адреса резолвится домен из разных точек планеты, с помощью сервиса host-tracker.com [15], выбрав любой из тестов, например http или ping.
Результат для домена vpn.zaborona.help: www.host-tracker.com/InstantCheck/ResultComplete/ec0e5a90-ed56-e711-b124-0003ff7328cc [16]
Многие украинские провайдеры блокируют DNS-запросы к запрещенным доменам, перехватывая запросы в том числе и к сторонним DNS-серверам, вроде 8.8.8.8. Поэтому важно, чтобы клиенты посылали DNS-запросы через VPN тоннель, где их не сможет модифицировать провайдер.
Это не так просто сделать, потому что в новых версиях Windows запросы могут уходить ко всем DNS-серверам в системе, и будет использоваться тот, который ответит быстрее. DNS-сервер провайдера находится физически ближе к клиенту, поэтому, с большой вероятностью, система быстрее получит подмененный ответ провайдера, а не корректный ответ DNS внутри VPN, и сайт останется заблокирован.
Для решения этой проблемы ValdikSS [17] написал патч для OpenVPN, блокирующий утечки DNS в Windows [18]. Он использует Windows Filtering Platform — специальный слой файрволла Windows, позволяющий блокировать запросы к сторонним DNS, пока запущен OpenVPN.
В комментариях к предыдущей статье меня упрекали в том, что некоторые этапы, которые мне казались очевидными, не описаны. Здесь я опишу полный набор команд для разворачивания сервера забороны.
Конфиги максимально унифицированы и могут быть без изменений развернуты на сервере. Это удобно при использоватии инструментов автоматического деплоя, вроде Ansible.
Единственное уникальные данные для каждого сервера — подсеть IPv6, подписанная в конфигурационном файле OpenVPN.
На серверах используется Ubuntu 16.04 LTS с ядром 4.4.0.
В репозитории дистрибутива содержится устаревшая версия OpenVPN 2.3, поэтому добавляем официальные репозитории проекта с OpenVPN 2.4. Все остальные пакеты ставим из стандартной поставки.
wget -O - https://swupdate.openvpn.net/repos/repo-public.gpg|apt-key add -
echo "deb http://build.openvpn.net/debian/openvpn/release/2.4 xenial main" > /etc/apt/sources.list.d/openvpn-aptrepo.list
apt update
apt upgrade
apt install openvpn dnsmasq ferm
Так как все сервера настроены идентично, просто копируем конфиги вместе с файлами ключей и сертификатам в папку /etc/openvpn. Никакой генерации ключей/сертификатов не выполняется. Число процессов OpenVPN настраивает по числу ядер на сервере, в нашем случае 2. Каждый отдельный процесс имеет свой конфиг: zaborona1.conf и zaborona2.conf.
Чтобы избежать путаницы, я буду называть процессы OpenVPN демонами, но сути это несколько отдельных серверов, запущенных внутри одного
Список файлов в /etc/openvpn
/etc/openvpn/zaborona1.conf # конфиг первого демона
/etc/openvpn/zaborona2.conf # конфиг второго демона
/etc/openvpn/ccd/DEFAULT # файл с изменяемым на лету настройками для первого демона
/etc/openvpn/ccd2/DEFAULT # файл с изменяемым на лету настройками для второго демона
/etc/openvpn/logs # папка с логами
/etc/openvpn/ca.crt # корневой сертификат
/etc/openvpn/zaborona.help.crt # сертификат сервера
/etc/openvpn/zaborona.help.key # ключ сервера
/etc/openvpn/dh2048.pem # файл с Diffie-Hellman группами (необходим для шифрования)
Содержимое файлов:
mode server
# Несмотря на то, что протокол UDP быстрее, мы используем TCP для экономии трафика и аккумулятора мобильных уcтройств, так как в режиме UDP клиент вынужден чаще посылать keep-alive пакеты, чтобы поддерживать NAT-трансляцию на роутере или CGNAT.
proto tcp
# Тип инкапсуляции L3, то есть ip уровень. Нам не нужен L2 уровень.
dev-type tun
# Имя tun-интерфейса на сервере
dev zaborona1
# Раздавать клиенту адреса из общей /24, а не резать на подсети /30.
topology subnet
# Диапазон "серых" ipv4-адресов, выдаваемых клиентам.
server 192.168.224.0 255.255.252.0
# Диапазон реальных ipv6-адресов, выдаваемых клиентам. Уникален для каждого сервера.
server-ipv6 2a00:1838:32:200::/112
txqueuelen 250
keepalive 300 900
persist-tun
persist-key
cipher AES-128-CBC
ncp-ciphers AES-128-GCM
#user nobody
duplicate-cn
log logs/zaborona1.log
status logs/status1.log 30
# Путь к папке с конфигами пользователей. Эта опция позволяет назначить индивидуальные опции для каждого пользователя. Файл перечитывается заново при каждом подключении клиента, поэтому изменения можно выполнять без перезапуска сервера.
client-config-dir ccd
ca ca.crt
cert zaborona.help.crt
key zaborona.help.key
dh dh2048.pem
mode server
port 1195
proto tcp
dev-type tun
dev zaborona2
topology subnet
server 192.168.228.0 255.255.252.0
server-ipv6 2a00:1838:32:280::/112
txqueuelen 250
keepalive 300 900
persist-tun
persist-key
cipher AES-128-CBC
ncp-ciphers AES-128-GCM
#user nobody
duplicate-cn
log logs/zaborona2.log
status logs/status2.log 30
client-config-dir ccd2
ca ca.crt
cert zaborona.help.crt
key zaborona.help.key
dh dh2048.pem
push "dhcp-option DNS 192.168.224.1"
push "dhcp-option DNS 74.82.42.42" # HE.net DNS
push "route 74.82.42.42" # Route to HE.net DNS
push "route 77.88.8.8" # Route to Yandex DNS
push "dhcp-option DNS6 2001:4860:4860::8888" # Google IPv6 dns
push "route-ipv6 2001:4860:4860::8888"
push "dhcp-option DNS6 2001:4860:4860::8844" # Google IPv6 dns
push "route-ipv6 2001:4860:4860::8844"
#Persist TUN
push "persist-tun"
# Routes
# Yandex network
push "route 5.45.192.0 255.255.192.0"
push "route 5.255.192.0 255.255.192.0"
push "route 37.9.64.0 255.255.192.0"
push "route 37.140.128.0 255.255.192.0"
push "route 77.75.152.0 255.255.248.0"
push "route 77.88.0.0 255.255.192.0"
push "route 84.201.128.0 255.255.192.0"
push "route 87.250.224.0 255.255.224.0"
push "route 93.158.128.0 255.255.192.0"
push "route 95.108.128.0 255.255.128.0"
push "route 100.43.64.0 255.255.224.0"
push "route 109.235.160.0 255.255.248.0"
push "route 130.193.32.0 255.255.224.0"
push "route 141.8.128.0 255.255.192.0"
push "route 178.154.128.0 255.255.128.0"
push "route 185.32.185.0 255.255.255.0"
push "route 185.32.186.0 255.255.255.0"
push "route 185.71.76.0 255.255.252.0"
push "route 199.21.96.0 255.255.252.0"
push "route 199.36.240.0 255.255.252.0"
push "route 213.180.192.0 255.255.224.0"
push "route-ipv6 2001:678:384::/48"
push "route-ipv6 2620:10f:d000::/44"
push "route-ipv6 2a02:6b8::/32"
push "route-ipv6 2a02:5180::/32"
# Mail.ru network
push "route 5.61.16.0 255.255.248.0"
push "route 5.61.232.0 255.255.248.0"
push "route 79.137.157.0 255.255.255.0"
push "route 79.137.183.0 255.255.255.0"
push "route 94.100.176.0 255.255.240.0"
push "route 95.163.32.0 255.255.224.0"
push "route 95.163.248.0 255.255.248.0"
push "route 128.140.168.0 255.255.248.0"
push "route 178.22.88.0 255.255.248.0"
push "route 178.237.16.0 255.255.240.0"
push "route 185.5.136.0 255.255.252.0"
push "route 185.16.148.0 255.255.252.0"
push "route 185.16.244.0 255.255.252.0"
push "route 188.93.56.0 255.255.248.0"
push "route 194.186.63.0 255.255.255.0"
push "route 195.211.20.0 255.255.252.0"
push "route 195.211.128.0 255.255.252.0"
push "route 195.218.168.0 255.255.255.0"
push "route 208.87.92.0 255.255.252.0"
push "route 217.20.144.0 255.255.240.0"
push "route 217.69.128.0 255.255.240.0"
push "route 185.6.244.0 255.255.252.0"
push "route 185.30.176.0 255.255.252.0"
push "route 195.218.190.0 255.255.254.0"
push "route-ipv6 2a00:1148::/32"
push "route-ipv6 2a00:a300::/32"
push "route-ipv6 2a00:b4c0::/32"
push "route-ipv6 2a04:4b40::/29"
# VK.com network
push "route 87.240.128.0 255.255.192.0"
push "route 93.186.224.0 255.255.240.0"
push "route 95.142.192.0 255.255.240.0"
push "route 95.213.0.0 255.255.192.0"
push "route 185.29.130.0 255.255.255.0"
push "route 185.32.248.0 255.255.252.0"
# Kaspersky network
push "route 77.74.176.0 255.255.252.0"
push "route 77.74.181.0 255.255.255.0"
push "route 77.74.183.0 255.255.255.0"
push "route 93.159.228.0 255.255.252.0"
push "route 185.54.220.0 255.255.254.0"
push "route 185.85.12.0 255.255.255.0"
push "route 185.85.14.0 255.255.254.0"
push "route 77.74.176.0 255.255.248.0"
push "route 91.103.64.0 255.255.248.0"
push "route 93.159.224.0 255.255.248.0"
push "route-ipv6 2a03:2480::/33"
# DrWeb
push "route 178.248.232.183 255.255.255.255"
push "route 178.248.233.94 255.255.255.255"
push "route 195.88.252.0 255.255.254.0"
push "dhcp-option DNS 192.168.228.1"
push "dhcp-option DNS 74.82.42.42" # HE.net DNS
push "route 74.82.42.42" # Route to HE.net DNS
push "route 77.88.8.8" # Route to Yandex DNS
push "dhcp-option DNS6 2001:4860:4860::8888" # Google ipv6 dns
push "route-ipv6 2001:4860:4860::8888"
push "dhcp-option DNS6 2001:4860:4860::8844" # Google ipv6 dns
push "route-ipv6 2001:4860:4860::8844"
#Persist TUN
push "persist-tun"
# Routes
# Yandex network
push "route 5.45.192.0 255.255.192.0"
push "route 5.255.192.0 255.255.192.0"
push "route 37.9.64.0 255.255.192.0"
push "route 37.140.128.0 255.255.192.0"
push "route 77.75.152.0 255.255.248.0"
push "route 77.88.0.0 255.255.192.0"
push "route 84.201.128.0 255.255.192.0"
push "route 87.250.224.0 255.255.224.0"
push "route 93.158.128.0 255.255.192.0"
push "route 95.108.128.0 255.255.128.0"
push "route 100.43.64.0 255.255.224.0"
push "route 109.235.160.0 255.255.248.0"
push "route 130.193.32.0 255.255.224.0"
push "route 141.8.128.0 255.255.192.0"
push "route 178.154.128.0 255.255.128.0"
push "route 185.32.185.0 255.255.255.0"
push "route 185.32.186.0 255.255.255.0"
push "route 185.71.76.0 255.255.252.0"
push "route 199.21.96.0 255.255.252.0"
push "route 199.36.240.0 255.255.252.0"
push "route 213.180.192.0 255.255.224.0"
push "route-ipv6 2001:678:384::/48"
push "route-ipv6 2620:10f:d000::/44"
push "route-ipv6 2a02:6b8::/32"
push "route-ipv6 2a02:5180::/32"
# Mail.ru network
push "route 5.61.16.0 255.255.248.0"
push "route 5.61.232.0 255.255.248.0"
push "route 79.137.157.0 255.255.255.0"
push "route 79.137.183.0 255.255.255.0"
push "route 94.100.176.0 255.255.240.0"
push "route 95.163.32.0 255.255.224.0"
push "route 95.163.248.0 255.255.248.0"
push "route 128.140.168.0 255.255.248.0"
push "route 178.22.88.0 255.255.248.0"
push "route 178.237.16.0 255.255.240.0"
push "route 185.5.136.0 255.255.252.0"
push "route 185.16.148.0 255.255.252.0"
push "route 185.16.244.0 255.255.252.0"
push "route 188.93.56.0 255.255.248.0"
push "route 194.186.63.0 255.255.255.0"
push "route 195.211.20.0 255.255.252.0"
push "route 195.211.128.0 255.255.252.0"
push "route 195.218.168.0 255.255.255.0"
push "route 208.87.92.0 255.255.252.0"
push "route 217.20.144.0 255.255.240.0"
push "route 217.69.128.0 255.255.240.0"
push "route 185.6.244.0 255.255.252.0"
push "route 185.30.176.0 255.255.252.0"
push "route 195.218.190.0 255.255.254.0"
push "route-ipv6 2a00:1148::/32"
push "route-ipv6 2a00:a300::/32"
push "route-ipv6 2a00:b4c0::/32"
push "route-ipv6 2a04:4b40::/29"
# VK.com network
push "route 87.240.128.0 255.255.192.0"
push "route 93.186.224.0 255.255.240.0"
push "route 95.142.192.0 255.255.240.0"
push "route 95.213.0.0 255.255.192.0"
push "route 185.29.130.0 255.255.255.0"
push "route 185.32.248.0 255.255.252.0"
# Kaspersky network
push "route 77.74.176.0 255.255.252.0"
push "route 77.74.181.0 255.255.255.0"
push "route 77.74.183.0 255.255.255.0"
push "route 93.159.228.0 255.255.252.0"
push "route 185.54.220.0 255.255.254.0"
push "route 185.85.12.0 255.255.255.0"
push "route 185.85.14.0 255.255.254.0"
push "route 77.74.176.0 255.255.248.0"
push "route 91.103.64.0 255.255.248.0"
push "route 93.159.224.0 255.255.248.0"
push "route-ipv6 2a03:2480::/33"
# DrWeb
push "route 178.248.232.183 255.255.255.255"
push "route 178.248.233.94 255.255.255.255"
push "route 195.88.252.0 255.255.254.0"
Конфиги разных демонов отличаются только номером порта для входящих соединений и диапазоном IP-адресов, выдаваемых клиентам.
Первое время мы постоянно реадктировали список заблокированных сетей, из-за этого приходилось перезапускать демоны OpenVPN каждый раз при изменении конфигов. Из-за этого у клиентов разрывалось подключение к серверу.
Решением этой проблемы стала опция client-config-dir. Она используется для того, чтобы назначит индивидуальные настройки поименно каждому пользователю. Так как у нас все пользователи подключаются от имени одного клиента public, то файл один на всех <b>ccd/DEFAULT. Хитрость в том, что файл перечитывается заново при каждом подключении клиента и не требует перезапуска сервера для применения настроек.
В результате мы можем редактировать настройки сервера без отключения клиентов. и для преминения новых настроек пользователю достаточно переподключиться к серверу. Так как пользователи рано или поздно в любом случае перподключаются, новые настройки со временем применяются всем клиентам.
Настройки фаерволла идентичны на всех серверах, поэтому копируем файл /etc/ferm/ferm.conf без изменений. По-умолчанию, после установки, пакет ferm сразу активирует стандартный набор правил в котором запрещены все соединения, кроме SSH на 22 порту. Так что если у вас SSH сервер находится на другом порту, будьте аккуратны, чтобы не заблокировать себя.
# Имена tun-интерфейсов из конфига OpenVPN. zaborona1, zaborona2 можно заменить на zaborona+.
@def $VPN = (
zaborona+
);
# Интерфейсы сервера, смотрящие в интернет
@def $WAN_4 = eth0;
@def $WAN_6 = eth0;
# Диапазоны "серых" адресов, выдаваемых клиентам
@def $VPN_ADDR_4 = (
192.168.224.0/22
192.168.228.0/22
);
@def $ALLOW_SSH = (
Список адресов, с которых разрешено подключение по SSH
);
@def $ALLOWED_NETWORKS_V4 = (
Список ipv4-сетей, заблокированных в Украине
);
@def $ALLOWED_NETWORKS_V6 = (
Список ipv6-сетей, заблокированных в Украине
);
table filter {
chain ZABORONA_V4 {
daddr $ALLOWED_NETWORKS_V4 ACCEPT;
}
chain FORWARD {
policy DROP;
mod conntrack ctstate INVALID DROP;
if $WAN_4 of $VPN mod conntrack ctstate (ESTABLISHED RELATED) ACCEPT;
if $VPN of $WAN_4 jump ZABORONA_V4;
}
chain INPUT {
saddr $ALLOW_SSH protocol tcp dport 22 ACCEPT;
protocol tcp dport 22 REJECT reject-with icmp-port-unreachable;
}
}
table nat {
chain POSTROUTING {
saddr $VPN_ADDR_4 of $WAN_4 MASQUERADE;
}
# Балансировка меджду демонами OpenVPN
chain PREROUTING {
interface $WAN_4 protocol tcp dport 1194 mod conntrack ctstate NEW mod statistic mode random probability 0.50000000000 REDIRECT to-ports 1195;
}
}
# IPv6:
domain ip6 {
table filter {
chain ZABORONA_V6 {
daddr $ALLOWED_NETWORKS_V6 ACCEPT;
}
chain FORWARD {
policy DROP;
mod conntrack ctstate INVALID DROP;
if $WAN_6 of $VPN mod conntrack ctstate (ESTABLISHED RELATED) ACCEPT;
if $VPN of $WAN_6 jump ZABORONA_V6;
}
}
}
Для сравнения, вот как выглядит тот же набор правил, полученный через iptables-save:
# Generated by iptables-save v1.6.0 on Fri Jun 23 19:44:10 2017
*filter
:INPUT ACCEPT [54622:15244109]
:FORWARD DROP [50:2520]
:OUTPUT ACCEPT [59291:85277655]
:ZABORONA_V4 - [0:0]
-A INPUT -s 1.2.3.4/32 -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -m conntrack --ctstate INVALID -j DROP
-A FORWARD -i eth0 -o zaborona+ -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i zaborona+ -o eth0 -j ZABORONA_V4
-A ZABORONA_V4 -d 87.240.128.0/18 -j ACCEPT
-A ZABORONA_V4 -d 93.186.224.0/20 -j ACCEPT
-A ZABORONA_V4 -d 95.142.192.0/20 -j ACCEPT
-A ZABORONA_V4 -d 95.213.0.0/18 -j ACCEPT
-A ZABORONA_V4 -d 185.29.130.0/24 -j ACCEPT
-A ZABORONA_V4 -d 185.32.248.0/22 -j ACCEPT
-A ZABORONA_V4 -d 5.45.192.0/18 -j ACCEPT
-A ZABORONA_V4 -d 5.255.192.0/18 -j ACCEPT
-A ZABORONA_V4 -d 37.9.64.0/18 -j ACCEPT
-A ZABORONA_V4 -d 37.140.128.0/18 -j ACCEPT
-A ZABORONA_V4 -d 77.75.152.0/21 -j ACCEPT
-A ZABORONA_V4 -d 77.88.0.0/18 -j ACCEPT
-A ZABORONA_V4 -d 84.201.128.0/18 -j ACCEPT
-A ZABORONA_V4 -d 87.250.224.0/19 -j ACCEPT
-A ZABORONA_V4 -d 93.158.128.0/18 -j ACCEPT
-A ZABORONA_V4 -d 95.108.128.0/17 -j ACCEPT
-A ZABORONA_V4 -d 100.43.64.0/19 -j ACCEPT
-A ZABORONA_V4 -d 109.235.160.0/21 -j ACCEPT
-A ZABORONA_V4 -d 130.193.32.0/19 -j ACCEPT
-A ZABORONA_V4 -d 141.8.128.0/18 -j ACCEPT
-A ZABORONA_V4 -d 178.154.128.0/17 -j ACCEPT
-A ZABORONA_V4 -d 185.32.185.0/24 -j ACCEPT
-A ZABORONA_V4 -d 185.32.186.0/24 -j ACCEPT
-A ZABORONA_V4 -d 185.71.76.0/22 -j ACCEPT
-A ZABORONA_V4 -d 199.21.96.0/22 -j ACCEPT
-A ZABORONA_V4 -d 199.36.240.0/22 -j ACCEPT
-A ZABORONA_V4 -d 213.180.192.0/19 -j ACCEPT
-A ZABORONA_V4 -d 5.61.16.0/21 -j ACCEPT
-A ZABORONA_V4 -d 5.61.232.0/21 -j ACCEPT
-A ZABORONA_V4 -d 79.137.157.0/24 -j ACCEPT
-A ZABORONA_V4 -d 79.137.183.0/24 -j ACCEPT
-A ZABORONA_V4 -d 94.100.176.0/20 -j ACCEPT
-A ZABORONA_V4 -d 95.163.32.0/19 -j ACCEPT
-A ZABORONA_V4 -d 95.163.248.0/21 -j ACCEPT
-A ZABORONA_V4 -d 128.140.168.0/21 -j ACCEPT
-A ZABORONA_V4 -d 178.22.88.0/21 -j ACCEPT
-A ZABORONA_V4 -d 178.237.16.0/20 -j ACCEPT
-A ZABORONA_V4 -d 185.5.136.0/22 -j ACCEPT
-A ZABORONA_V4 -d 185.16.148.0/22 -j ACCEPT
-A ZABORONA_V4 -d 185.16.244.0/22 -j ACCEPT
-A ZABORONA_V4 -d 188.93.56.0/21 -j ACCEPT
-A ZABORONA_V4 -d 194.186.63.0/24 -j ACCEPT
-A ZABORONA_V4 -d 195.211.20.0/22 -j ACCEPT
-A ZABORONA_V4 -d 195.218.168.0/24 -j ACCEPT
-A ZABORONA_V4 -d 217.20.144.0/20 -j ACCEPT
-A ZABORONA_V4 -d 217.69.128.0/20 -j ACCEPT
-A ZABORONA_V4 -d 195.211.128.0/22 -j ACCEPT
-A ZABORONA_V4 -d 208.87.92.0/22 -j ACCEPT
-A ZABORONA_V4 -d 77.74.176.0/22 -j ACCEPT
-A ZABORONA_V4 -d 77.74.181.0/24 -j ACCEPT
-A ZABORONA_V4 -d 77.74.183.0/24 -j ACCEPT
-A ZABORONA_V4 -d 93.159.228.0/22 -j ACCEPT
-A ZABORONA_V4 -d 185.54.220.0/23 -j ACCEPT
-A ZABORONA_V4 -d 185.85.12.0/24 -j ACCEPT
-A ZABORONA_V4 -d 185.85.14.0/23 -j ACCEPT
-A ZABORONA_V4 -d 77.74.176.0/21 -j ACCEPT
-A ZABORONA_V4 -d 91.103.64.0/21 -j ACCEPT
-A ZABORONA_V4 -d 93.159.224.0/21 -j ACCEPT
-A ZABORONA_V4 -d 8.8.8.8/32 -j ACCEPT
-A ZABORONA_V4 -d 8.8.4.4/32 -j ACCEPT
-A ZABORONA_V4 -d 74.82.42.42/32 -j ACCEPT
-A ZABORONA_V4 -d 77.75.152.0/21 -j ACCEPT
-A ZABORONA_V4 -d 185.71.72.0/21 -j ACCEPT
-A ZABORONA_V4 -d 185.6.244.0/22 -j ACCEPT
-A ZABORONA_V4 -d 185.30.176.0/22 -j ACCEPT
-A ZABORONA_V4 -d 195.218.190.0/23 -j ACCEPT
-A ZABORONA_V4 -d 195.88.252.0/23 -j ACCEPT
-A ZABORONA_V4 -d 178.248.232.183/32 -j ACCEPT
-A ZABORONA_V4 -d 178.248.233.94/32 -j ACCEPT
COMMIT
# Completed on Fri Jun 23 19:44:10 2017
# Generated by iptables-save v1.6.0 on Fri Jun 23 19:44:10 2017
*nat
:PREROUTING ACCEPT [917:61256]
:INPUT ACCEPT [430:26400]
:OUTPUT ACCEPT [122:8320]
:POSTROUTING ACCEPT [122:8320]
-A PREROUTING -i eth0 -p tcp -m tcp --dport 1194 -m conntrack --ctstate NEW -m statistic --mode random --probability 0.50000000000 -j REDIRECT --to-ports 1195
-A POSTROUTING -s 192.168.224.0/22 -o eth0 -j MASQUERADE
-A POSTROUTING -s 192.168.228.0/22 -o eth0 -j MASQUERADE
COMMIT
# Completed on Fri Jun 23 19:44:10 2017
Балансировку между демонами выполняет это правило
-A PREROUTING -i eth0 -p tcp -m tcp --dport 1194 -m conntrack --ctstate NEW -m statistic --mode random --probability 0.50000000000 -j REDIRECT --to-ports 1195
С 50% вероятностью подключения к порту 1194 перенаправляются на порт 1195. Так, подключения равномерно распределяются между двумя процессами OpenVPN. Если бы процессов было больше, нужно было бы добавить дополнительные правила на каждый процесс и изменить вероятность срабатывания каждого правила.
По-умолчанию dnsmasq принимает запросы только с локального интерфейса 127.0.0.1, поэтому разрешаем запросы с адресов VPN клиентов и устанавливаем размер DNS-кеша.
/etc/dnsmasq.d/zaborona
listen-address=127.0.0.1,192.168.224.1,192.168.228.1
cache-size=1000
Файл systctl.conf настройки ядра. В нем включаем форвардинг IP-пакетов и другие опции.
Что еще важного тут сказать?
# Включаем форвардинг ipv4 и ipv6 пакетов
net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1
net.netfilter.nf_conntrack_max=65535
net.netfilter.nf_conntrack_generic_timeout = 600
net.netfilter.nf_conntrack_icmp_timeout = 30
net.netfilter.nf_conntrack_tcp_timeout_close = 10
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60
net.netfilter.nf_conntrack_tcp_timeout_established = 1800
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_last_ack = 30
net.netfilter.nf_conntrack_tcp_timeout_max_retrans = 300
net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 60
net.netfilter.nf_conntrack_tcp_timeout_syn_sent = 120
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_unacknowledged = 300
net.netfilter.nf_conntrack_udp_timeout = 60
net.netfilter.nf_conntrack_udp_timeout_stream = 180
net.ipv4.tcp_slow_start_after_idle = 0
net.ipv4.tcp_fastopen = 3
net.ipv4.tcp_rmem = 4096 262143 4194304
net.core.rmem_max = 4194304
net.core.rmem_default = 262143
net.ipv4.tcp_wmem = 4096 262143 4194304
net.core.wmem_max = 4194304
net.core.wmem_default = 262143
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 90
net.ipv4.tcp_keepalive_probes = 5
net.ipv4.tcp_congestion_control=bbr
net.ipv6.conf.default.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0
net.ipv6.conf.default.accept_source_route = 0
net.ipv6.conf.all.use_tempaddr = 2
После того, как все сервисы настроены, можно добавить их старт в автозагрузку.
Предварительно увеличиваем лимит на число открытых файловых дескрипторов для процессов OpenVPN, иначе при большом числе клиентов мы их превысим и получим ошибку Too many open files из-за большого числа открытых сокетов.
systemctl edit openvpn@.service
[Service]
LimitNOFILE=8192
# Перечитываем стартовые скрипты, чтобы изменения вступили в силу.
systemctl daemon-reload
# Добавляем в автозагрузку и сразу стартуем оба процесса OpenVPN.
systemctl enable --now openvpn@zaborona1
systemctl enable --now openvpn@zaborona2
# Перезапускаем сервисы dnsmasq и ferm. Они добавлены в автозагрузку по умолчанию после установки.
systemctl restart dnsmasq
systemctl restart ferm
Для проверки корректности настроек, можно перезагрузить сервер и убедиться что все сервисы запущены.
Автор: zhovner
Источник [19]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/openvpn/258639
Ссылки в тексте:
[1] Zaborona.Help: https://zaborona.help
[2] VPS: https://www.reg.ru/?rlink=reflink-717
[3] NDP-прокси: https://github.com/DanielAdolfsson/ndppd
[4] Veesp.com: https://veesp.com/
[5] «Storage 1»: https://veesp.com/ru/products/storage-vps
[6] «Compute»: https://veesp.com/en/products/vps
[7] slash64.net: http://slash64.net/
[8] RFC 6177: https://tools.ietf.org/html/rfc6177#section-5
[9] SLAAC: https://en.wikipedia.org/wiki/IPv6#Stateless_address_autoconfiguration_.28SLAAC.29
[10] Veesp.com: https://Veesp.com
[11] version6.ru/vps: https://version6.ru/vps
[12] из списка запрещенных в Украине сетей: https://zaborona.help/ips.txt
[13] Ferm: http://ferm.foo-projects.org/
[14] преобразование сетевых адресов (NAT): https://ru.wikipedia.org/wiki/NAT
[15] host-tracker.com: https://www.host-tracker.com/
[16] www.host-tracker.com/InstantCheck/ResultComplete/ec0e5a90-ed56-e711-b124-0003ff7328cc: https://www.host-tracker.com/InstantCheck/ResultComplete/ec0e5a90-ed56-e711-b124-0003ff7328cc
[17] ValdikSS: https://habrahabr.ru/users/valdikss/
[18] патч для OpenVPN, блокирующий утечки DNS в Windows: https://habrahabr.ru/post/268173/
[19] Источник: https://habrahabr.ru/post/331178/
Нажмите здесь для печати.