Skip to content

Repository files navigation

This project is not affiliated with or endorsed by MikroTik / SIA Mikrotikls

awg-proxy -- AmneziaWG для MikroTik

Go Version License

English version

Легковесный Docker-контейнер, который позволяет MikroTik подключаться к серверам AmneziaWG. Весь трафик шифруется нативным WireGuard-клиентом роутера, а контейнер только преобразует формат пакетов.

Содержание

Как это работает

MikroTik WG-клиент ──UDP──> [awg-proxy] ──UDP──> сервер AmneziaWG
   (шифрование)          (преобразование)          (обфускация)

Прокси заменяет заголовки пакетов, добавляет паддинг и мусорные пакеты так, чтобы сервер AmneziaWG принял трафик. Ключи и данные не затрагиваются.

Совместим с AWG v1 и v2 -- версия определяется автоматически по переменным окружения.

Быстрый старт (конфигуратор)

  1. Экспортируйте .conf-файл из AmneziaVPN (см. Получение параметров AWG)
  2. Откройте конфигуратор
  3. Вставьте содержимое .conf-файла
  4. Скопируйте сгенерированные команды и выполните их в терминале MikroTik

Готово. Конфигуратор работает оффлайн, данные не отправляются на сервер.

awg-proxy-test1.mp4

Замеры скорости на MikroTik AX3

Замеры скорости на устройстве MikroTik AX3

Требования

  • Сервер AmneziaWG с известными параметрами обфускации
  • Файл конфигурации .conf, экспортированный из AmneziaVPN
  • MikroTik RouterOS 7.4+ с пакетом container
    • RouterOS 7.21+: стандартные образы awg-proxy-{arch}.tar.gz (OCI-формат)
    • RouterOS 7.20 и ниже: образы awg-proxy-{arch}-7.20-Docker.tar.gz (Docker-формат)
    • Конфигуратор определяет версию автоматически
  • Архитектура: ARM64, ARM (v7) или x86_64 (проверить устройство)
  • Минимум 5 МБ свободного места на диске (или USB-накопитель)
  • Минимум 16 МБ свободной оперативной памяти (RAM)

Ручная установка

1. Включение контейнеров

Установите пакет container с mikrotik.com, загрузите на роутер и перезагрузитесь. Затем:

/system/device-mode/update container=yes

Роутер попросит подтверждение (кнопка или перезагрузка, зависит от модели).

2. Загрузка образа

Скачайте awg-proxy-{arch}.tar.gz со страницы Releases и загрузите на роутер через Winbox или SCP. Для RouterOS 7.20 и ниже используйте файлы с суффиксом -7.20-Docker (Docker-формат).

Или скачайте прямо на роутер (замените URL на актуальный):

/tool/fetch url="https://github.com/timbrs/amneziawg-mikrotik/releases/latest/download/awg-proxy-arm64.tar.gz" dst-path=awg-proxy-arm64.tar.gz

3. Настройка сети

/interface/veth/add name=veth-awg-proxy address=172.18.0.2/30 gateway=172.18.0.1
/ip/address/add address=172.18.0.1/30 interface=veth-awg-proxy
/ip/firewall/nat/add chain=srcnat action=masquerade src-address=172.18.0.0/30

4. WireGuard

/interface/wireguard/add name=wg-awg-proxy private-key="YOUR_PRIVATE_KEY" listen-port=12429
/interface/wireguard/peers/add interface=wg-awg-proxy public-key="SERVER_PUBLIC_KEY" \
    preshared-key="YOUR_PRESHARED_KEY" endpoint-address=172.18.0.2 endpoint-port=51820 \
    allowed-address=0.0.0.0/0 persistent-keepalive=25
/ip/address/add address=YOUR_TUNNEL_IP interface=wg-awg-proxy

Замените:

  • YOUR_PRIVATE_KEY -- PrivateKey из [Interface]
  • SERVER_PUBLIC_KEY -- PublicKey из [Peer]
  • YOUR_PRESHARED_KEY -- PresharedKey из [Peer] (если есть)
  • YOUR_TUNNEL_IP -- Address из [Interface] (например, 10.8.0.2/32)

5. Переменные окружения

/container/envs/add list=awg-proxy-env key=AWG_LISTEN value=":51820"
/container/envs/add list=awg-proxy-env key=AWG_REMOTE value="SERVER_IP:PORT"
/container/envs/add list=awg-proxy-env key=AWG_JC value="5"
/container/envs/add list=awg-proxy-env key=AWG_JMIN value="30"
/container/envs/add list=awg-proxy-env key=AWG_JMAX value="500"
/container/envs/add list=awg-proxy-env key=AWG_S1 value="20"
/container/envs/add list=awg-proxy-env key=AWG_S2 value="20"
/container/envs/add list=awg-proxy-env key=AWG_H1 value="1234567890"
/container/envs/add list=awg-proxy-env key=AWG_H2 value="1234567891"
/container/envs/add list=awg-proxy-env key=AWG_H3 value="1234567892"
/container/envs/add list=awg-proxy-env key=AWG_H4 value="1234567893"
/container/envs/add list=awg-proxy-env key=AWG_SERVER_PUB value="SERVER_PUBLIC_KEY"
/container/envs/add list=awg-proxy-env key=AWG_CLIENT_PUB value=[/interface/wireguard/get [find name=wg-awg-proxy] public-key]

Замените все значения на параметры из вашего .conf-файла. AWG_CLIENT_PUB берется автоматически из WireGuard-интерфейса.

6. Создание и запуск контейнера

/container/add file=awg-proxy-arm64.tar.gz interface=veth-awg-proxy envlist=awg-proxy-env \
    hostname=awg-proxy root-dir=disk1/awg-proxy logging=yes shm-size=4M start-on-boot=yes
/container/start [find where tag~"awg-proxy"]

Проверьте работу:

/container/print
/interface/wireguard/peers/print

Контейнер должен быть в статусе running, а у пира должно появиться значение last-handshake.

Получение параметров AWG

  1. Откройте приложение AmneziaVPN
  2. Выберите нужное подключение
  3. Нажмите Поделиться (Share)
  4. Выберите: Протокол: AmneziaWG, Формат: AmneziaWG Format
  5. Сохраните .conf-файл

Параметры обфускации (Jc, Jmin, Jmax, S1, S2, H1--H4) находятся в секции [Interface], а Endpoint и PublicKey -- в секции [Peer].

Дополнительные настройки

Все переменные окружения

Переменная Обязательная Описание
AWG_LISTEN Да Адрес прослушивания (например, :51820)
AWG_REMOTE Да Адрес AWG-сервера -- Endpoint из [Peer] (например, 1.2.3.4:443)
AWG_JC Да Количество мусорных пакетов (Jc из .conf)
AWG_JMIN Да Минимальный размер мусорного пакета (Jmin)
AWG_JMAX Да Максимальный размер мусорного пакета (Jmax)
AWG_S1 Да Паддинг handshake init в байтах (S1)
AWG_S2 Да Паддинг handshake response в байтах (S2)
AWG_H1 Да Тип handshake init (H1); может быть диапазоном min-max для v2
AWG_H2 Да Тип handshake response (H2); может быть диапазоном для v2
AWG_H3 Да Тип cookie reply (H3); может быть диапазоном для v2
AWG_H4 Да Тип transport data (H4); может быть диапазоном для v2
AWG_SERVER_PUB Да Публичный ключ сервера, base64 (PublicKey из [Peer])
AWG_CLIENT_PUB Да Публичный ключ клиента, base64
AWG_S3 Нет Паддинг cookie reply в байтах (v2)
AWG_S4 Нет Паддинг transport data в байтах (v2)
AWG_I1--AWG_I5 Нет CPS-шаблоны (v1.5/v2); до 5 шаблонов
AWG_SRC_PORT Нет Source-порт для подключения к серверу. Не задан или 0 -- auto-режим: порт берётся из первого пакета клиента (MikroTik WG). 1--65535 -- статический порт. Используется для NAT hole punching: прокси подключается к серверу с тем же src-портом, что и MikroTik, что позволяет потом переключиться на прямое соединение без прокси (по умолчанию: auto)
AWG_TIMEOUT Нет Таймаут бездействия в секундах (по умолчанию: 180)
AWG_LOG_LEVEL Нет none, error, info, debug (по умолчанию: info)
AWG_SOCKET_BUF Нет Размер буфера сокета в байтах (по умолчанию: 16777216 = 16 МБ)
AWG_GOMAXPROCS Нет Количество потоков Go (по умолчанию: 2)

Версия протокола определяется автоматически: v2 если заданы S3/S4 или H в виде диапазонов, v1.5 если заданы CPS-шаблоны (I1-I5), иначе v1.

Маршрутизация трафика через туннель

Конкретный хост:

/ip/route/add dst-address=8.8.8.8/32 gateway=wg-awg-proxy

Подсеть:

/ip/route/add dst-address=10.0.0.0/8 gateway=wg-awg-proxy

Просмотр маршрутов:

/ip/route/print where gateway=wg-awg-proxy

Удаление маршрута:

/ip/route/remove [find where dst-address="8.8.8.8/32" gateway="wg-awg-proxy"]

DNS через туннель

Чтобы DNS-запросы шли через туннель, укажите DNS-сервер и добавьте маршрут к нему:

/ip/dns/set servers=8.8.8.8,8.8.4.4
/ip/route/add dst-address=8.8.8.8/32 gateway=wg-awg-proxy
/ip/route/add dst-address=8.8.4.4/32 gateway=wg-awg-proxy

Маршрутизация по address-list (продвинутое)

Для выборочной маршрутизации трафика через туннель используйте routing table и mangle rules.

Создание routing table:

/routing/table/add disabled=no fib name=r_to_vpn

Маршрут по умолчанию через туннель для этой таблицы:

/ip/route/add dst-address=0.0.0.0/0 gateway=wg-awg-proxy routing-table=r_to_vpn

Address-list с адресами, которые нужно направить через туннель:

/ip/firewall/address-list/add address=8.8.8.8 list=to_vpn
/ip/firewall/address-list/add address=1.1.1.1 list=to_vpn

Mangle rules для маркировки трафика:

# Пропускаем локальный трафик
/ip/firewall/mangle/add chain=prerouting action=accept dst-address=10.0.0.0/8
/ip/firewall/mangle/add chain=prerouting action=accept dst-address=172.16.0.0/12
/ip/firewall/mangle/add chain=prerouting action=accept dst-address=192.168.0.0/16

# Маркируем соединения к адресам из списка
/ip/firewall/mangle/add chain=prerouting action=mark-connection \
    dst-address-list=to_vpn connection-mark=no-mark \
    new-connection-mark=to-vpn-conn passthrough=yes

# Маркируем маршрутизацию для отмеченных соединений
/ip/firewall/mangle/add chain=prerouting action=mark-routing \
    connection-mark=to-vpn-conn new-routing-mark=r_to_vpn passthrough=yes

NAT для маркированного трафика:

/ip/firewall/nat/add chain=srcnat action=masquerade routing-mark=r_to_vpn

Теперь весь трафик к адресам из списка to_vpn будет идти через туннель. Добавляйте адреса в список по мере необходимости.

Запуск на Windows (Standalone)

Если на роутере нет поддержки контейнеров (RouterOS Lite, мало памяти) или нужно сохранить существующий WireGuard-интерфейс, awg-proxy можно запустить на любом Windows-компьютере в локальной сети.

Схема работы

MikroTik WG-клиент ──UDP──> [awg-proxy на Windows] ──UDP──> сервер AmneziaWG
   (192.168.1.1)              (192.168.1.100:51820)           (внешний IP:порт)

1. Скачайте бинарник

Скачайте awg-proxy-windows-amd64.exe со страницы Releases.

2. Настройте переменные окружения и запустите

Все параметры берутся из .conf-файла AmneziaWG. Замените значения на свои.

PowerShell:

$env:AWG_LISTEN = ":51820"
$env:AWG_REMOTE = "SERVER_IP:PORT"
$env:AWG_JC = "5"
$env:AWG_JMIN = "30"
$env:AWG_JMAX = "500"
$env:AWG_S1 = "20"
$env:AWG_S2 = "20"
$env:AWG_H1 = "1234567890"
$env:AWG_H2 = "1234567891"
$env:AWG_H3 = "1234567892"
$env:AWG_H4 = "1234567893"
$env:AWG_SERVER_PUB = "SERVER_PUBLIC_KEY_BASE64"
$env:AWG_CLIENT_PUB = "CLIENT_PUBLIC_KEY_BASE64"

.\awg-proxy-windows-amd64.exe

CMD:

set AWG_LISTEN=:51820
set AWG_REMOTE=SERVER_IP:PORT
set AWG_JC=5
set AWG_JMIN=30
set AWG_JMAX=500
set AWG_S1=20
set AWG_S2=20
set AWG_H1=1234567890
set AWG_H2=1234567891
set AWG_H3=1234567892
set AWG_H4=1234567893
set AWG_SERVER_PUB=SERVER_PUBLIC_KEY_BASE64
set AWG_CLIENT_PUB=CLIENT_PUBLIC_KEY_BASE64

awg-proxy-windows-amd64.exe

AWG_CLIENT_PUB -- публичный ключ WireGuard-клиента на MikroTik. Его можно получить командой /interface/wireguard/print на роутере.

3. Настройте MikroTik

Используйте конфигуратор в режиме MikroTik + Server (Standalone), указав IP Windows-машины. Конфигуратор сгенерирует все нужные команды для роутера.

Или вручную: создайте WireGuard-интерфейс с endpoint-address=IP_WINDOWS_МАШИНЫ и endpoint-port=51820.

4. Файрвол Windows

Разрешите входящий UDP-трафик на порт 51820. В PowerShell от администратора:

New-NetFirewallRule -DisplayName "awg-proxy" -Direction Inbound -Protocol UDP -LocalPort 51820 -Action Allow

5. Автозапуск (опционально)

Для автоматического запуска при старте Windows создайте bat-файл с переменными окружения и командой запуска, затем добавьте его в планировщик задач или в автозагрузку.

Или создайте Windows-службу через NSSM:

nssm install awg-proxy "C:\path\to\awg-proxy-windows-amd64.exe"
nssm set awg-proxy AppEnvironmentExtra AWG_LISTEN=:51820 AWG_REMOTE=SERVER_IP:PORT ...
nssm start awg-proxy

Удаление

Если установка была через конфигуратор:

/system/script/run awg-proxy-uninstall

Скрипт удалит контейнер, WireGuard-интерфейс, правила NAT, маршруты, переменные окружения, восстановит DNS и удалит себя.

Устранение неполадок

Контейнер не запускается -- проверьте установку пакета container (/system/package/print), режим устройства (/system/device-mode/print) и свободное место (/system/resource/print).

Нет рукопожатия -- убедитесь, что все параметры AWG (Jc, Jmin, Jmax, S1, S2, H1--H4) точно совпадают с сервером. Проверьте AWG_REMOTE, AWG_SERVER_PUB и AWG_CLIENT_PUB.

Нет трафика после рукопожатия -- проверьте правило NAT (/ip/firewall/nat/print), маршрутизацию и endpoint-address пира (должен быть 172.18.0.2).

Контейнер перезапускается -- установите AWG_LOG_LEVEL=info и проверьте логи. Частая причина -- отсутствующие переменные окружения.

Storage device not found

Если при установке появляется ошибка Storage device usb1 not found or has 0 free space -- диск не отформатирован или имя точки монтирования не совпадает.

  1. Проверьте доступные диски:
/disk/print
  1. Если диск виден как block-устройство, но без раздела -- отформатируйте его в ext4:
/disk/format-drive usb1 file-system=ext4 label=usb1
  1. После форматирования диск будет доступен как mount-point (обычно usb1). Проверьте имя через /disk/print и используйте его в конфигураторе (поле "Container storage").

Важно: Контейнеры требуют файловую систему ext4. FAT32 не подходит.

Insufficient disk space

Если при установке контейнера возникает ошибка Insufficient disk space, а на внешнем накопителе (USB, SD, NVMe) есть свободное место -- перенастройте директорию для загрузки образов:

/container/config set tmpdir=usb1/pull ram-high=200M

Замените usb1 на mount-point вашего накопителя (см. /disk/print).

После установки контейнера можно вернуть значение обратно:

/container/config set tmpdir="" ram-high=0

Если используете конфигуратор -- выберите нужный накопитель в поле "Container storage", и tmpdir будет настроен автоматически.

not allowed by device-mode

Если при загрузке образа или создании контейнера появляется ошибка not allowed by device-mode, значит контейнеры не активированы. Выполните:

/system/device-mode/update container=yes

Роутер попросит подтверждение -- нажмите кнопку Reset или Mode на корпусе (зависит от модели) в течение нескольких минут, либо дождитесь автоматической перезагрузки. После перезагрузки повторите установку.

child spawn failed / could not load next layer

На устройствах с 16 МБ flash (hAP ac2, hEX и др.) контейнер может не запускаться с ошибками:

  • child spawn failed: container run error или exited with status 255 (RouterOS 7.20)
  • download/extract error: could not load next layer (RouterOS 7.21+)

Чек-лист:

  1. Формат образа -- убедитесь, что используете правильный формат:

    • RouterOS 7.21+: awg-proxy-{arch}.tar.gz (OCI)
    • RouterOS 7.20 и ниже: awg-proxy-{arch}-7.20-Docker.tar.gz (Docker)
  2. tmpdir на USB -- без этого RouterOS распаковывает образ на внутреннюю flash, которой не хватает (замените usb1 на ваш mount-point из /disk/print):

    /container/config set tmpdir=usb1/pull
    
  3. root-dir -- указывайте путь к папке на USB, но не создавайте её вручную (RouterOS создаст её сам):

    /container add ... root-dir=usb1/awg-proxy
    
  4. Формат USB -- отформатируйте накопитель в ext4:

    /disk/format-drive usb1 file-system=ext4 label=usb1
    
  5. Загрузка из файла -- на устройствах с 16 МБ flash загружайте образ через файл, а не remote-image:

    /container add file=awg-proxy-arm.tar.gz ...
    

Сборка из исходников

Требуется Go 1.25+, Docker (для контейнерных образов) и make.

# Тесты
make test

# Локальная сборка бинарника
make build

# Docker-образы (OCI, для RouterOS 7.21+)
make docker-arm64    # ARM64
make docker-arm      # ARM v7
make docker-armv5    # ARM v5
make docker-amd64    # x86_64
make docker-all      # Все архитектуры

# Docker-образы (классический формат, для RouterOS 7.20 и ниже)
make docker-arm64-7.20-docker
make docker-arm-7.20-docker
make docker-armv5-7.20-docker
make docker-amd64-7.20-docker
make docker-all-7.20-docker

# Windows-бинарник (Standalone)
make binary-windows-amd64

Артефакты создаются в директории builds/.

Сборка на Windows без make

$env:CGO_ENABLED = "0"
go build -trimpath -ldflags="-s -w" -o builds/awg-proxy.exe .

Для кросс-компиляции Linux-бинарников на Windows:

$env:CGO_ENABLED = "0"; $env:GOOS = "linux"; $env:GOARCH = "arm64"
go build -trimpath -ldflags="-s -w" -o builds/awg-proxy-linux-arm64 .

Лицензия

MIT -- см. LICENSE.

About

Go-Container позволяющий подключаться к AmneziaWG серверам из Mikrotik. Лучшая версия (переписали на Си) здесь: https://github.com/timbrs/amneziawg-mikrotik-c

Resources

Stars

95 stars

Watchers

4 watching

Forks

Releases

Contributors

Languages