BLA
BLA (Blind LLM Agents) is the open-source Blue Defense MCP and CLI built to protect software artifacts against automated AI reverse-engineering workflows.
Клиент AmneziaWG (Amnezia VPN) в контейнере RouterOS 7 с веб-интерфейсом.
Translation pending
SecurityGitHub @Namikko-chadOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Repository information has not been collected yet.
No updates detected yet. GitHub releases will appear here.
AmneziaWG (Amnezia VPN) client for MikroTik RouterOS 7 as a container with web UI: vpn:// keys, .conf, SSH, split tunneling, failover. AmneziaWG на MikroTik.
Translation pending
Taken from the repository README
Loading the full README.
Read the full README ↗English | Русский
Amnezia VPN on a MikroTik router: a full AmneziaWG
client (AWG 1.x and 2.0) packaged as a RouterOS 7 container, with a web UI to manage it. Run it on your
MikroTik (hAP ax², hAP ax³, RB5009, CCR2004, hAP ac², RB4011, CHR …) and send your whole LAN, selected
devices or selected sites through an obfuscated WireGuard tunnel that DPI cannot recognize. No VPN client
is needed on each device, and nothing has to be typed into the RouterOS terminal to set up the tunnel:
paste the vpn:// key from the Amnezia app and click Apply.
vpn:// key from the Amnezia app;.conf file;ru) and their subnets bypass the tunnel. The container
downloads the lists daily and serves them to the router as a .rsc script.arm64, arm/v7 and amd64 (CHR/x86).Router setup guide: docs/mikrotik-setup.md
| Component | Role |
|---|---|
amneziawg-go | userspace AmneziaWG implementation (no kernel module needed) |
awg from amneziawg-tools | configures the interface |
awg-manager (backend/) | Go backend: config parsing, vpn:// decoding, SSH provisioning, bringing the tunnel up and down, routing and NAT |
| nginx | serves the web UI (web/) on :80 and proxies /api/ to the backend |
vpn:// key. Open the Amnezia app, go to Share, choose AmneziaWG, and copy the key.
Plain base64 of a .conf file also works. If the key grants full access to the server (it contains
SSH credentials), the backend provisions a new client automatically.
.conf file. Any AmneziaWG or WireGuard config: Jc, Jmin, Jmax, S1–S4, H1–H4,
I1–I5 and the other AmneziaWG 2.0 keys are passed to awg unchanged.
SSH credentials of a server set up by the Amnezia app (container amnezia-awg2, or legacy amnezia-awg).
The backend does what the Amnezia app does when you add a client:
[Peer] to the server config and runs syncconf;clientsTable, so it shows up in the Amnezia app under the name you choose.Users other than root get sudo, using the same password. Credentials are never stored.
LAN device ──► RouterOS ──(routing rule)──► veth 172.18.0.2 ──► container
│ ip rule: iif <veth> → table 51820 → awg0
│ MASQUERADE + TCP MSS clamp on awg0
▼
awg0 ──UDP──► AmneziaWG server
The container's own traffic (the tunnel's UDP packets, SSH, the web UI) goes out through the veth via the main routing table. Only packets forwarded to the container by the router enter the tunnel, so there are no routing loops and no special route to the endpoint is needed.
Get the image. Either let the router pull it (arm64, arm/v7 and amd64 in one tag):
ghcr.io/namikko-chad/amneziawg-mikrotik:latestnamikko/amneziawg-mikrotik:latestor download the .tar for your router's architecture from
Releases, or build it yourself.
Follow the router setup guide.
Open http://172.18.0.2/, paste your key, and click Apply.
Requirements: Docker with buildx. To cross-build ARM images on an x86 host you also need QEMU binfmt
(once per boot: make qemu).
make test # go vet + backend unit tests
make build-arm64 # hAP ax², hAP ax³, RB5009, CCR2004, Chateau ax …
make build-armv7 # hAP ac², hAP ac³, RB4011, cAP ac …
make build-amd64 # CHR / x86
make all # all of the above
Output: dist/amneziawg-mikrotik-<arch>.tar (docker-archive format, which RouterOS can import).
The AmneziaWG versions are pinned with the build args AWG_GO_VERSION and AWG_TOOLS_VERSION in the Dockerfile.
docker load -i dist/amneziawg-mikrotik-amd64.tar
docker run -d --name awg --cap-add NET_ADMIN --device /dev/net/tun \
-p 8080:80 -v awg-conf:/etc/amnezia amneziawg-mikrotik:latest
# open http://localhost:8080/
Environment variables:
| Variable | Default | Description |
|---|---|---|
AWG_DATA_DIR | /etc/amnezia | where profiles.json (all saved servers) is stored; mount persistent storage here. An awg0.conf left by an older version is imported automatically |
LAN_IFACE | auto | interface that receives traffic from the router. Detected from the default route: on RouterOS it is the veth name, in Docker it is eth0 |
LISTEN | 127.0.0.1:8080 | backend listen address (nginx proxies to it) |
CHECK_HOSTS | 1.1.1.1 8.8.8.8 | hosts pinged through each link to detect failures when a backup server is set; a link is up if any of them answers |
The tunnel comes up automatically on start with the selected server, unless it was stopped with Disconnect in the UI.
| Method | Path | Body |
|---|---|---|
| GET | /api/status | — |
| GET | /api/config | — (config of the selected server, keys are masked) |
| GET | /api/logs | — |
| POST | /api/config/text | {"config": "[Interface]…", "name": "…"} |
| POST | /api/config/vpnkey | {"key": "vpn://…", "client_name": "…", "name": "…"} |
| POST | /api/config/ssh | {"host", "port", "user", "password", "private_key", "passphrase", "client_name", "name"} |
| GET | /api/profiles | — (list of saved servers and the selected one) |
| GET | /api/profiles/{id}/config | — (keys are masked) |
| POST | /api/profiles/{id}/activate | {} |
| PATCH | /api/profiles/{id} | {"name": "…"} |
| DELETE | /api/profiles/{id} | — |
| POST | /api/backup | {"id": "…"} ("" removes the backup) |
| POST | /api/up, /api/down | {} |
| GET | /api/router | — (saved routing plan, default router URL) |
| POST | /api/router/info | {"auth": {"url", "user", "password", "insecure"}} |
| POST | /api/router/apply | {"auth": {…}, "plan": {"mode": "off|all|devices|sites", "lan", "exclude", "exclude_dst", "bypass_geo", "devices", "sites", "kill_switch", "paused", "dns"}} |
| POST | /api/router/geo | {"auth": {…}} (make the router reload the country list now) |
| GET | /api/geo | — (country list: countries, source, per-country status, script URL) |
The three /api/config/* calls save a new server, select it and connect. name is optional: by
default the description from the vpn:// key or the server address is used. Selecting another server
reconnects the tunnel to it, unless the tunnel was stopped with /api/down. Selecting the backup server
swaps the two roles. Deleting the selected server makes the backup the selected one, or stops the tunnel
if there is no backup.
With a backup server, the container runs two tunnels: awg0 to the selected server and awg1 to the
backup. Every 5 s it pings CHECK_HOSTS through each of them. After 3 failed checks in a row on the link
in use, LAN traffic is switched to the other link (if that one is answering); after 12 successful checks
in a row (~1 min) on the selected server, traffic switches back. The switch is a single route change in
the container, so nothing has to change on the router. Connections that were open at the moment of the
switch break because the public IP changes; apps reconnect on their own.
/api/status reports which link carries traffic in using (primary or backup) and the state of
each link in links.
172.18.0.2:80 with the RouterOS firewall
(see the setup guide).sessionStorage and
sends it with each request. Without it the container cannot change the router. Give that RouterOS
user only the read,write,api,rest-api policies and address=172.18.0.2/32.profiles.json on the mounted disk, as with any WireGuard setup.backend/ Go backend (awg-manager)
internal/conf/ AmneziaWG/WireGuard config parser
internal/profiles/ saved servers and the selected one
internal/vpnkey/ vpn:// key decoder
internal/sshprov/ client provisioning over SSH
internal/tunnel/ interfaces, routing, NAT and failover between the two links
internal/routeros/ RouterOS REST API client
internal/routing/ routing plan -> router rules (routing rules, mangle, address lists, DNS)
internal/geoip/ per-country subnet lists, served to the router as a .rsc script
web/ static web UI (plain HTML/JS/CSS)
docker/ nginx.conf, entrypoint.sh
docs/ router setup guide
Not on its own: RouterOS has a WireGuard client, but AmneziaWG adds junk packets and changes packet headers, so the built-in client cannot talk to an AmneziaWG server. This project runs the AmneziaWG client in a RouterOS 7 container, and the router sends traffic to it with ordinary routing rules.
Any router with RouterOS 7 and the container package on arm64 (hAP ax², hAP ax³, RB5009, CCR2004,
Chateau ax …), arm/v7 (hAP ac², hAP ac³, RB4011, cAP ac …) or x86/CHR (amd64). The image takes
about 10 MB of storage and about 8 MB of RAM. mipsbe/mmips routers (hAP lite, hEX) cannot run containers.
Proxy projects keep the tunnel in RouterOS's own WireGuard interface and run a small container that rewrites
packets on the way to the server. This project runs the complete AmneziaWG client (amneziawg-go) in the
container instead, so every AmneziaWG option, including AWG 2.0 (S3, S4, I1–I5, header ranges), is
supported as is. It also adds a web UI, several saved servers with failover, routing by device, site or
country, and creating a client on your own Amnezia server over SSH.
Only once, to create the container (see the setup guide). After that the web UI writes the routing rules, mangle rules, address lists, kill switch and DNS settings through the RouterOS REST API.
Yes. Choose selected sites mode to send only listed domains or subnets through the tunnel, or pick
countries (e.g. ru) under country exceptions so their subnets bypass it.
Yes. Enter the server's SSH login and the container creates its own client there, just as the Amnezia app
does. A vpn:// key or .conf from any AmneziaWG or WireGuard server works too.
MIT for the code in this repository.
The container image also includes third-party software under its own licenses:
amneziawg-go (MIT),
amneziawg-tools (GPL-2.0, the awg binary, built unmodified from upstream source),
nginx (BSD-2-Clause) and Alpine Linux packages.
This project is not affiliated with Amnezia VPN or MikroTik.
| POST | /api/geo | {"countries": ["ru", "by"], "source": "…"} (source is optional, {cc} is the country code) |
| POST | /api/geo/update | {} (download all country lists again) |
| GET | /lists/geo.rsc | — (RouterOS script that fills the address list awg-geo; 503 while there is no list) |