Уточнения к разбору AmneziaWG 3.0: набор тегов CPS расходится между реализациями, плюс обновления после 4 августа #1
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Здравствуйте.
Я мейнтейнер
amneziawg-installer. Сверил ваш разбор третьего поколения с исходниками и хочу предложить четыре уточнения. Первое относится к самому разбору, два следующих - обновления после 4 августа (на вашу дату всё было верно), последнее - мой замер, дополняющий ваше наблюдение по коду.1. Набор тегов CPS расходится между реализациями
В
internalsсказано, что в коде зарегистрировано восемь тегов:<b>,<r>,<rc>,<rd>,<t>плюс недокументированные<d>,<ds>,<dz>. Это верно дляamneziawg-go, но у модуля ядра набор другой, и расходятся они в обе стороны:src/junk.cdevice/obf.go<b>,<r>,<rc>,<rd>,<t><c>(счётчик пакетов пира, u32 BE)<d>,<ds>,<dz>-EINVALГде смотреть: в модуле -
jp_parse_tags()вsrc/junk.c, таблица черезstrcmpс финальнымelse return -EINVAL; тегcразбирается вparse_c_tag, а пишет счётчик уже функция-модификаторpkt_counter_modifier. В go - mapobfBuildersи функцияnewObfChainлежат вdevice/obf.go, а вызывается она изdevice/uapi.go, отдельной строкой на каждый изi1-i5.Практическое следствие: конфиг с
<c>работает на ноде с модулем ядра и не поднимается на userspace, то есть в LXC и Docker, на роутерах, на macOS. И наоборот,<d>/<ds>/<dz>модуль ядра отвергает целиком. Отказ в обоих случаях жёсткий, но заметен по-разному. go возвращает наружу готовую строкуfailed to parse I1: unknown tag <c>. Модуль ядра возвращает-EINVAL, а поясняющую строкуI1-packet invalid formatпечатает черезnet_dbg_ratelimited(), то есть вdmesgона видна только при включённом dynamic debug для модуля. Без него человек получает голый отказ без причины - и это, возможно, объясняет часть жалоб вида «интерфейс просто не поднимается, в логе пусто».Отсюда правило, которое я держу у себя: любой рецепт
I1, предлагаемый людям, должен использовать только пересечение{b, r, rc, rd, t}.2. Вышла 3.1, PPA раздаёт её
12 августа внутри третьей линии вышел
v3.1.20260812с двумя новыми параметрами устройства:RandomTrailers- случайный хвост к пакетам рукопожатия. Двусторонний: приёмник без флага удлинённый пакет не опознаёт, поэтому включение только на одной стороне рвёт рукопожатие. Вamneziawg-go(device/receive.go) гейт стоит на init, response и cookie, а транспорт проверяется какsize >= expectedSizeуже без флага; в модуле ядра я этот механизм не проверял, но вывод про двусторонность от этого не меняется.DisableCookies- сервер перестаёт слать cookie-ответы. Односторонний.WG_GENL_VERSIONне менялся, то есть утилиты 3.0 работают с модулем 3.1. PPA раздаёт эту сборку с 12 августа; на 17 августа тамamneziawg-dkms 1.0.0-0~202608140352+4680320, где4680320- сокращённый хеш коммита46803204e7ec, помеченного тегомv3.1.20260812.К вашему чек-листу про ревизию модуля: версию загруженного модуля показывает
cat /sys/module/amneziawg/version. Версия apt-пакета для этого не годится - она начинается с1.0.0(это версия упаковки изdkms.conf), и линию видно только по хешу в конце строки.3. PR 2908 в amnezia-client смержен
В
referenceсказано, что поддержка self-hosted живёт в незакрытом PR #2908. Он смержен 6 августа: 9 коммитов, 40 файлов. Но смержено не выпущено: последний релиз приложения - 5.0.0.5 от 26 июля, то есть вышел раньше мержа.4. Паддинг keepalive: побочный эффект, который я воспроизвёл
Вы отметили, что keepalive получает
S4и content padding. У этого поведения есть побочный эффект.При ненулевом
S4keepalive классифицируется как пакет с данными, и это сбрасывает таймер, отвечающий за паузу перед новым рукопожатием. На простаивающем туннеле частота рукопожатий вырастает примерно в десять раз: на стенде медиана интервала составила 15,0 с против 147,0 с у контроля, причинность доказана A/B/A с однострочным патчем.Границы замера: воспроизведено на модуле ядра. В проверенных версиях
amneziawg-goдефект дал те же 15,0 с наv3.0.3, но не воспроизвёлся наv0.2.19, где медиана составила 132,0 с; линию 3.1 этим замером я не проверял. Для модуля ядра дефект разобран в issue #186 и исправлен PR #208, я прогнал фикс на стенде 6 августа - медиана вернулась к 147,0 с.Что из этого следует для вашего текста: паддинг убирает постоянную длину keepalive, но в измеренном сценарии простаивающего туннеля дефект примерно десятикратно увеличивал частоту рукопожатий, а перед каждым уходят
Jcмусорных иI1-I5сигнатурных пакетов. Влияние этого на обнаруживаемость я отдельно не измерял.Если понадобятся методика и сырые результаты замера по последнему пункту, приложу их сюда.
Спасибо исправили. Присылайте больше фактов будем только рады.
Спасибо, что учли. Тогда одно уточнение к разбору тегов и пара наблюдений из поля.
Про LXC и Docker. У вас сказано, что конфигурация с
<c>не поднимется на userspace-движке, «то есть в LXC и Docker, на роутерах, на macOS». С движками так и есть, а вот привязка к типу узла держится не всегда: в контейнере реализацию выбирает хост.awg-quickизamneziawg-toolsсначала пробует ядро и уходит в userspace только при неудаче - функцияadd_if()вsrc/wg-quick/linux.bash. Причём условие там написано так, что при существующем/sys/module/amneziawgотката не будет вовсе, команда просто упадёт. АWG_QUICK_USERSPACE_IMPLEMENTATIONпроверяется внутри той же ветки отката, так что штатного способа удержать контейнер на go, когда модуль на хосте есть, нет.Модуль хоста контейнеру при этом виден:
run_container.shвamnezia-clientзапускает его с--privileged --cap-add=SYS_MODULEи монтирует/lib/modules. Образ собран отamneziavpn/amneziawg-go, а скрипты подготовки хоста модуль не ставят - потому он и живёт на go, пока модуля нет. А появитсяamneziawg-dkms- и тот же контейнер с нетронутой конфигурацией меняет допустимый набор тегов на противоположный. Поставить пакет при этом могло что угодно рядом, к контейнеру отношения не имеющее.Наткнулся я на это, разбирая жалобу пользователя моего установщика: у него перестал принимать подключения контейнер AWG 2.0, а соседний, на обычном WireGuard, работал как ни в чём не бывало. Диагноз по исходникам. На стенде не воспроизводил - для чистого «до» нужен хост без модуля, а у меня он уже стоял.
Теперь наблюдения. Оба про 2.0, по третьему поколению отчётов у меня нет. Но для раздела про диагностику, наверное, сгодятся: в обоих случаях человек описывал это как «не работает на операторе X», а картина была разная.
26 июня, МТС. На
39743/udpтуннель не поднимался, на443/udpвстал сразу - тот же конфиг, тот же сервер. Для контроля: на трёх домашних провайдерах в Москве этот же сервер работал на исходном порту, и потери в туннеле были как у обычного UDP до того же адреса. Почему так, не знаю: проверял только сам факт. Тогда же ещё один человек писал про похожее на МТС: не поднимается, пресетmobileне спасает. Его порт и чем всё кончилось, мне неизвестно.6 августа, другой человек, тоже сотовая. Порт не трогал вообще, помогла смена IP: попросил у хостера другой адрес, подставил его на сервере и в клиентах, заработало и на сотовой, и дома. Он же проверил, что VPS в той же стране у другого хостера поднимается из коробки. Менялся, получается, адрес и всё, что с ним связано, а порт и обфускация оставались теми же; одной страной это не объяснить. Если повторится уже на новом адресе, стоит просить у хостера адрес из другой подсети, а не соседний из того же пула.
Там же нашлась деталь, из-за которой я и пишу этот пункт: вместе с туннелем не отвечали SSH и пинг до того же адреса. Значит дело было в самом адресе или маршруте до него, а не в AmneziaWG. Блокировка, фильтр у хостера, упавшая машина, маршрутизация - не разбирался.
С тех пор это у меня первый шаг: пока не проверил сам адрес, в том числе из другой сети, крутить обфускацию и порт рано. Если недоступен весь адрес, конфигурация не поможет - как раз то, про что у вас написано, что смена протокола такое не лечит.
Понадобятся подробности по любому из двух - скажите, приложу.
Ivan Bondarev (bivlked)
Переключение не мгновенное а так исправили.