Свой AmneziaWG пару лет спустя: что ломается в быту и что я с этим делаю

от автора

Поднять свой VPN на дешёвом VPS — дело на вечер: как это делается с нуля через мой установщик amneziawg-installer, я недавно разбирал отдельно. А что начинается потом, обычно обходят молчанием: через неделю на телефоне начинает рвать, сервер надо обновлять, кому-то раздать доступ и через месяц забрать обратно, а кто-то хочет российские сайты держать напрямую, всё остальное — за границу. Про этот второй уровень и расскажу.

Сервер я держу пару лет, на нём сидят жена и пара друзей, и за это время накопилось понимание, что обычно идёт не так. Почти всё, что ниже, пришлось либо чинить у себя, либо разбирать по чужим отчётам в issues. Собрал в одном месте.

Сначала коротко: что вообще прячет AmneziaWG

Обычный WireGuard быстрый и лёгкий, но у его трафика характерный почерк, и системы фильтрации научились его опознавать и резать, даже если сервер личный. AmneziaWG этот почерк маскирует: подмешивает в поток мусорные пакеты (параметры Jc/Jmin/Jmax), прячет служебные заголовки в случайные диапазоны (H1-H4) и в версии 2.0 добавляет так называемые CPS-пакеты (I1-I5), которые имитируют посторонний протокол на старте соединения. Считается всё в ядре, поэтому на вменяемом железе маскировка скорость почти не ест — на совсем дохлом VPS это уже не так, но про него ниже.

Подробно разбирать протокол я не буду — это уже сделали в подробной статье самой Amnezia про AmneziaWG 2.0, лучше там и прочитать. Для практики важно другое: руками эти параметры подбирать тяжело и легко ошибиться. Диапазоны H1-H4, например, не должны пересекаться и не должны попадать в зарезервированные значения, иначе соединение просто не встанет. Поэтому я их не трогаю руками: установщик генерирует корректные непересекающиеся диапазоны сам и делает их случайными на каждой установке — чтобы у всех серверов отпечаток был разный, а не один на всех.

Параметры обфускации, которые установщик сгенерировал сам: число и размер мусорных пакетов Jc/Jmin/Jmax и непересекающиеся диапазоны H1-H4

Параметры обфускации, которые установщик сгенерировал сам: число и размер мусорных пакетов Jc/Jmin/Jmax и непересекающиеся диапазоны H1-H4

Чем я ставлю и обновляю

Ставится всё одной командой на чистый Ubuntu или Debian:

wget -O install_amneziawg.sh https://raw.githubusercontent.com/bivlked/amneziawg-installer/v5.16.1/install_amneziawg.shsudo bash ./install_amneziawg.sh

Это amneziawg-installer — мой открытый установщик AmneziaWG 2.0 под выделенный сервер на Ubuntu 24.04/25.10/26.04 и Debian 12/13. Он спрашивает порт и пару вещей, дальше работает сам: ставит протокол, настраивает фаервол, генерирует параметры обфускации, сервер и готовых клиентов с QR-кодами. На ARM (Raspberry Pi, Oracle Ampere, Hetzner arm64) сначала пробует готовый модуль ядра для известных таргетов, а если совпадения нет — собирает через DKMS. Есть русская и английская версии. Если посреди установки сервер просит перезагрузку — запускаете команду ещё раз, и она продолжает с того места, где остановилась.

Я специально веду установщик так, чтобы на сервере крутился только VPN, без веб-панели и Docker. Дома панель не нужна: все операции — это одна-две команды, а постоянно висящий процесс ест память на дешёвом сервере и торчит наружу лишним портом. Если у вас не сервис на сотню клиентов, это плата за удобство, которым воспользуетесь пару раз.

Почему именно на телефоне рвёт, и что помогает

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

Под это в установщике есть отдельный профиль:

sudo bash ./install_amneziawg.sh --preset=mobile --yes

Он фиксирует Jc=3 и зажимает размер мусорных пакетов в узкий диапазон. Значения взяты не с потолка: часть я гонял сам на том, что было под рукой, остальное свёл из отчётов в проекте. Для Tele2 лучше всего держится малое число джанк-пакетов, поэтому mobile и ставит Jc=3; на московском Yota/Tele2 сработала связка Jc=3, Jmin=40, Jmax=70. Но это не универсальный рецепт, а первая попытка: по тому же Yota встречался вариант с другим размером и бинарным I1, а на МТС в Приморье профиля mobile из коробки не хватило, помог короткий I1 = <r 48>. Если профиль не зашёл, дальше подбираем I1 и Jmax по таблице операторов. А если хочется задать значения сразу вручную, при установке для этого есть точечные флаги:

sudo bash ./install_amneziawg.sh --jc=3 --jmin=30 --jmax=70 --yes

На уже работающем сервере ради этого всё переустанавливать не нужно: правите Jc/Jmin/Jmax прямо в /etc/amnezia/amneziawg/awg0.conf, перезапускаете awg-quick@awg0 и перевыпускаете клиентам конфиги — manage regen имя для одного или manage regen без имени сразу для всех. Главное, чтобы параметры обфускации совпадали на сервере и на клиенте, иначе соединение не встанет.

Второй виновник на мобильном — MTU. Если идут потери на крупных передачах (страницы открываются, а большой файл или видео встаёт), помогает уменьшить MTU на клиенте. И отдельно: на совсем дохлом VPS в один поток обфускация упирается в процессор. Если скорость просела, загляните в top — если одно ядро в потолок и много времени висит в %si (это обработка сетевых прерываний), значит уткнулись в CPU, а не в канал, и лечится это сервером пободрее, а не настройками.

То, что я проверил сам — это капля. Какой оператор и хостинг как себя ведёт и что помогает, я свожу в таблицу в ADVANCED.md, и там уже накопленная статистика из десятков отчётов тех, кто поднял у себя и написал, что сработало. Поднимете — добавьте свой случай, это реально выручает следующих.

Жизнь после установки: клиенты, сроки, бэкапы

Дальше с сервером живёшь одной командой manage — многие скрипты на этом месте заканчиваются, поставил и забыл. Полная форма — bash /root/awg/manage_amneziawg.sh, дальше я для краткости пишу просто manage.

Добавить друга:

bash /root/awg/manage_amneziawg.sh add petya

На выходе — конфиг, ссылка vpn:// и QR-код: открыл приложение Amnezia на телефоне, отсканировал, готово. Посмотреть, кто есть и кто подключался — manage list. Удалить — manage remove petya.

Список клиентов одной командой: видно, у кого есть конфиг и QR и кто выходил на связь

Список клиентов одной командой: видно, у кого есть конфиг и QR и кто выходил на связь

Что я ценю больше всего — временный доступ. Дал знакомому VPN на поездку, на неделю:

bash /root/awg/manage_amneziawg.sh add guest --expires=7d

Через неделю клиент сам отвалится, чистить вручную и вспоминать о нём не надо. Ещё есть бэкап и восстановление конфигов одной командой, перегенерация конфига и QR существующего клиента (regen), а list и stats умеют отдавать --json, если захочется прикрутить что-то своё сверху.

Раздельный выход: Россия напрямую, остальное за границу

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

Решается это каскадом из двух серверов. Клиент подключается к одному, а трафик расходится уже на стороне сервера:

  • к российским сетям — напрямую с сервера-входа (российские сайты видят российский IP и открываются быстро);

  • всё остальное — через второй сервер за границей (зарубежные сайты видят зарубежный IP).

Вход лучше держать в России или рядом, выход — обычный зарубежный VPS. Сервер-вход решает, куда направить пакет, по списку российских сетей: список берётся из открытой зоны ipdeny, грузится в ipset, трафик к адресам из него идёт мимо туннеля, а остальное помечается и уходит на выход. На клиенте настраивать нечего — добавляете его обычным manage add на сервере-входе, деление целиком на сервере и одинаковое для всех.

Если раздельный выход нужен только вам одному, проще задать список AllowedIPs прямо на клиенте (это есть в ADVANCED.md). Каскад оправдан, когда деление хочется держать на сервере и одинаково для всех, кто подключается.

Делит каскад по IP назначения, по адресам, а не по доменам, и отсюда растут его нюансы. Самый заметный: Google и YouTube держат часть своих кэшей на российских адресах, поэтому по умолчанию уходят через вход и видят российский IP — подменой DNS это не лечится, нужно вручную гнать их сети на зарубежный выход. Похожая история с отдельными ведомственными сайтами вроде госуслуг: если их адреса не попали в список российских сетей, они уйдут за границу, а туда иностранные IP не пускают, такие добавляют в список руками. Плюс двойная инкапсуляция требует заниженного MTU и заметнее грузит дешёвый VPS. Всё это с диагностикой разобрано в гайде.

Идею предложил @glfenix в обсуждении проекта, я собрал схему на стенде, погонял, поправил пару мест и оформил в пошаговую инструкцию — с готовым скриптом маршрутизации и автозапуском после перезагрузки. С тех пор её повторили и другие: в том же обсуждении отписались, что каскад поднялся и работает. Полный разбор с шагами, скриптом и частыми вопросами — в гайде по каскаду. В сам установщик каскад не входит специально: несколько серверов — другой масштаб, в одном скрипте такому не место.

Где может не взлететь

Из коробки заводится не всегда. У совсем агрессивного провайдера может не пойти с первого раза — придётся поиграть профилем маскировки или сменить хостинг (и тут выручает то, что переехать дешевле, чем выяснять причину: команда одна, дальше сервер ставится сам с парой перезагрузок, минут двадцать, но руками там делать нечего — снёс, поднял на другом VPS, раздал новые ссылки).

Адреса популярных хостеров вроде Hetzner давно у всех на карандаше, и трафик до них чаще режут — дешёвый VPS можно держать как расходник и менять, если не повезло с подсетью. Мобильный интернет капризнее домашнего. И свой сервер — это пара долларов в месяц, бесплатным он не будет.

Про надёжность скажу одно, без дев-дневника. Я не просто обернул чужие команды в скрипт. По дороге вылезали вещи, которые молча ломали бы установку: например, валидация endpoint сервера когда-то пропускала заведомую чушь вроде 999.0.0.1 как валидный IP. Такое чинится, на это есть тесты — и поэтому у меня дома оно заводится с первого раза и работает месяцами без присмотра.

Про себя и куда смотреть дальше

Я автор этого установщика. Пишу не чтобы продать — он бесплатный, с открытым кодом под MIT. Просто сам когда-то продирался через всё это руками и хочу, чтобы у других ушло меньше времени. Если что-то не пошло — спрашивайте в issues, помогу разобраться.

На установке всё это кажется территорией линуксоидов. А когда сервер уже работает, остаётся-то несколько команд, и они быстро уходят в привычку — примерно как когда-то привык к ним я.

ссылка на оригинал статьи https://habr.com/ru/articles/1051054/