AmneziaWG (AWG) — справочник для zapret-gui
SkillProductivityComplete reference for AmneziaWG (AWG) in the zapret-gui project (Keenetic routers on Entware / OpenWrt / Linux). Use for any tasks concerning: AWG configs (.conf — [Interface]/[Peer], wg-quick extensions), obfuscation parameters (Jc/Jmin/Jmax, S1-S4, H1-H4, I1-I5, J1-J3, Itime), and protocol versio
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the AmneziaWG (AWG) — справочник для zapret-gui skill
What this skill tells your AI
The instructions your AI receives, as published by avatardd/zapret-gui in .claude/skills/awg/SKILL.md and read by ahel’s review.
Единый источник истины о том, как AmneziaWG реально работает и как с ним
обращаться в zapret-gui. Читать перед тем, как трогать разбор/генерацию
.conf, менеджер туннелей, параметры обфускации, WARP, интеграцию с Keenetic
или объяснять пользователю «почему handshake есть, а трафика нет».
Источники истины (в порядке убывания авторитета):
- amnezia-vpn/amneziawg-go — userspace-реализация протокола на Go
(
README.md= спецификация параметров обфускации; сверено с v3.1.20260814); amnezia-vpn/amneziawg-tools — форкwireguard-tools(awg/awg-quick), сверено с v3.1.20260812. README на ветке 3.1 не изменился: два новых параметра (§2.1.2) описаны только кодом —device/uapi.goиsrc/config.c. Окончательный список ключей, которые вообще можно писать в.conf, — этоkey_matchв егоsrc/config.c, а НЕ документация: docs.amnezia.org описывает параметры протокола, часть которых парсер не принимает (см. §2.1 проJ1..J3/Itime). docs.amnezia.org — описание протокола и версий (1.0 / 1.5 / 2.0); поколение AWG 3+ документировано только в README amneziawg-go (§2.1.1). awg show <iface>/awg showconf <iface>— что демон реально принял. Если вshowconfнет вашихI1/S3/H*— значит доawg setconfони не дошли (см. §3, §12). Это первичная диагностика.- Наш код —
core/awg_config.py(парсер/генератор.conf, ключи),core/awg_manager.py(up/down/status/diagnostics),core/awg_platform.py(пути),core/awg_installer.py+core/awg_detector.py(бинари/арх),core/warp_generator.py+core/warp_importer.py+core/awg_warp_in_warp.py(WARP),core/ndms/wg_discovery.py(нативный WG Keenetic),core/awg_watchdog.py,core/awg_autostart_manager.py+core/awg_init_script.py,api/awg.py,web/js/pages/awg_*.js.
⚠️ Версия протокола — главный источник «handshake есть, трафика нет». AmneziaWG несовместим между мажорными версиями обфускации (§2.3). Если клиент шлёт data-пакеты в формате одной версии, а пир ждёт другую — handshake проходит (он на общих параметрах), а transport-пакеты дропаются. Классическая картина в
awg show:transfer: 92 B received, 20 KB sent— мы отправляем, сервер молчит. См. §12.
1. Как AWG используется в zapret-gui
Модель: один туннель = один сетевой интерфейс (как у WireGuard; в отличие
от sing-box, где инстанс = файл). Имя инстанса = имя .conf без расширения и =
имя интерфейса (конфиг awg0.conf → интерфейс awg0).
Мы НЕ используем awg-quick. Логику wg-quick (Address/MTU/Table/DNS/
PreUp…PostDown, маршруты из AllowedIPs) мы реализуем сами в
awg_manager._do_up, а ядро поднимаем напрямую:
amneziawg-go <iface> # форкает userspace-демон + TUN-устройство
awg setconf <iface> <filtered.conf> # заливает крипто + обфускацию в демон
ip link set dev <iface> mtu <MTU>
ip addr add <Address> dev <iface>
ip link set dev <iface> up
ip route add <AllowedIPs> dev <iface> table <id> # если Table != off
Почему так, а не awg-quick up: на Keenetic/Entware нет полноценного bash и
ряда утилит, которые тянет awg-quick; нам нужен контроль над таблицами
маршрутизации (Selective routing GUI) и устойчивый teardown. Поэтому
amneziawg-go (userspace) + awg setconf + ручной ip — наш базовый путь.
Поток:
- Конфиги лежат в
platform.config_dir(Keenetic:/opt/etc/amneziawg/). CRUD — черезapi/awg.pyповерхcore/awg_config.py. awg setconfполучает НЕ весь.conf, а отфильтрованный (толькоWG_INTERFACE_FIELDS+WG_PEER_FIELDS, §3) — wg-quick-поля демон не понимает.- Маршрутизация GUI поверх:
target_iface = <iface>, правила навешиваетcore/routing/applierпри подъёме интерфейса.
2. Параметры обфускации AmneziaWG (официальная истина)
AmneziaWG — форк WireGuard-Go, который убирает узнаваемые DPI-сигнатуры
WireGuard, сохраняя его крипто и производительность. Все «магия» —
дополнительные поля в секции [Interface] (в README апстрима эта секция
называется [Device]). Какие из них обязаны совпадать с пиром, а какие
задаются только на клиенте — см. таблицу «сторон» ниже: путать их дорого.
Если все параметры = 0 → ведёт себя как обычный WireGuard (для плавной
миграции), и «значение не задано» апстрим трактует именно как 0.
2.1 Таблица параметров (источник: amneziawg-go README + docs.amnezia.org)
| Параметр | Что делает | Диапазон/рекомендация | Версия |
|---|---|---|---|
| Jc | Кол-во junk-пакетов перед handshake (после I1–I5) | рекоменд. 4–12 (docs: 0–10) | 1.0 |
| Jmin | Мин. размер junk-пакета | байты; Jmin ≤ Jmax | 1.0 |
| Jmax | Макс. размер junk-пакета | байты; Jmax < MTU (иначе фрагментация); docs: 64–1024 | 1.0 |
| S1 | Префикс-padding handshake init | 0–64 байт | 1.0 |
| S2 | Префикс-padding handshake response | 0–64 байт | 1.0 |
| S3 | Префикс-padding handshake cookie | 0–64 байт | 2.0 |
| S4 | Префикс-padding transport (data) | 0–32 байта | 2.0 |
| H1 | Магический заголовок (тип) пакета init | 0…4294967295 | 1.0 |
| H2 | Магический заголовок пакета response | 0…4294967295 | 1.0 |
| H3 | Магический заголовок пакета cookie | 0…4294967295 | 1.0 |
| H4 | Магический заголовок transport (data) | 0…4294967295 | 1.0 |
| I1…I5 | Signature-пакеты перед handshake (мимикрия под реальный протокол); отправляются по порядку I1→I5, пропускаются, если значение не задано | последовательность тегов, §2.1.2 | 1.5 |
| J1…J3 | Доп. junk-параметры | — | 1.5, удалены в 2.0 |
| Itime | Тайминг signature-пакетов | — | 1.5, удалён в 2.0 |
Где параметр обязан совпадать с пиром. README amneziawg-go вводит явное
деление: server-side — значение ОБЯЗАНО быть одинаковым на обоих концах,
client-side — можно задавать только у клиента.
| Параметр | Сторона | Практический вывод |
|---|---|---|
Jc/Jmin/Jmax | client-side | «Junk-пакеты не несут данных, задавать на обеих сторонах не требуется; общая рекомендация — только на клиенте» (README). Поэтому junk и работает против ванильного WireGuard-пира (§8.1) |
I1…I5 | client-side | то же самое: signature-пакеты пир просто игнорирует |
S1–S4, H1–H4 | должны совпадать | это формат САМИХ пакетов, пир обязан уметь их разобрать |
HeaderProtectionKey | server-side | ключ защиты заголовка (§2.1.1) |
ContentPaddingAddition, тайминги, PersistentKeepalive | client-side | «важно задать паддинг с обеих сторон, но строго не обязательно» |
Тип range,x (AWG 3): значение может быть "a-b", "a" или "(off)" —
например PersistentKeepalive = 22-30. Значение не задано = 0 для любого
параметра.
2.1.2 Синтаксис I1…I5 — это НЕ просто hex
Значение I1..I5 — последовательность тегов (README amneziawg-go, раздел
«Custom signature packets»):
| Тег | Что кладёт в пакет |
|---|---|
<b 0x[seq]> | статические байты: [seq] — hex-строка чётной длины (2 знака на байт) |
<r [size]> | [size] случайных байт |
<rd [size]> | [size] случайных цифр [0-9] |
<rc [size]> | [size] случайных букв [a-zA-Z] |
<t> | 4 байта текущего времени в формате UNIX |
Теги можно комбинировать в одной строке. Наш парсер (§3.2) заточен под самый
частый случай — многострочный <b …> — и остальные теги переносит как есть
(мы их не интерпретируем, это делает демон). Если правишь parse_conf, не
считай, что содержимое I* обязано быть hex: <r 32><t> — валидное значение.
Jmaxи MTU. README: «еслиJmax≥ системного MTU (не того, что задан в AWG), система нарежет пакет на фрагменты, что со стороны цензора выглядит подозрительно». То же про итоговый размер signature-пакета.
⚠️
J1..J3иItimeнельзя отдавать вawg setconf— вообще никогда. Их нет вkey_matchпарсера amneziawg-tools (src/config.c) ни в одном релизе, включая свежийv3.1.20260812. На неизвестном ключе парсер делаетgoto error: печатаетLine unrecognized: '<строка>'и отбрасывает конфиг целиком. То есть один лишний ключ из чужого.conf= интерфейс не поднимается вовсе, а наружу видно лишь невнятное «Unable to modify interface». Разбирать и сохранять их при round-trip мы обязаны (профиль из клиента Amnezia не должен терять поля), а в setconf — не отдаём:AWG_FIELDS_UNSUPPORTED_BY_TOOLS+_setconf_skip_fieldsвcore/awg_config.py, сторож —tests/test_awg_config.py.
2.1.1 AWG 3+: защита заголовка, паддинг содержимого, тайминги
Ветка amneziawg-go v3.x (текущая; сверено с README v3.1.20260814 —
на 3.1 он не менялся) добавила
поколение параметров, которое апстрим маркирует как [AWG 3+]. В .conf
они живут в секции устройства ([Device] в терминах README = [Interface] в
терминах wg-quick):
| Ключ | Тип / сторона | Назначение |
|---|---|---|
HeaderProtectionKey | key,string, server-side | Ключ шифрования низкоэнтропийных полей заголовка — тех, что WireGuard использует для аутентификации и собственного шифрования. Нонсом служит crypto-паддинг S1–S4. Генерируется awg genkey |
ContentPaddingAddition | uint32,range, client-side | Дополнительный паддинг содержимого |
RekeyAfterTime | uint32,range, сек | Через сколько клиент пробует сделать handshake |
RekeyTimeout | uint32,range, сек | Таймаут, после которого handshake повторяется |
RejectAfterTime | uint32,range, сек | Когда клиент форсирует handshake и отвергает входящие данные |
KeepaliveTimeout | uint32,range, сек | Через сколько после последней отправки данных шлётся keepalive |
MaxHandshakeAttempts | uint32,range | Предел попыток handshake |
⚠️ Защита заголовка требует
S1–S4не меньше 12 (README, «Header protection»): паддинг служит нонсом шифра.HeaderProtectionKeyприS*< 12 — нерабочая связка.
Все семь ключей принимаются парсером tools — они есть в key_match
(src/config.c, v3.0.20260730 и новее), в отличие от J1..J3/Itime.
То есть в awg setconf их отдавать можно и нужно.
Наш статус: поддержаны — константа AWG3_INTERFACE_FIELDS в
core/awg_config.py входит в WG_INTERFACE_FIELDS, поэтому поля переживают
round-trip и доходят до демона. validate() проверяет их как тип range
("a-b" / "a" / "(off)" — числом их валидировать нельзя),
HeaderProtectionKey — как base64-ключ на 32 байта, и отдельно ругается,
если при заданном ключе минимальный из S1..S4 меньше
AWG3_HEADER_PROTECTION_MIN_S (12).
⚠️ Раньше этих полей в списке не было, и AWG3-профиль молча терял их при
render_setconf: демон поднимался без защиты заголовка, а пир, который её ждёт, дропал data-пакеты — тот самый «92 B in / 20 KB out» (§12). Тесты-сторожа:TestAwg3Fieldsвtests/test_awg_config.py.
2.1.2 AWG 3.1: случайные хвосты и отказ от cookie-ответов
Пара amneziawg-go v3.1.20260814 + amneziawg-tools v3.1.20260812
добавила ровно два ключа в секцию устройства. В README их нет — источник
истины здесь только код: device/uapi.go (UAPI-ключи) и src/config.c
(key_match).
| Ключ | UAPI-ключ | Тип | Назначение |
|---|---|---|---|
RandomTrailers | random_trailers | bool | Дописывать служебным пакетам (init / response / cookie) хвост случайной длины — до размера UDP-окна пира. Размер пакета перестаёт быть константой, по которой его опознаёт DPI |
DisableCookies | disable_cookies | bool | Не отвечать cookie-reply на отброшенный handshake. Cookie-ответ — заметная сигнатура WireGuard, но это же и штатная анти-DoS-защита |
⚠️
RandomTrailersсимметричен — включать надо на ОБОИХ концах. Приёмник опознаёт служебный пакет по точному размеру и допускает больший только при включённом флаге (DeterminePacketTypeAndPaddingвdevice/receive.go). Включён у клиента и выключен у сервера — handshake не проходит вовсе: пакет просто не распознаётся как init.
⚠️ Значение пишется как
on/offили число, но НЕtrue/false.parse_boolвsrc/config.cзнает толькоon/off(без учёта регистра) и десятичное число (0= выкл). Наtrueон печатает «Boolean value is neither on/off nor 0/1» и, как на любой ошибке разбора, отбрасывает конфиг целиком. Нашvalidate()ловит это на импорте, пока ещё видно, какое поле виновато.
⚠️ Это отдельная планка поколения, а не «ещё два поля AWG 3+». Движок
v3.0.xна этих UAPI-ключах отвечаетinvalid UAPI device key→ EINVAL → знакомое «Unable to modify interface: Invalid argument». Поэтомуrequired_generation()поднимает такой профиль до 3.1, а не до 3.0: подсказка «нужен AWG 3.0» пользователю, у которого как раз 3.0, увела бы совсем не туда.
Наш статус: поддержаны — AWG31_INTERFACE_FIELDS в core/awg_config.py
входит в WG_INTERFACE_FIELDS, поэтому поля переживают round-trip и доходят
до awg setconf.
2.1.2а Поле [Peer] AdvancedSecurity
В key_match секции [Peer] у tools, кроме стандартных PublicKey,
PresharedKey, AllowedIPs, Endpoint, PersistentKeepalive, есть ещё
AdvancedSecurity (флаг «продвинутой безопасности» для конкретного пира).
Он есть и в нашем WG_PEER_FIELDS, так что импортированный профиль его не
теряет.
PersistentKeepalive в AWG 3+ — тоже тип range: валидны 25, 22-30 и
(off). validate() принимает все три формы и проверяет границы 0..65535
для числовых.
Junk vs padding vs header — не путать.
Jc/Jmin/Jmax— отдельные мусорные пакеты ДО рукопожатия.S1–S4— случайный префикс ВНУТРИ реальных пакетов каждого типа.H1–H4— подменяют первый байт (тип сообщения), чтобы DPI не видел сигнатуру WireGuard.
2.2 H1–H4: ограничения
- Стандартный WireGuard использует типы сообщений 1, 2, 3, 4 (init/
response/cookie/transport).
H1–H4их заменяют — но это работает, только если AmneziaWG-обфускацию понимает и пир. Cloudflare WARP — это ВАНИЛЬНЫЙ WireGuard, онH1–H4 ≠ 1,2,3,4не понимает и дропает handshake. Поэтому для WARPwarp_generatorоставляетH1=1, H2=2, H3=3, H4=4(иS1=S2=0), а обфускацию даёт только junk-пакетами (Jc/Jmin/Jmax) — их ванильный WireGuard просто игнорирует. НестандартныеH*(5 … 0x7FFFFFFF) уместны лишь для AmneziaWG-aware сервера, не для чистого WARP (core/warp_generator.py). Проверено локально: против ванильного WG-пира handshake проходит ТОЛЬКО приS1=S2=0иH1..H4=1,2,3,4; рандомныеH*илиS>0→ handshake не идёт. - В AmneziaWG 2.0 у
H1–H4появилась поддержка диапазонов (range): значения выбираются случайно в заданном окне и не должны перекрываться. В.confэто строка видаH1 = 123-456.parse_confхранитH*как строки, аvalidate()принимает дляH1–H4либо одиночный uint, либо диапазонN-M(N<=M); прочие числовые поля обфускации остаются строгими int. amneziawg-tools (src/config.c) хранитH*как opaque-строки (parse_awg_string) — так что это лишь GUI-санити-чек формата.
2.3 Версии протокола и совместимость (КРИТИЧНО)
| Версия | Что добавляет | Параметры |
|---|---|---|
| 1.0 | базовая обфускация: junk + magic-headers + padding init/response | Jc, Jmin, Jmax, S1, S2, H1–H4 |
| 1.5 | мимикрия под обычные UDP-протоколы (QUIC, DNS…) через signature-пакеты | + I1–I5, J1–J3, Itime |
| 2.0 | «полная мимикрия»: меняющиеся заголовки и размеры пакетов и в data-фазе | + S3, S4; range для H1–H4; − J1–J3, Itime |
3.0 (AWG 3+) | шифрование полей заголовка, кастомный паддинг содержимого, настраиваемые тайминги WireGuard | + HeaderProtectionKey, ContentPaddingAddition, RekeyAfterTime, RekeyTimeout, RejectAfterTime, KeepaliveTimeout, MaxHandshakeAttempts; тип range у таймингов и PersistentKeepalive (§2.1.1) |
| 3.1 | случайная длина служебных пакетов, отказ от cookie-ответов | + RandomTrailers, DisableCookies (bool, on/off; §2.1.2) |
Нумерация версий ≠ нумерация релизов, но с 3.0 они совпали.
amneziawg-goпрыгнул сv0.2.19сразу наv3.0.0, и[AWG 3+]в README — это ровно поколение параметров этой ветки. Пользователь со старым бинарём (v0.2.x) AWG3-полей не понимает: демон их не применит, аawgиз старогоamneziawg-tools(v1.0.2026*) на них ещё и отбросит весь конфиг (Line unrecognized). То есть «профиль AWG3 + старая пара бинарей» = туннель не поднимется вовсе, а не деградирует.
Версия должна совпадать на обоих концах. Подключиться по 2.0 к старому пиру нельзя; в старом AmneziaVPN профиль 2.0 даже не покажется, хотя сервер его поддерживает (docs.amnezia.org). Это и есть инженерная причина "92 B in / 20 KB out": handshake собирается на общих параметрах и проходит, а data-пакеты пир дропает, потому что ждёт другой набор обфускации (например, на сервере включены S3/S4/I1, а в нашем конфиге их нет — или наоборот, мы их потеряли при парсинге, см. §3).
3. Формат .conf и наш парсер (core/awg_config.py)
API модуля: parse_conf(text) -> {"interface": {...}, "peers": [{...}]},
render_conf(cfg) -> text, validate(cfg) -> [errors], generate_keypair().
3.1 Какие поля куда идут
| Группа | Константа | Куда применяется |
|---|---|---|
| Крипто + ListenPort + FwMark + вся обфускация | WG_INTERFACE_FIELDS | в демон через awg setconf |
Address, DNS, MTU, Table, PreUp, PostUp, PreDown, PostDown, SaveConfig | WGQUICK_INTERFACE_FIELDS | наша wg-quick-логика в _do_up (демон их НЕ видит) |
PublicKey, PresharedKey, AllowedIPs, Endpoint, PersistentKeepalive | WG_PEER_FIELDS | в демон через awg setconf |
WG_INTERFACE_FIELDS содержит: PrivateKey, ListenPort, FwMark, обфускацию v1
(Jc, Jmin, Jmax, S1, S2, H1, H2, H3, H4) и расширенную (S3, S4, I1–I5, J1–J3, Itime). Числовые валидируются как int (AWG_OBFUSCATION_FIELDS), а
H1–H4 — как int ИЛИ диапазон N-M (§2.2); hex-blob I1–I5, J1–J3 — отдельно
(AWG_V2_BLOB_FIELDS).
Голого поля
Iв AmneziaWG нет — signature-пакеты этоI1…I5(подтверждено парсером amneziawg-toolssrc/config.c:key_matchтолькоI1..I5). РаньшеIошибочно числился в наших списках как «v1»-параметр; убрано (см. CHANGELOG), чтобы случайныйI=не ушёл вawg setconf— иначе тулза отбросила бы весь конфиг. Расширенный набор у нас исторически назван «v2», хотя по docs.amnezia.orgJ1–J3/Itimeотносятся к 1.5 и удалены в 2.0 — мы их просто пропускаем как есть, решение принимает движок.
3.2 Парсинг hex-blob I1–I5 (многострочный <b …>) — частый баг
I1…I5 в .conf приходят как бинарный blob в одной из форм:
# однострочная
I1 = <b 0xf6ab...>
# многострочная (закрывается '>' или новым 'Key=' или пустой строкой)
I1 = <b
0xf6ab34c1...
9d2e...
>
parse_conf накапливает hex-куски (pending_*/flush_pending) и склеивает их.
Без этой обработки парсер брал только <b, и I1 терялся при
render_setconf → handshake проходил, а сервер дропал data → ровно «92 B in /
20 KB out». Если меняешь парсер — не сломай blob-склейку; тесты —
tests/test_awg_config.py.
3.3 Прочее
- Голым адресам без маски
parse_confдобавляет/32//128, чтобыawg/ipих приняли. _is_base64_keyпроверяет ключи: 44 символа, заканчивается=, декодится в 32 байта.validate()ругается на кривые ключи/Endpoint/AllowedIPs.render_confпишет полный.conf(для хранения/показа), а вawg setconfуходит отфильтрованный временный файл (только setconf-поля).
4. Инструменты AmneziaWG (CLI)
Форк wireguard-tools, CLI идентичен — просто awg вместо wg:
| Команда | Назначение | Используем мы? |
|---|---|---|
awg show [<iface>] [dump] | статус: handshake, transfer, endpoint, allowed-ips | да (status/diagnostics; dump — таб-разделённый машинный вид) |
awg showconf <iface> | дамп активного конфига демона | да (диагностика — что реально принято) |
awg setconf <iface> <file> | залить конфиг в демон (replace) | да (основной путь конфигурации) |
awg syncconf <iface> <file> | применить дельту без сброса peers | нет (мы делаем setconf при up) |
awg genkey / pubkey / genpsk | генерация ключей | через наш generate_keypair (Python) |
awg set <iface> … | точечная правка | нет |
awg-quick up/down <conf> | bash-обёртка (Address/MTU/Table/routes/DNS) | НЕТ — реализуем сами (§1) |
amneziawg-go <iface> | запустить userspace-демон + TUN | да (это и есть «движок») |
Альтернативы userspace-демону: модуль ядра amneziawg (DKMS /
amneziawg-linux-kernel-module). Мы ставим/детектим userspace amneziawg-go
(§7) — он не требует сборки под ядро роутера.
5. Жизненный цикл туннеля (awg_manager)
5.1 Подъём — _do_up
validate()конфига; если ошибки — не стартуем.PreUp-хуки.amneziawg-go <iface>(subprocess) — форкает демон + TUN. PID находим черезpgrep, пишем в<run_dir>/awg-<iface>.pid.- короткая пауза (UAPI-сокет
/var/run/wireguard/<iface>.sockдолжен подняться). awg setconf <iface> <filtered.conf>— крипто + обфускация.ip link set dev <iface> mtu <MTU>(если задан).ip addr add <Address>(каждый адрес).ip link set dev <iface> up.- маршруты из
AllowedIPs→table <id>(еслиTable != off).id— стабильный хэш имени интерфейса в диапазоне 100…999. - снимок состояния
<run_dir>/awg-<iface>.last_up.json+ список добавленных маршрутов<run_dir>/awg-<iface>.routes.json(чтобы корректно снять при down). PostUp-хуки →core.routing.applier.apply_all_on_interface_up().
5.2 Снятие — _do_down
Обратный порядок: PreDown → снять правила роутинга → удалить добавленные
маршруты → ip link down → ip link delete dev <iface> → SIGTERM (затем
SIGKILL) демону по PID → удалить pid-файл и UAPI-сокет → PostDown →
откат auto-dnsmasq (если это был последний AWG-интерфейс).
restart = down → up. status(name) парсит awg show <iface> dump
(per-peer: latest_handshake unix-ts, rx_bytes, tx_bytes).
6. Платформенные пути (awg_platform)
| Keenetic/Entware | OpenWrt | Generic Linux | |
|---|---|---|---|
| bin | /opt/usr/sbin | /usr/sbin | /usr/local/bin |
| config | /opt/etc/amneziawg | /etc/amneziawg | /etc/amneziawg |
| run | /opt/var/run/awg | /var/run/awg | /var/run/awg |
| init | /opt/etc/init.d | /etc/init.d | /etc/systemd/system |
Файлы в run_dir: awg-<iface>.pid, awg-<iface>.routes.json,
awg-<iface>.last_up.json.
UAPI-сокет демона лежит НЕ в нашем run_dir — путь задаёт сам движок:
| Бинарь | Каталог сокета |
|---|---|
amneziawg-go v3.x | /var/run/amneziawg/<iface>.sock (ipc/uapi_unix.go: var socketDirectory = "/var/run/amneziawg") |
awg (tools v3.1.20260812) | тот же: SOCK_PATH RUNSTATEDIR "/amneziawg/" (src/ipc-uapi-unix.h) |
унаследованный от wireguard-go (старые сборки v0.2.x) | /var/run/wireguard/<iface>.sock |
Единый список каталогов — awg_platform.UAPI_SOCKET_DIRS (v3-путь первым);
platform.uapi_paths(iface) отдаёт все кандидаты, uapi_path(iface) —
существующий, иначе путь текущей ветки. Подчистка в
awg_manager._cleanup_iface() и поиск интерфейсов в awg_detector обходят
оба каталога: на роутере вполне может стоять и старый amneziawg-go.
Раньше оба места были захардкожены на
/var/run/wireguard/, и с бинарями v3 сокет после SIGKILL оставался лежать, а обнаружение интерфейсов по сокетам не находило ничего. На путь ЗАПУСКА это не влияло и не влияет —_do_upсокет намеренно НЕ ждёт (был регресс, ронявший AWG на Keenetic, см. комментарий в_do_up). Сторож —TestUapiSocketDirsвtests/test_awg_manager_lifecycle.py.
Shortened here. Read the whole file on GitHub.
Signals
- GitHub stars
- 133
- Forks
- 10
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
awg- Source
- github.com/avatardd/zapret-gui