mikwg — AmneziaWG 3.1 на MikroTik RouterOS
Клиент AmneziaWG 3.1 для роутеров MikroTik (RouterOS 7.24+, ARM64), который
использует штатный kernel WireGuard роутера и компактный контейнер-конвертер
(awg-converter). На выходе — полноценный AmneziaWG 3.1 без выноса секретов за
пределы RouterOS и без потери производительности ядра на шифровании.
Как это работает
[LAN] → WireGuard (ядро RouterOS; приватный ключ только здесь)
→ container: awg-converter (обфускация пакетов)
→ [AmneziaWG 3.1 сервер]
AmneziaWG не меняет криптографию WireGuard: все его механизмы — внешние слои над
пакетом. Конвертер «переодевает» пакеты на лету, а AEAD/MAC остаются
нетронутыми. Подробности формата — в
docs/protocol-notes.md.
Модель безопасности: конвертеру доступны только параметры обфускации и
метаданные трафика. Приватный ключ WireGuard существует только в
/interface/wireguard RouterOS и в контейнер не передаётся.
Требования
- MikroTik ARM64 (проверялось на RB5009 и hAP ax³, RouterOS 7.24.5), RouterOS 7.24+
- Рабочая конфигурация роутера — mikwg не выполняет factory reset и не заменяет вашу конфигурацию, а дополняет её
- Пакет
containerтой же версии RouterOS - Внешний носитель (USB/SATA), смонтированный в RouterOS: на нём лежит образ
контейнера (по умолчанию
usb1/images/awg-converter, stagingusb1/tmp).awg0.confна роутере не нужен — параметры обфускации передаются в контейнер как environment-переменные - ≥ 64 МБ свободного места во flash (сам образ кладётся на носитель)
- Конфиг AmneziaWG 3.1 (поля
S1-S4,H1-H4,HeaderProtectionKey,Jc/Jmin/Jmax,I1-I5) - Готовый бинарник
rscgenиз релиза — для установки; Go 1.26+ — только для сборки из исходников - Доступ роутера в интернет для загрузки образа из Docker Hub (для оффлайн-установки из tar не требуется)
Быстрый старт
Установка состоит из двух частей: сначала на компьютере вы готовите скрипт установки, затем один раз импортируете его на роутер. Ниже — по шагам.
Шаг 0. Что понадобится
- Роутер MikroTik на ARM64 (например, RB5009 или hAP ax³) с RouterOS 7.24 или новее.
- Доступ к роутеру через Winbox (или SSH/Terminal). Заранее убедитесь, что изменения не отрежут вам доступ к управлению (подключайтесь по LAN-порту или Winbox-by-MAC).
- Конфиг AmneziaWG — файл
awg0.conf. - Компьютер (Windows, macOS или Linux) — на нём генерируется скрипт.
- USB-флешка или диск, подключённый к роутеру: образ контейнера не помещается
во встроенную память. Носитель будет виден в RouterOS как
usb1(илиdisk1). - Интернет на роутере — образ скачивается из Docker Hub самим роутером.
Номер последней версии всегда можно посмотреть в бейдже в начале этой страницы или на странице релизов.
Шаг 1. Возьмите конфиг AmneziaWG (awg0.conf)
Файл должен содержать параметры обфускации (S1–S4, H1–H4,
HeaderProtectionKey, Jc/Jmin/Jmax, I1–I5) и адрес сервера (Endpoint).
Если файла нет — возьмите его у VPN-провайдера или экспортируйте из клиента
AmneziaWG.
Шаг 2. Скачайте генератор rscgen
Генератор запускается на компьютере и превращает awg0.conf в скрипт для
роутера. Откройте
страницу последнего релиза,
в разделе Assets скачайте файл под вашу систему:
| Ваша система | Файл |
|---|---|
| macOS (Apple Silicon, M1–M4) | rscgen-<версия>-darwin-arm64 |
| macOS (Intel) | rscgen-<версия>-darwin-amd64 |
| Linux | rscgen-<версия>-linux-amd64 |
| Windows | rscgen-<версия>-windows-amd64.exe |
На macOS и Linux сделайте его исполняемым (в терминале, в папке с файлом):
chmod +x rscgen-<версия>-darwin-arm64
Если у вас установлен Go 1.26+, скачивать ничего не нужно — вместо имени файла используйте
go run github.com/nskforward/mikwg/cmd/rscgen@latest.
Шаг 3. Сгенерируйте скрипт установки
Положите awg0.conf и скачанный rscgen в одну папку и выполните из неё:
# macOS / Linux
./rscgen-<версия>-darwin-arm64 -conf awg0.conf -out routeros.generated.rsc
# Windows (PowerShell)
.\rscgen-<версия>-windows-amd64.exe -conf awg0.conf -out routeros.generated.rsc
Рядом появится файл routeros.generated.rsc — это и есть скрипт для
роутера. По умолчанию в него подставляется образ nskforward/mikwg:latest
(самый свежий релиз).
🔒 Файл
*.generated.rscсодержит приватный ключ WireGuard — не коммитьте его в git (он уже в.gitignore) и не передавайте третьим лицам.
⚠️ Антилуп-маршрут до IP сервера должен указывать на реальный next-hop (
gateway=192.168.1.1), а не на интерфейс (gateway=ether1).rscgenопределяет next-hop автоматически; переопределить можно флагом-wan-gw(именно IP шлюза, не интерфейс). Подробнее — вdocs/advanced.md.
Шаг 4. Подготовьте роутер (один раз)
⚠️ mikwg никогда не сбрасывает роутер: ни
rscgen, ни сгенерированный скрипт не содержатreset-configuration. Установка идёт поверх вашей рабочей конфигурации. Перед началом прочитайтеdocs/safe-operations.md.
- Сделайте и скачайте бэкап. В терминале роутера:
Затем в Winbox откройте Files, выделите
/system/backup/save name=pre-mikwg /export file=pre-mikwg-exportpre-mikwg.backupиpre-mikwg-export.rscи перетащите их на рабочий стол компьютера кнопкой Download (или Drag&drop). - Установите пакет
container. Откройте mikrotik.com/download, выберите свою модель роутера и ту же версию RouterOS, что стоит на роутере, затем в разделе Extra packages скачайте файлcontainer-<версия>-arm64.npk. В Winbox откройте Files и перетащите.npkв список (Upload), затем перезагрузите роутер: System → Reboot.Версия пакета обязана совпадать с версией RouterOS, иначе роутер может не загрузиться.
- Включите режим контейнеров. В терминале:
RouterOS попросит подтвердить действие нажатием кнопки на корпусе роутера (или перезагрузкой) — это защита от случайного включения контейнеров.
/system/device-mode/update container=yes - Подключите USB-носитель. Вставьте флешку/диск в роутер и проверьте, что
он виден:
Носитель появится как
/file/printusb1(илиdisk1). Если его нет — отформатируйте носитель в FAT32/ext4 и подключите снова.
Шаг 5. Загрузите скрипт на роутер и импортируйте его
- В Winbox откройте Files и перетащите туда
routeros.generated.rsc(Upload). - Откройте New Terminal и выполните:
/import file=routeros.generated.rsc - Скрипт создаст контейнер и всё окружение, скачает образ
nskforward/mikwgиз Docker Hub и запустит его. Первая загрузка образа занимает несколько секунд (в логе видны стадии download/extract).
Скрипт идемпотентен (повторный импорт безопасен) и настраивает veth/bridge/NAT,
список параметров обфускации awg-env, WireGuard, антилуп-маршрут, srcnat в
туннель, выборочную маршрутизацию, watchdog и start-on-boot.
Дефолтный маршрут роутера не меняется.
Шаг 6. Проверьте, что всё работает
Выполните в терминале роутера:
# контейнер должен быть в статусе running
/container/print
# рукопожатие с сервером установлено: last-handshake должен обновляться
/interface/wireguard/peers/print
# трафик до адреса из to_vpn_list уходит через туннель (команда должна отработать без ошибок)
/tool/fetch url=https://core.telegram.org/ output=none
В логе контейнера видно строку mikwg awg-converter <версия>:
/log/print where message~"awg-converter".
ICMP до внутреннего адреса сервера (
ping 10.8.2.1) на многих VPN-серверах не проходит — это нормально. Критерий работоспособности — TCP-трафик через туннель (fetch, браузер с LAN-клиента).
Выборочная маршрутизация
Через туннель идёт только трафик к адресам из списка to_vpn_list — это
единственная точка управления маршрутизацией, default route не трогается:
# направить подсеть/адрес в VPN
/ip/firewall/address-list/add list=to_vpn_list address=1.2.3.0/24
# убрать
/ip/firewall/address-list/remove [find list=to_vpn_list address="1.2.3.0/24"]
# направить ВЕСЬ трафик через туннель
/ip/firewall/address-list/add list=to_vpn_list address=0.0.0.0/0
Как именно это устроено внутри (mangle, anti-loop, FastTrack, MSS) —
в docs/routing.md.
Обновление
Одной командой (рекомендуется). Генерируемый скрипт ставит на роутер
служебный скрипт awg-update, который перекачивает образ и перезапускает
контейнер на свежем бинарнике:
/system/script/run awg-update
Чтобы получать свежие релизы, генерируйте скрипт с дефолтным образом
nskforward/mikwg:latest.
Новый awg0.conf от провайдера: сгенерируйте скрипт заново и импортируйте
его — параметры обфускации перезапишутся значениями из файла.
Ручное обновление образа, правка отдельных параметров обфускации и
оффлайн-установка — в docs/advanced.md.
Устранение неполадок
- Контейнер стартует, но
last-handshakeне обновляется. Проверьте лог контейнера (источник конфига и распознанные S/H/HPK), значения/container/envs/print where list=awg-env(UPSTREAMдолжен указывать на сервер,S1–S4 ≥ 12при заданномHPK), доступность адреса сервера и что антилуп-маршрут до IP сервера указывает на реальный WAN next-hop, а не на интерфейс. - Handshake проходит, data не идёт. Почти всегда — нет srcnat в туннель
(
out-interface=awg) либо reply-loop из-за порядка mangle-правил; разбор вdocs/routing.md. - После перезагрузки контейнер не поднялся. Проверьте
start-on-boot=yesи что внешний носитель смонтирован (образ лежит на нём). - ICMP через туннель не проходит. На многих VPN-серверах это ожидаемо; TCP при этом работает. Не считайте это поломкой.
Ограничения
- Только RouterOS с поддержкой контейнеров (ARM/ARM64/x86; не MIPS).
- Один peer (один AWG-сервер).
- Маршрутизация выборочная: через туннель идёт только
to_vpn_list, остальное — напрямую. Чтобы завернуть всё, добавьте0.0.0.0/0в список. - Туннель IPv4-only: IPv6-трафик через него не пойдёт. Если нужен полный IPv6-нет-лок, отключите IPv6 на LAN.
ContentPaddingAdditionи точная тайминговая мимикрия не воспроизводятся.
Лицензия
GPLv3 (см. LICENSE). Логика трансформаций сверена и заимствована из
amnezia-vpn/amneziawg-go (GPLv2),
что совместимо с GPLv3.
Документация
docs/safe-operations.md— обязательная памятка по безопасным операциям на RouterOS перед изменениямиdocs/advanced.md— флагиrscgen, детали образа, оффлайн-установка, ручное обновлениеdocs/routing.md— устройство выборочной маршрутизацииdocs/converter.md— конфигурация конвертера и совместимость с AmneziaWG 3.1docs/development.md— сборка, тесты, публикация, производительностьdocs/protocol-notes.md— спецификация проводного формата AmneziaWG 3.x