Зачем нужен каскад из двух серверов
Обычный VPN на единственном зарубежном сервере решает задачу обхода блокировок, но создаёт новую проблему: российские сайты и сервисы начинают видеть иностранный IP-адрес. Многие банки, государственные порталы и стриминговые платформы либо блокируют такие подключения, либо открываются с ошибками. Каскад AmneziaWG — это схема, в которой участвуют два сервера: один расположен в России или рядом, второй — за границей. Клиент подключается к «входному» серверу, а тот уже сам решает, куда направить каждый пакет: российские адреса уходят в интернет напрямую, всё остальное — через туннель на зарубежный «выходной» сервер.
Главное преимущество такого подхода — вся логика разделения живёт на сервере, а не на клиенте. Пользователю не нужно настраивать списки маршрутов, включать сплит-туннелинг или менять конфигурацию при смене сети. Достаточно один раз подключиться к входному серверу, и трафик будет распределяться автоматически. Это особенно удобно, когда VPN используют несколько человек или устройств: администратор один раз настраивает сервер, и все клиенты получают одинаковое поведение.
Каскад также решает проблему «лишнего крюка»: без него даже запрос к российскому сайту уходит за границу и возвращается обратно, увеличивая задержку и создавая лишнюю нагрузку на зарубежный канал. С каскадом российский трафик идёт по короткому пути, а зарубежный — через второй сервер, что в сумме даёт более стабильную и быструю работу.
Важно понимать, что каскад — это не панацея и не универсальное решение. Он оправдан, когда нужно разделять трафик для многих клиентов централизованно. Если разделение нужно только одному человеку, проще настроить AllowedIPs на клиенте. Но для семьи, небольшой команды или собственной инфраструктуры каскад — это элегантный и гибкий инструмент.
Как работает разделение трафика в каскаде
Механика каскада основана на серверном сплит-туннелинге. Входной сервер анализирует IP-адрес назначения каждого пакета, поступающего от клиентов. Для этого используется список российских сетей, который загружается из открытой зоны ipdeny и помещается в ipset — специальную структуру ядра Linux для быстрой проверки принадлежности IP-адреса к набору.
Алгоритм прост:
- Пакет от клиента приходит на входной сервер через туннель awg0.
- Если адрес назначения есть в списке российских сетей, пакет отправляется в интернет напрямую с входного сервера.
- Если адрес не российский, пакет помечается меткой (fwmark) и направляется через второй туннель (awg1) на выходной сервер.
- Выходной сервер, в свою очередь, отправляет пакет в интернет со своего IP-адреса.
Такая схема позволяет клиенту иметь одно подключение, а серверу — гибко управлять маршрутизацией. Список российских сетей обновляется, поэтому со временем могут появляться новые подсети, и скрипт маршрутизации должен уметь их подхватывать.
Ключевой момент — порядок правил iptables. Сначала проверяется принадлежность к российским сетям (RETURN), и только потом всё остальное помечается (MARK). Если порядок нарушить, весь трафик уйдёт за границу, и каскад перестанет выполнять свою функцию.
Отдельно стоит сказать о DNS. По умолчанию клиентский DNS (например, Cloudflare) имеет зарубежные адреса, поэтому DNS-запросы уходят через выходной сервер. Это нормально и не влияет на разделение: после получения IP-адреса российского сайта трафик к нему пойдёт напрямую. При диагностике не стоит пугаться, что DNS-запросы идут через заграницу.
Что нужно для сборки каскада
Для каскада понадобятся два VPS-сервера с чистой операционной системой — Debian 12/13 или Ubuntu 24.04/25.10. Оба должны иметь root-доступ и реальный публичный IP-адрес. Это принципиально: если сервер находится за CGNAT (провайдерским NAT), он недоступен снаружи, и каскад не заработает. Проверить это просто: адрес, который возвращает curl -s ifconfig.me, должен совпадать с адресом на сетевом интерфейсе (ip -4 addr).
Роли серверов:
- Вход — сервер в России или рядом. К нему подключаются клиенты, и именно с него российские сайты открываются напрямую. Важно, чтобы он имел низкую задержку до российских ресурсов.
- Выход — обычный зарубежный VPS. Через него уходит весь остальной трафик.
Желательно, чтобы подсети серверов различались. Например, у входа — 172.16.17.1/24, у выхода — 172.16.61.1/24. Это стандартная практика для WireGuard-подобных туннелей, она позволяет избежать конфликтов маршрутизации.
Также важно отключить IPv6 на обоих серверах. Установщик AmneziaWG делает это по умолчанию, но если вы настраиваете вручную, убедитесь, что IPv6 выключен. Каскад работает по IPv4, и если IPv6 останется включённым, часть трафика пойдёт в обход разделения, что сведёт на нет всю схему.
Отдельный случай — серверы Hetzner. У них публичный IP часто выдаётся как /32, а шлюз по умолчанию лежит вне подсети сервера. Это приводит к ошибке «Nexthop has invalid gateway» при добавлении маршрута. Решение — использовать флаг onlink при добавлении маршрута. Современные версии скрипта маршрутизации делают это автоматически, но при ручной настройке нужно помнить об этом нюансе.
Пошаговая настройка: установка AmneziaWG на оба сервера
Первый шаг — установка AmneziaWG на оба сервера. Для этого используется установщик amneziawg-installer, который разворачивает AmneziaWG 2.0 с обфускацией и сразу настраивает файрвол. Установка происходит неинтерактивно, с указанием нужной подсети.
На сервере-выходе (за границей):
bash install_amneziawg.sh --yes --disallow-ipv6 --route-all --subnet=172.16.61.1/24На сервере-входе (в России):
bash install_amneziawg.sh --yes --disallow-ipv6 --route-all --subnet=172.16.17.1/24Установщик сам поднимает пересылку пакетов и NAT, поэтому серверные конфиги дальше править не нужно. На входном сервере дополнительно нужно установить пакеты curl и ipset, которые могут отсутствовать в минимальном образе:
apt update && apt install -y curl ipsetПосле установки на обоих серверах будут созданы туннели awg0 (для клиентов) и файлы управления в /root/awg/. Важно, чтобы оба сервера имели доступ к интернету и могли обмениваться пакетами по UDP.
Создание туннеля между серверами
Следующий шаг — соединить два сервера туннелем. Для этого на выходном сервере создаётся клиентский конфиг для входного сервера. Это делается командой:
bash /root/awg/manage_amneziawg.sh add ru_hostВ результате появится файл /root/awg/ru_host.conf. Его нужно скопировать на входной сервер, например, через scp. Внутри файла — обычный клиентский конфиг с Endpoint (внешний IP выходного сервера) и AllowedIPs = 0.0.0.0/0.
На входном сервере этот конфиг сохраняется как /etc/amnezia/amneziawg/awg1.conf. Затем вносятся два изменения:
- В секцию
[Interface]добавляетсяTable = off, чтобы awg-quick не прописывал маршруты самостоятельно — этим займётся скрипт маршрутизации. - Строка
DNS = ...удаляется, так как на сервере DNS не нужен.
После этого нужно установить права и запустить туннель:
chmod 600 /etc/amnezia/amneziawg/awg1.conf
systemctl start awg-quick@awg1
awg show awg1В выводе awg show awg1 должна появиться строка latest handshake — это означает, что связь с выходным сервером установлена. Пинг внутреннего адреса выходного сервера на этом этапе может не проходить, и это нормально: маршрут к нему появится позже, в отдельной таблице маршрутизации.
Скрипт маршрутизации: сердце каскада
Вся логика разделения трафика реализована в одном bash-скрипте на входном сервере, обычно /root/awg/awg-routing.sh. Скрипт идемпотентный — его можно запускать повторно, и он при каждом запуске обновляет список российских сетей.
Основные компоненты скрипта:
- Загрузка списка российских сетей в ipset. Используется временный набор с атомарной подменой (
ipset swap), чтобы не было момента, когда набор пуст. Если список не скачался (например, ipdeny заблокирован), скрипт останавливается с ошибкой, а не продолжает работу с пустым набором — это защита от «тихой катастрофы», когда весь трафик уходит за границу.
- Создание отдельной таблицы маршрутизации для помеченного трафика:
ip route replace default dev awg1 table 100
ip rule add fwmark 0x1 table 100 priority 10000- Маркировка трафика с помощью iptables:
iptables -t mangle -I PREROUTING 1 -i awg0 -s 172.16.17.0/24 -m set --match-set ru dst -j RETURN
iptables -t mangle -A PREROUTING -i awg0 -s 172.16.17.0/24 -j MARK --set-mark 0x1Важен порядок: сначала RETURN для российских адресов, потом MARK для остальных.
- Маршрут к выходному серверу держится вне туннеля, иначе пакеты к нему закольцуются. Это отдельная тонкость, которая появляется после тестов.
В начале скрипта нужно указать свою клиентскую подсеть и внешний IP выходного сервера. После этого скрипт делается исполняемым и запускается:
chmod +x /root/awg/awg-routing.sh
bash /root/awg/awg-routing.shАвтозапуск после перезагрузки и обновление списка сетей
Одна из главных проблем исходной схемы — после перезагрузки сервера маршруты не восстанавливались, и всё приходилось поднимать вручную. Решение — systemd-юнит, который запускается строго после поднятия обоих туннелей.
Пример юнита /etc/systemd/system/awg-routing.service:
[Unit]
Description=Каскадный сплит-роутинг
After=awg-quick@awg0.service awg-quick@awg1.service network-online.target
Requires=awg-quick@awg0.service awg-quick@awg1.service
Wants=network-online.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/root/awg/awg-routing.sh
[Install]
WantedBy=multi-user.targetЗатем нужно выполнить:
systemctl daemon-reload
systemctl enable awg-quick@awg1 awg-routingRequires здесь жёсткий: если туннель к выходу не поднялся, маршрутизация не запустится. Это правильное поведение — клиенты смогут подключиться, но без раздельного выхода весь трафик пойдёт напрямую, что нарушит работу.
Список российских сетей со временем меняется, поэтому рекомендуется раз в неделю перезапускать юнит, чтобы обновить список. Это делается через cron:
echo '0 5 * * 1 root systemctl restart awg-routing' > /etc/cron.d/awg-routing-refreshПроверка работоспособности и диагностика
Убедиться, что каскад работает, можно по счётчикам iptables. На входном сервере обнуляем счётчики:
iptables -t mangle -Z PREROUTINGЗатем с клиента создаём оба вида трафика:
curl https://ifconfig.me # покажет внешний IP выходного сервера
ping -c3 77.88.55.242 # российский адрес (Яндекс)После этого смотрим счётчики:
iptables -t mangle -L PREROUTING -n -vЕсли счётчик RETURN (match-set ru dst) вырос на российских адресах, а MARK — на остальных, каскад работает правильно.
Типичные проблемы:
- Весь трафик идёт через заграницу. Проверяем список российских сетей:
ipset list ru | grep "Number of entries". Должно быть несколько тысяч записей (около 8600). Если ноль — список не скачался. Скрипт должен остановиться с ошибкой, но если он был запущен до исправления, нужно перезапустить. - Некоторые российские сайты открываются через заграницу. Это происходит, если сайт физически расположен на зарубежном хостинге или за Cloudflare. Его IP не входит в российский список, поэтому трафик уходит на выход. Проверить можно командой
getent hosts имя.ruи затемipset test ru <адрес>. Если адрес зарубежный — это ожидаемо. - Google и YouTube тормозят. Часть кэшей Google и YouTube находится на российских адресах, поэтому они уходят напрямую через вход. Google видит российский IP. Если нужно, чтобы Google всегда шёл через выход, его сети можно добавить в исключения.
- Отдача ниже приёма. Если приём нормальный, а отдача проседает, узкое место — участок между серверами. Нужно мерить направленно:
iperf3 -sна выходе,iperf3 -cсо входа (отдача) иiperf3 -c -R(приём). Низкая отдача при нормальном приёме указывает на шейпинг исходящего трафика у хостера или проблемы с пирингом.
Ограничения и особые случаи
Каскад работает только по IPv4. Если на серверах включён IPv6, часть трафика пойдёт в обход маркировки, и схема сломается. Установщик AmneziaWG отключает IPv6 по умолчанию, но при ручной настройке нужно убедиться, что он выключен.
Серверы за CGNAT не подходят для роли входа. Если у провайдера нет реального публичного IP, клиенты не смогут подключиться к входному серверу. Проверка: адрес из curl -s ifconfig.me должен совпадать с адресом на интерфейсе.
На серверах Hetzner с приватным шлюзом может возникать ошибка «Nexthop has invalid gateway». Решение — флаг onlink при добавлении маршрута. Современные версии скрипта делают это автоматически.
DNS-запросы клиентов по умолчанию уходят через выходной сервер, так как DNS-серверы (например, Cloudflare) имеют зарубежные адреса. Это не влияет на разделение, но при диагностике может сбивать с толку.
Каскад не решает проблему сайтов, которые блокируют иностранные IP-адреса, если сам сайт расположен за границей. В этом случае трафик к нему уходит на выход, и сайт видит иностранный IP. Лечится только на стороне сайта.
Кому каскад нужен, а кому нет
Каскад — это решение для централизованного разделения трафика. Он оправдан, когда:
- VPN используют несколько человек или устройств, и администрировать каждый клиент вручную неудобно.
- Нужно, чтобы все клиенты автоматически получали одинаковое поведение: российские сайты напрямую, зарубежные — через выход.
- Есть желание держать логику на сервере и не зависеть от возможностей клиентских приложений.
Если разделение нужно только одному человеку, каскад — избыточен. Проще настроить AllowedIPs на клиенте, указав нужные подсети. Это описано в документации AmneziaWG и не требует второго сервера.
Также каскад не входит в стандартный установщик AmneziaWG, потому что несколько серверов — это уже другой масштаб, и в одном скрипте такому не место. Поэтому и существует отдельная инструкция.
В целом, каскад собирается за вечер: две установки, туннель между серверами, один скрипт маршрутизации и systemd-юнит. Это надёжная и гибкая схема для тех, кто хочет получить максимальную пользу от VPN, не жертвуя доступом к российским сервисам.
Вопросы и ответы
Что такое каскад AmneziaWG и зачем он нужен?
Каскад AmneziaWG — это схема с двумя серверами: один в России (вход), другой за границей (выход). Клиент подключается ко входному серверу, а тот автоматически направляет российский трафик напрямую в интернет, а весь остальной — через туннель на выходной сервер. Это позволяет одновременно обходить блокировки и сохранять доступ к российским сайтам, которые не пускают иностранные IP-адреса.
Какие требования к серверам для каскада?
Нужны два VPS с чистой ОС (Debian 12/13 или Ubuntu 24.04/25.10), root-доступом и реальным публичным IP-адресом. Серверы не должны быть за CGNAT. Также важно отключить IPv6, так как каскад работает только по IPv4. Подсети серверов должны различаться, например 172.16.17.1/24 и 172.16.61.1/24.
Как проверить, что каскад работает правильно?
Обнулите счётчики iptables на входном сервере (iptables -t mangle -Z PREROUTING), затем с клиента выполните curl https://ifconfig.me (должен показать IP выходного сервера) и ping -c3 77.88.55.242 (российский адрес). После этого посмотрите счётчики: счётчик RETURN должен расти на российских адресах, а MARK — на остальных.
Что делать, если весь трафик идёт через заграницу?
Проверьте список российских сетей: ipset list ru | grep "Number of entries". Если там ноль — список не скачался. Скрипт маршрутизации должен остановиться с ошибкой, но если он был запущен до исправления, перезапустите его. Также убедитесь, что порядок правил iptables правильный: сначала RETURN для российских сетей, потом MARK для остальных.
Почему некоторые российские сайты всё равно открываются через зарубежный IP?
Это происходит, если сайт физически расположен на зарубежном хостинге или за Cloudflare. Его IP-адрес не входит в список российских сетей, поэтому трафик к нему помечается и уходит на выходной сервер. Проверить можно командой getent hosts имя.ru, а затем ipset test ru <адрес>. Если адрес зарубежный — это ожидаемо и лечится только на стороне сайта.
Нужен ли каскад, если VPN пользуюсь только я?
Нет. Если разделение трафика нужно только одному человеку, проще настроить AllowedIPs на клиенте, указав нужные подсети. Каскад оправдан, когда нужно централизованно управлять разделением для многих клиентов или устройств, не настраивая каждый из них вручную.
Как обновлять список российских сетей в каскаде?
Скрипт маршрутизации при каждом запуске обновляет список российских сетей. Для регулярного обновления можно добавить cron-задание, например, раз в неделю: echo '0 5 * * 1 root systemctl restart awg-routing' > /etc/cron.d/awg-routing-refresh. Это перезапустит юнит и обновит список.