Скрипт для автоустановки AmneziaWG 2.0 на Ubuntu

@bivlked, спасибо за скрипт. Поставил вместо стандартной установки amneziaVPN, с конфигом из которой почему-то не хотел работать throne. С вашим завелось.
Так как у меня уже стоит настроенный xray для VLESS с маршрутизацией и нужными настройками DNS, то решил не дублировать всё это для AWG, а сделать проброс трафика из интерфейса AWG в xray через механизм tproxy, и рулить всем в конфиге xray. Поделюсь конфигурацией, может кому-то пригодится:

  1. Создать файл /etc/nftables.conf:
#!/usr/sbin/nft -f
define RESERVED_IP = {
    10.0.0.0/8,
    100.64.0.0/10,
    127.0.0.0/8,
    169.254.0.0/16,
    172.16.0.0/12,
    192.0.0.0/24,
    224.0.0.0/4,
    240.0.0.0/4,
    255.255.255.255/32
}

table ip xray {
    chain prerouting {
        type filter hook prerouting priority mangle; policy accept;
        iifname != "awg0" return
        fib daddr type local return
        ip daddr $RESERVED_IP return
        ip protocol tcp tproxy to 127.0.0.1:44444 meta mark set 1
        ip protocol udp tproxy to 127.0.0.1:44444 meta mark set 1
    }
}
  1. В файле /etc/amnezia/amneziawg/awg0.conf заменить PostUp и PostDown на строки ниже (также заменить eth0 на свой интерфейс):
...
PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; iptables -t mangle -A FORWARD -o %i -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1240; iptables -t mangle -A FORWARD -i %i -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1240
PostUp = nft -f /etc/nftables.conf
PostUp = ip rule add fwmark 1 table 100
PostUp = ip route add local default dev lo table 100
...
PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; iptables -t mangle -D FORWARD -o %i -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1240; iptables -t mangle -D FORWARD -i %i -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1240
PostDown = nft delete table ip xray
PostDown = ip rule del fwmark 1 table 100
PostDown = ip route del local default dev lo table 100
...
  1. В xray создать inbound:
{
	"tag": "tproxy-in",
	"port": 44444,
	"protocol": "dokodemo-door",
	"settings": {
		"network": "tcp,udp",
		"followRedirect": true
	},
	"streamSettings": {
		"sockopt": {
			"tproxy": "tproxy"
		}
	}
}

Опционально: для перехвата DNS добавить:

  • в routing.rules:
        {
          "type": "field",
          "inboundTag": ["tproxy-in"],
          "port": 53,
          "outboundTag": "dns-out"
        }
  • в outbounds:
      {
        "tag": "dns-out",
        "protocol": "dns"
      }
  1. Если используется ufw, то добавить в файл /etc/ufw/before.rules после строки # End required lines:
-A ufw-before-input -i awg0 -m mark --mark 0x1 -j ACCEPT

Применить:

ufw reload
systemctl restart xray
systemctl restart awg-quick@awg0

Опционально можно теперь почистить правила и настройки, связанные с форвардингом, но они вроде и не мешают.
Проверял на окружении: Ubuntu 26.04, amneziawg-installer v5.18.3, Xray 26.3.27

parfit, спасибо на добром слове, и что всё целиком расписали. Схема логичная: раз xray уже стоит и держит на себе маршрутизацию с DNS, дублировать это на стороне AWG незачем - проще завернуть в него весь клиентский трафик через tproxy и держать правила в одном месте. MSS-кламп, смотрю, оставили - он тут и нужен, трафик всё равно идёт через туннель.

Про throne: установщик отдаёт обычный конфиг AmneziaWG 2.0, .conf и vpn:// ссылку, без обёртки под приложение Amnezia. Поэтому его понимают и сторонние клиенты, тот же throne, а не только родное приложение. Почему конфиг из самого приложения у вас не пошёл, точно не скажу, но с обычным конфигом сюрпризов меньше.

У меня в установщике деление трафика сделано на самом сервере (каскад), у вас через xray - обе схемы рабочие, просто под разные ситуации. Спасибо, что поделились - у кого xray уже настроен, точно пригодится.

Добрый вечер! Не подскажите, почему тайм аут может быть в shadowrocket? Ставил на голую 24.04. Процесс прошел без проблем, выбирал второй вариант с роутингом. Сервер в норме

Привет. Таймаут в Shadowrocket почти всегда упирается в одно: ему нужен PresharedKey, без него он не поднимает хендшейк и отваливается как раз по таймауту. Родное приложение Amnezia и throne цепляются и без PSK, а Shadowrocket без него молчит. Роутинг, который ты выбирал при установке, тут ни при чём, дело в самом клиенте.

Проще всего пересоздать клиента с этим флагом:

sudo bash /root/awg/manage_amneziawg.sh remove имя_клиента
sudo bash /root/awg/manage_amneziawg.sh add имя_клиента --psk

В новом .conf появится строка PresharedKey, импортируй конфиг в Shadowrocket заново, файлом или по QR. Если удобнее руками, сгенерируй ключ один раз (awg genpsk) и впиши одно и то же значение в обе стороны: в [Peer] на сервере и в [Peer] клиентского конфига. Разойдутся значения, хендшейк не пройдёт.

Если PSK уже стоял, а таймаут остаётся, скажи, с чего подключаешься. С мобильного интернета дефолтный порт 39743 у части операторов режется, и тогда таймаут ловится и без PSK: проверь с wi-fi или переставь сервер на 443/udp. И заодно напиши версию установщика (первые строки install_amneziawg.sh) и покажи из клиентского .conf строки AllowedIPs и [Interface] без ключей, гляну, что не так.

Апдейт из тех, где за сутки всё поменялось дважды.

30 июля upstream влил AmneziaWG 3.0 в основную ветку модуля ядра и в ту же ночь переключил на неё PPA. Новый модуль использует nla_put_uint, а эта функция появилась только в ядре 6.7, поэтому DKMS-сборка на всём, что ниже, падала с implicit declaration of function 'nla_put_uint'. Под ударом оказались те, кто берёт модуль из PPA на старом ядре: Debian 12 с ядром 6.1, Ubuntu 22.04. Чистая установка обрывалась на шаге 2.

31 июля я собрал минимальный репродьюсер и завёл issue в upstream. Через час с небольшим ygurov прислал PR, к вечеру фикс влили и выпустили тег v3.0.20260731-04, а этой ночью пересобранные пакеты уже разъехались по PPA. Так что если у вас в эти сутки перестало ставиться, чинить со своей стороны нечего: sudo apt update подтянет исправленный пакет.

Issue с репродьюсером: AmneziaWG 3.0 module fails to build on kernels < 6.7 (nla_put_uint) - Debian 12, Ubuntu 22.04 · Issue #204 · amnezia-vpn/amneziawg-linux-kernel-module · GitHub

Пока фикс ехал, вышел v5.23.0, и в нём на ядрах ниже 6.7 установщик не берёт модуль из PPA, а собирает модуль линии 2.0 (v1.0.20260725) из исходника, сверяя его по неизменяемому commit-хэшу. Теперь, когда сборка 3.0 на старых ядрах починена, этот путь перестал быть спасательным и стал осознанным выбором: на таких системах установщик держит 2.0 не потому, что 3.0 там не соберётся, а потому что я его там ещё не проверял. Собранный модуль пересобирается при обновлении ядра штатным AUTOINSTALL=yes, следить за ним отдельно не надо, а удаление чистит за собой. Ставится всё так же:

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

Отдельно про современные ядра (Ubuntu 24.04 и новее, Debian 13). На x86 установка идёт по прежнему пути из PPA, но модуль оттуда теперь приезжает поколения 3.0. Базовую совместимость я проверил на стенде (свежая установка на Ubuntu 24.04 + существующий Linux-клиент с 2.0-модулем): клиент подключается и работает - handshake, трафик, DNS, плановое обновление ключей; конфиги менять не пришлось. ARM-установок это вообще не касается: там модуль ставится из моих предсобранных пакетов, закреплённых на линии 2.0. Более глубокую проверку (мобильные клиенты, длительные сессии) продолжаю и о результатах отпишусь.

Заодно перевёл ARM-пребилды с плавающего HEAD на тег линии 2.0: после переключения upstream цель debian-bookworm-arm64 перестала компилироваться с тем же nla_put_uint.

Возможностей самой 3.0 - header protection, рандомизация таймингов, новые маскирующие пакеты - в установщике пока нет, сроков не называю.

В v5.22.0, который вышел в тот же день, добавились три вещи. manage regen и manage check теперь предупреждают, если правка awgsetup_cfg.init не дошла до живого awg0.conf (повод - issue #196). Появилось руководство WARP-RU.md про маршрутизацию российского сегмента через Cloudflare WARP по BGP-фиду antifilter, для тех, у кого сервер один; схему предлож@alexfiu4-cyberл @alexfiu4-cyber, я повторил её на стенде. И поправил в доках старую ошибку: совпадать на сервере и клиенте обязаны только S1-S4 и H1-H4, а Jc/Jmin/Jmax и I1-I5 не обязаны - это отдельные пакеты-обманки, вторая сторона их отбрасывает.

CHANGELOG: amneziawg-installer/CHANGELOG.md at main · bivlked/amneziawg-installer · GitHub

Давно не обновлял тему, за это время вышло шестнадцать релизов, сейчас v5.36.0.

Главное - мобильный интернет. Если клиент AmneziaWG бесконечно висит на «Подключение», а на сервере пир виден, счётчик принятого растёт, но latest handshake пустой, дело может быть в маскирующем пакете I1. Раньше установщик делал его из случайных байт, и часть мобильных сетей режет такой пакет вместе с рукопожатием, которое летит следом. Замерил на МТС в Москве: при одинаковых 128 байтах со случайным пакетом рукопожатие не собралось ни разу, а с пакетом в виде DNS-ответа собралось за 40 секунд. С v5.33.0 установщик генерирует I1 в форме DNS-ответа. Недавний случай из issue: Мегафон в Питере, смена порта не помогла, а I1 в DNS-форме помог ( Проблемы с подключением по мобильной сети (Мегафон, Санкт-Петербург, возможно, Ленинградская область) · Issue #283 · bivlked/amneziawg-installer · GitHub ). Переустановка с --force уже заданные параметры не трогает, чтобы не отвалились выданные конфиги, так что на старом сервере I1 останется прежним, установщик только предупредит. Совпадать на сервере и клиенте I1 не обязан, поэтому можно поправить его в .conf одного клиента, не трогая сервер. Как именно, расписал тут: amneziawg-installer/ADVANCED.md at main · bivlked/amneziawg-installer · GitHub

В прошлый раз обещал отписаться по долгим сессиям. Гонял их на модуле ядра и нашёл баг в самом AmneziaWG: при ненулевом S4 keepalive принимался за пакет данных, и на простаивающем туннеле рукопожатия шли во много раз чаще обычного. Связь при этом работает, просто служебного трафика больше: перед каждым рукопожатием уходят junk-пакеты и I1. Причину подтвердил однострочным патчем и отправил разбор в upstream ( Handshake every 15 seconds instead 2+ minutes if s4 used · Issue #186 · amnezia-vpn/amneziawg-linux-kernel-module · GitHub ), 5 августа исправление влили. На x86 с ядром 6.7 и новее модуль ставится из PPA, так что фикс приезжает обычным apt upgrade и включается после перезагрузки, версию загруженного модуля показывает cat /sys/module/amneziawg/version. В закреплённый модуль второй линии (ядра старше 6.7, в том числе Debian 12, и ARM) исправление не входит, решения по нему пока нет.

Ещё одна причина жалоб «на мобильном не работает, на Wi-Fi работает» - IPv6: в прежнем режиме по умолчанию IPv6 шёл мимо туннеля, и сайты с IPv6-адресом оставались заблокированными. С v5.31.0 в профиль добавляется ::/0: IPv6 уходит в туннель и там глохнет, а устройство само переходит на IPv4. С v5.34.0 новые установки по умолчанию ставят полный туннель (0.0.0.0/0, ::/0). Профилям, выданным раньше в этом режиме, исправление доставляет manage_amneziawg.sh regen после обновления скриптов на сервере, потом профили надо заново импортировать; ручные AllowedIPs при этом сохраняются. Перевести старый сервер на полный туннель можно через --force --route-all и затем regen --reset-routes, только --reset-routes сбросит и ручные AllowedIPs.

Если неясно, что на сервере, 2.0 или 3.1: на ядре 6.7 и новее из PPA приезжает модуль третьей линии, а профили установщик выдаёт второй. С v5.36.0 manage check, show и diagnose пишут поколение протокола прямо в выводе, в check --json это поле protocol. Сама 3.1 будет включаться отдельным флагом --protocol=3.1, без RandomTrailers и с возможностью вернуться на 2.0. По умолчанию установка остаётся на AmneziaWG 2.0: профиль 3.1 работает только в приложениях с поддержкой 3.1, а в остальных просто не подключится. Сроков пока не называю.

Для тех, кто не любит запускать от root скачанный скрипт: с v5.29.0 релизы подписаны minisign, ключ лежит офлайн и в GitHub Actions не попадает. Как проверить, написано в README ( GitHub - bivlked/amneziawg-installer: One-command AmneziaWG 2.0 / 3.x installer for a self-hosted VPN server on Ubuntu and Debian: DPI bypass, traffic obfuscation, split tunneling, auto-hardening, client management. Includes a VPN cascade guide. · GitHub ). Отпечаток ключа дублирую здесь, чтобы было с чем сверить не только на GitHub: 3E598A1C01907E17.

Ставится как раньше (рекомендую Ubuntu 24.04 или Debian 13), только ссылка теперь ведёт на последний релиз:

wget -O install_amneziawg.sh https://github.com/bivlked/amneziawg-installer/releases/latest/download/install_amneziawg.sh
sudo bash install_amneziawg.sh

CHANGELOG: amneziawg-installer/CHANGELOG.md at main · bivlked/amneziawg-installer · GitHub

Поправка к посту выше. Для режима «Amnezia» я советовал сделать regen, чтобы IPv6 не шёл мимо туннеля. На версиях до 5.36.1 это дописывало в профиль ::/0, а клиент AmneziaWG для Windows при ::/0 блокирует всё мимо туннеля, и вместе с этим пропадают роутер, соседние компьютеры и SSH в домашней сети. В v5.36.2 вместо ::/0 пишется 2000::/3 и служебный IPv6-адрес в Address: IPv6 устройства по-прежнему в туннель, а локальная сеть доступна. Проверил на Windows, Linux и Android в мобильной сети с IPv6. Если уже делали regen по моему совету, обновите скрипты на сервере и сделайте его ещё раз, ::/0 он заменит сам, а где не сможет, подскажет как. Потом профили надо заново импортировать. Режим «Весь трафик» это не затрагивает.

Вышел v5.37.0. Из того, что может пригодиться:

  • DNS для новых клиентов теперь задаётся одной строкой CLIENT_DNS в /root/awg/awgsetup_cfg.init и переживает обновление скриптов. Удобно, если на сервере свой резолвер или блокировщик рекламы. Как такой поднять и на чём эти схемы обычно ломаются без единой ошибки, теперь расписано в ADVANCED: amneziawg-installer/ADVANCED.md at main · bivlked/amneziawg-installer · GitHub
  • На ARM появился флаг --no-prebuilt: модуль собирается через DKMS, а не ставится готовым пакетом. Готовые пакеты собирает CI проекта, сверяются они только по SHA256 из того же релиза, подписи у них нет, так что теперь есть выбор. На ядрах 6.7 и новее с этим флагом ставится тот же модуль из PPA, что и на x86.
  • --ssh-port с недопустимым значением останавливает установку на шаге 0, до любых изменений на сервере, так что опечатка в номере порта не закроет SSH.
  • --uninstall убирает своё и не запускает apt-get autoremove по всей системе.

И поправка к моему посту от 23 сентября. 3E598A1C01907E17 я назвал там отпечатком ключа, это неточно: это идентификатор, и у чужого ключа он может совпасть. Сверять надо публичный ключ целиком:

RWQXfpABHIpZPttqrwYrQNHRTk/iLIz4cVh9KkRwAElHP+CoW/NPEysN

Он же лежит в KEYS.txt в репозитории и в каждом подписанном релизе. Команда проверки с полным ключом (minisign -P) в README: GitHub - bivlked/amneziawg-installer: One-command AmneziaWG 2.0 / 3.x installer for a self-hosted VPN server on Ubuntu and Debian: DPI bypass, traffic obfuscation, split tunneling, auto-hardening, client management. Includes a VPN cascade guide. · GitHub

CHANGELOG: amneziawg-installer/CHANGELOG.md at main · bivlked/amneziawg-installer · GitHub