javascript

Как я поднял AmneziaWG 2.0 на роутере ASUS: DPI, GeoIP и веб-интерфейс

  • понедельник, 6 апреля 2026 г. в 00:00:04
https://habr.com/ru/articles/1019440/
АмнезияМэн - ты не вспомнишь о блокировках
АмнезияМэн - ты не вспомнишь о блокировках

Когда VPN на телефоне уже не спасает, а DPI провайдера научился резать WireGuard за секунды, приходит время переносить обфускацию на роутер. В этой статье расскажу, как я сделал полноценный аддон для Asuswrt-Merlin с веб-интерфейсом, выборочной маршрутизацией и поддержкой AmneziaWG 2.0. И почему пришлось отказаться от kernel module в пользу пользовательского пространства.

Проблема

У меня ASUS GT-AX11000 с прошивкой Asuswrt-Merlin. Обычный WireGuard на роутере через встроенный клиент Merlin работает, но провайдер его видит и режет. AmneziaWG решает эту проблему за счёт обфускации, DPI не может отличить трафик от обычного UDP.

На телефоне и ПК есть клиент Amnezia VPN, и там всё работает. Но есть нюанс.

Корпоративный VPN и бесконечные конфликты

На рабочем ПК постоянно поднят корпоративный VPN. И он регулярно конфликтует с личным VPN: маршруты перебивают друг друга, DNS ломается, Split Tunneling работает через раз. В итоге: инструменты для работы, которые оказались под санкциями (GitHub Copilot, Claude, ChatGPT, Figma, Slack, список растёт каждый месяц), то работают, то нет. Переключаешь VPN, отваливается корпоративный. Поднимаешь корпоративный, отваливается доступ к заблокированным ресурсам.

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

Отдельная боль, YouTube. Когда его замедлили, на выручку пришёл b4, инструмент, который обманывает DPI на уровне роутера без всякого VPN. Отличный продукт, спасибо автору (DanielLavrushin), именно его проекты, включая xrayui, вдохновили меня сделать аналогичный аддон для AmneziaWG. Но b4 решает только проблему замедления, а когда блокируют целиком (AI-сервисы, мессенджеры, рабочие инструменты), нужен полноценный VPN-туннель.

Решение: перенести VPN на роутер. Корпоративный VPN на ПК остаётся как есть, а роутер сам решает куда направить трафик. Никаких конфликтов, никаких переключений.

Что хочется получить

  • Один туннель на весь дом, а не VPN на каждом устройстве

  • Выборочную маршрутизацию: YouTube и рабочие инструменты через VPN, банк напрямую

  • Управление через веб-интерфейс роутера, без SSH для каждого изменения

  • Отсутствие конфликтов с корпоративным VPN на рабочих машинах

  • Поддержку AmneziaWG 2.0 с новыми параметрами I1-I5 для мимикрии трафика

Первый подход: kernel module

AmneziaWG это форк WireGuard с дополнительными параметрами обфускации. Есть kernel module, который компилируется, как модуль для Linux.

Проблема: роутер работает на ядре 4.1.51 (Broadcom HND). Модуль нужно кросс-компилировать с Broadcom toolchain под конкретную версию ядра. Собрал Docker-окружение, модуль скомпилировался, загрузился, handshake проходит, ping работает...

Но TCP умирал через 2 минуты. :(

Handshake свежий, ICMP работает, а TCP нет. Перезапуск помогал, но ненадолго. На десктопном клиенте с тем же сервером всё идеально. Радость длилась не долго.

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

Решение: userspace

У AmneziaWG есть amneziawg-go, реализация на Go, форк wireguard-go. Это то же самое, что использует десктопный клиент, статический бинарник, работает на любом ядре. Никаких проблем с совместимостью. Бинго воскликнул я и начал внедрять под уже реализованный ui.

Результат: TCP стабилен, key rotation работает, туннель не падает. Проблема со стабильностью решена полностью.

Кастомная iptables-цепочка

Все правила живут в отдельной цепочке AWG в таблице mangle. Очистка одной командой iptables -t mangle -F AWG. Никакого ручного удаления отдельных правил.

mangle PREROUTING → AWG chain:
  1. dst-type LOCAL → RETURN          # трафик к роутеру
  2. dst LAN → RETURN                 # LAN-to-LAN
  3. udp dports 67,68,123 → RETURN    # DHCP, NTP
  4. dst 224.0.0.0/4 → RETURN         # multicast
  5. dst VPN_ENDPOINT → RETURN        # защита от петель
  6. [direct devices → RETURN]         # исключения
  7. [vpn_all devices → MARK 0x100]    # весь трафик через VPN
  8. [vpn_geo devices + ipset → MARK]  # выборочно через VPN
  9. [default policy]                   # для остальных

Помеченный трафик (fwmark 0x100) уходит в routing table 300, где маршруты через awg0.

Три политики на устройство

  • VPN All весь трафик через VPN

  • VPN Geo только трафик к IP из GeoIP/GeoSite списков

  • Direct устройство обходит VPN

GeoIP по сервисам

IP-диапазоны для Telegram, Google, Netflix и других сервисов из Loyalsoldier/geoip. Это CIDR-блоки, они не зависят от DNS, трафик матчится по IP назначения напрямую.

telegram,google,netflix,cloudflare

Скрипт скачивает текстовые файлы с CIDR-блоками и загружает в ipset awg_dst.

GeoSite по доменам

Доменные списки из v2fly/domain-list-community, 1400+ категорий. Работают через dnsmasq ipset: когда устройство резолвит домен, IP попадает в ipset, и последующий трафик маркируется.

youtube,google,discord,netflix,spotify

Грабли на пути

1. iPhone и зашифрованный DNS

Потратил несколько часов на дебаг: правила iptables на месте, ipset наполнен, а iPhone видит прямой IP. Оказалось, iPhone использует DNS-over-HTTPS, обходя dnsmasq роутера. Домен резолвится через Apple DoH, IP не попадает в ipset.

Решение: принудительный перехват DNS + блокировка DoH/DoT:

# Перенаправить весь DNS на роутер
iptables -t nat -I PREROUTING -i br0 -p udp --dport 53 -j DNAT --to $ROUTER_IP
# Заблокировать DNS-over-TLS
iptables -I FORWARD -i br0 -p tcp --dport 853 -j REJECT
# Заблокировать DoH к известным провайдерам
for ip in 8.8.8.8 8.8.4.4 1.1.1.1 1.0.0.1 9.9.9.9; do
    iptables -I FORWARD -i br0 -d $ip -p tcp --dport 443 -j REJECT
    iptables -I FORWARD -i br0 -d $ip -p udp --dport 443 -j REJECT
done

Но это не помогает полностью, iPhone использует Apple DoH серверы (17.x.x.x), которых слишком много для блокировки. Финальное решение: ручной DNS на устройстве (IP роутера) для политики VPN Geo.

Для политики VPN All это не проблема, весь трафик и так идёт через VPN.

2. MSS clamping

TCP SYN проходит, SYN-ACK возвращается, а данные нет. Классическая MTU/MSS проблема. Десктопный клиент делает MSS clamping автоматически, на роутере нужно явно:

iptables -t mangle -A FORWARD -o awg0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
iptables -t mangle -A FORWARD -i awg0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

3. Теги v2fly ломали dnsmasq

В v2fly domain list домены могут иметь теги: cici.com:@!cn. Эти теги попадали в dnsmasq конфиг и ломали его, dnsmasq не запускался. Пришлось чистить:

domain=$(echo "$domain" | sed 's/^\.//;s/:@[^ ]*$//')

И уменьшить количество доменов на строку с 80 до 20, dnsmasq не переваривал слишком длинные строки ipset.

4. Telegram и прямые IP

Добавил telegram в GeoSite (доменные списки), не работает. Telegram подключается напрямую по IP, минуя DNS. Нужны GeoIP CIDR-блоки, не домены. Для этого добавил отдельную секцию GeoIP Service Lists с автодополнением.

Веб-интерфейс

Аддон встраивается в стандартный веб-интерфейс Merlin через Addons API:

  • Import Config загрузка .conf файла из клиента Amnezia VPN (все поля включая I1-I5 заполняются автоматически)

  • Device Rules таблица устройств с выбором политики и добавлением из DHCP-списка

  • GeoIP Service Lists IP-диапазоны по сервисам с автодополнением

  • GeoSite Service Lists домены по сервисам с автодополнением из v2fly базы (1400+ категорий)

  • Custom Domains / IPs ручные записи

  • Start / Stop / Apply управление туннелем

При нажатии Apply скрипт проверяет, какие GeoIP списки отсутствуют, и скачивает только недостающие. Update Now принудительно обновляет все списки.

Установка

Одной командой по SSH:

curl -sfL https://raw.githubusercontent.com/r0otx/asuswrt-merlin-amneziawg/main/install-online.sh | sh

Скрипт сам определит архитектуру, скачает последний релиз и установит. Обновление так же, через UI появится кнопка если вышла новая версия.

Entware .ipk пакет

Для ручной установки собирается .ipk пакет:

./build-ipk.sh
# output/amneziawg_1.0.2-1_aarch64-3.10.ipk  (ARM64)
# output/amneziawg_1.0.2-1_armv7-2.6.ipk      (ARM32)

Установка на роутере:

opkg install /tmp/amneziawg_1.0.2-1_aarch64-3.10.ipk

Post-install скрипт создаёт /dev/net/tun, устанавливает web UI, настраивает автозапуск.

Что в итоге

Поддерживаются все aarch64 роутеры с Merlin (GT-AX11000, RT-AX86U, RT-AX88U и др.) и ARM32 модели (RT-AC68U). Kernel module не нужен, работает на любом ядре.

Правовой аспект

На момент публикации (март 2026) использование VPN в России не запрещено и не является правонарушением.

Федеральный закон № 281-ФЗ от 31.07.2025, вступивший в силу 1 сентября 2025 года, вводит административную ответственность за умышленный поиск и доступ к материалам из реестра экстремистских (штраф 3 000 – 5 000 руб.), а также за рекламу средств обхода блокировок (штраф до 500 000 руб.). При этом само использование VPN для обеспечения приватности, безопасности и защиты персональных данных закон не затрагивает.

Депутат Госдумы Антон Горелкин (зампред комитета по информполитике) публично подтвердил: «введение штрафов за использование VPN не планируется и даже не обсуждается».

Проект является техническим инструментом для обеспечения сетевой безопасности и приватности. Автор не несёт ответственности за использование программного обеспечения в целях, противоречащих законодательству Российской Федерации или иных юрисдикций. Пользователь самостоятельно несёт ответственность за соблюдение применимого законодательства.

Ссылки