From 984af96cc9a6d95850888f7bf94a40d65d622ed9 Mon Sep 17 00:00:00 2001 From: vados-dev <192440777+vados-dev@users.noreply.github.com> Date: Fri, 14 Aug 2026 14:15:04 +0300 Subject: [PATCH] Autocommit in repo: ros.vados.ru, generated by owner: root, in 14:15:04 14.08.2026. --- html/AM-GlobalFunc.rsc | 4 +- .../configurator/configurator-old1.html | 5241 +++++++++++++++ html/amneziawg/configurator/configurator.html | 101 +- .../configurator/configurator3.0.html | 5836 +++++++++++++++++ 4 files changed, 11162 insertions(+), 20 deletions(-) create mode 100644 html/amneziawg/configurator/configurator-old1.html create mode 100644 html/amneziawg/configurator/configurator3.0.html diff --git a/html/AM-GlobalFunc.rsc b/html/AM-GlobalFunc.rsc index 744e1e481..15898ad07 100644 --- a/html/AM-GlobalFunc.rsc +++ b/html/AM-GlobalFunc.rsc @@ -17,9 +17,9 @@ :global GlobalFuncReady false; # Git commit id & info, expected configuration version -:global CommitId "main/8401/39191990"; +:global CommitId "main/8402/c7fbdc63"; :global CommitTAG "unknown"; -:global CommitInfo "Autocommit in repo: ros.vados.ru, generated by owner: root, in 14:10:03 14.08.2026."; +:global CommitInfo "Autocommit in repo: ros.vados.ru, generated by owner: root, in 14:15:04 14.08.2026."; # The variables are received right here. :global GlobalConfVersion 140; diff --git a/html/amneziawg/configurator/configurator-old1.html b/html/amneziawg/configurator/configurator-old1.html new file mode 100644 index 000000000..9402c4903 --- /dev/null +++ b/html/amneziawg/configurator/configurator-old1.html @@ -0,0 +1,5241 @@ + + + + + + AWG Proxy — Offline MikroTik Command Generator + + + +
+ +
+
+
+

AWG Proxy — MikroTik Offline Command Generator

+

Paste your AmneziaWG .conf file contents to generate ready-to-use MikroTik RouterOS commands

+
+ +
+
+ +
+
AmneziaWG Configuration File
+

All configuration and data is processed locally in your browser. Nothing is transmitted anywhere. Your private keys are safe.

+
+ +
+ + + + +
+
WireGuard client on MikroTik + awg-proxy runs inside a Docker container directly on the router
+
+ + +
+ +
+ + + +
+
Routes traffic to selected services through the tunnel using DNS forwarding (DoH). ⓘ
+
+
FastTrack rules will be modified (out-interface-list=WAN) to keep FastTrack active for non-VPN traffic. Uninstall script restores them.
+ +
+ +
+ + + + + + +
+ +
All services will use this DNS-over-HTTPS (DoH) provider for domain resolution.
+
+
+
+ +
+ + +
+
+
+
+ +
+ + +
+
+
+
+ +
+ +
Monitors tunnel availability by pinging 8.8.8.8 through the WG interface (via a pinned probe route). If the tunnel is down, disables its route — traffic falls back to the next tunnel (by distance) or goes direct. Re-enables the route when the tunnel recovers.
+
+
+ +
Adds AWG_NO_DF=1 to the container ENV: the proxy clears the Don’t Fragment bit on its UDP packets. Some DPI equipment passes DF=0 UDP better than DF=1. Enable only if the tunnel has connectivity issues — with DF=0 large packets may be fragmented along the path.
+
+
+ + + +
+ +
+ + + +
Change the prefix only if you need 2+ tunnels with different routing rules
+
+ + +
+ +
+
+
+ +
+ +
+
Parsed parameters
+
+
+ +
+
+
MikroTik RouterOS Commands
+ +
+

+        
+    
+ + + +
+
+
Uninstall Commands
+ +
+

+        
+    
+ +
+
+
+
Side A (MikroTik 1) — client
+ +
+

+            
+
Uninstall Side A (client)
+

+            
+
+
+
+
Side B (MikroTik 2) — server
+ +
+

+            
+
Uninstall Side B (server)
+

+            
+
+
+ + + + +
+ + + + diff --git a/html/amneziawg/configurator/configurator.html b/html/amneziawg/configurator/configurator.html index 9402c4903..72cad297e 100644 --- a/html/amneziawg/configurator/configurator.html +++ b/html/amneziawg/configurator/configurator.html @@ -631,6 +631,16 @@
+
+ This page is outdated. + It knows nothing about AmneziaWG 3.0 and is kept only so links shared earlier keep working. For a new install — or to bring an existing one up to date — reinstall using the new page: + conf3.0.html +
+ +
@@ -1000,6 +1010,9 @@ var I18N = { en: { + deprecatedTitle: 'This page is outdated.', + deprecatedBody: 'It knows nothing about AmneziaWG 3.0 and is kept only so links shared earlier keep working. For a new install \u2014 or to bring an existing one up to date \u2014 reinstall using the new page:', + linkFromNewer: 'This link was created by the new configurator and cannot be opened here. Open it in', title: 'AWG Proxy \u2014 MikroTik Offline Command Generator', subtitle: 'Paste your AmneziaWG .conf file contents to generate ready-to-use MikroTik RouterOS commands', privacy: 'All configuration and data is processed locally in your browser. Nothing is transmitted anywhere. Your private keys are safe.', @@ -1177,6 +1190,9 @@ igTipAwgServer: 'AmneziaWG Server\n\nThe remote VPN server running AmneziaWG. Receives transformed packets from awg-proxy and routes them to the internet.\n\nTraffic flows: Client \u2192 MikroTik WG \u2192 awg-proxy \u2192 AWG Server \u2192 Internet' }, ru: { + deprecatedTitle: 'Эта страница устарела.', + deprecatedBody: 'Она ничего не знает про AmneziaWG 3.0 и живёт только ради ранее розданных ссылок. Для новой установки — и чтобы обновить существующую — переустановите по новой странице:', + linkFromNewer: 'Эта ссылка создана новым конфигуратором и здесь не открывается. Откройте её в', title: 'AWG Proxy \u2014 \u041e\u0444\u043b\u0430\u0439\u043d-\u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u043a\u043e\u043c\u0430\u043d\u0434 MikroTik', subtitle: '\u0412\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 .conf \u0444\u0430\u0439\u043b\u0430 AmneziaWG \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u043c\u0430\u043d\u0434 MikroTik RouterOS', privacy: '\u0412\u0441\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e \u0432 \u0432\u0430\u0448\u0435\u043c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435. \u041d\u0438\u0447\u0435\u0433\u043e \u043d\u0438\u043a\u0443\u0434\u0430 \u043d\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u0442\u0441\u044f. \u0412\u0430\u0448\u0438 \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u0435 \u043a\u043b\u044e\u0447\u0438 \u0432 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438.', @@ -2623,7 +2639,7 @@ '/ip/firewall/nat/add chain=srcnat action=masquerade src-address=' + net.natSrc, '', '# 3. WireGuard interface (MikroTik derives the public key automatically)', - '/interface/wireguard/add name=wg-' + prefix + ' private-key="' + i.PrivateKey + '" listen-port=' + net.wgPort + ' disabled=yes', + '/interface/wireguard/add name=wg-' + prefix + ' private-key="' + i.PrivateKey + '" listen-port=' + randomWgPort() + ' disabled=yes', peerAdd, '/ip/address/add address=' + i.Address + ' interface=wg-' + prefix, '', @@ -2696,9 +2712,12 @@ ' :if ($arch = "arm") do={', ' :set file ("awg-proxy-arm" . $suffix . ".tar.gz")', ' :local rbModel ""', - ' :do { :set rbModel [/system/routerboard/get model] } on-error={}', + // /system/routerboard does not exist on CHR: RouterOS fails while parsing + // the script, before on-error can catch anything, and the whole block dies. + // :parse defers the lookup to runtime, so :do handles the missing menu. + ' :do { :set rbModel [[:parse ":return [/system/routerboard/get model]"]] } on-error={}', ' :local bName [/system/resource/get board-name]', - ' :if ($rbModel~"E50UG" || $rbModel~"E60iUGS" || $bName~"^hEX") do={', + ' :if ($rbModel~"E50UG" || $rbModel~"E60iUGS" || $bName~"E50UG" || $bName~"E60iUGS" || $bName~"^hEX") do={', ' :set file ("awg-proxy-armv5" . $suffix . ".tar.gz")', ' }', ' }', @@ -2854,7 +2873,7 @@ lines = lines.concat([ '', '# 2. WireGuard interface', - '/interface/wireguard/add name=wg-' + prefix + ' private-key="' + i.PrivateKey + '" listen-port=' + net.wgPort, + '/interface/wireguard/add name=wg-' + prefix + ' private-key="' + i.PrivateKey + '" listen-port=' + randomWgPort(), peerAdd, '/ip/address/add address=' + i.Address + ' interface=wg-' + prefix, '', @@ -3062,11 +3081,12 @@ return sel; } - // Deterministically derives a unique /30 veth subnet and WireGuard listen port - // from the tunnel name (prefix), so multiple tunnels on the same MikroTik - // don't collide. Uses a simple djb2-style hash spread across different bit - // ranges: bits 0-3 → 2nd octet (172.16-31.x.x), bits 4-11 → 3rd octet, - // bits 12-17 → 4th octet base (0-252, aligned to /30), bits 18+ → WG port. + // Deterministically derives a unique /30 veth subnet from the tunnel name + // (prefix), so multiple tunnels on the same MikroTik don't collide. It has to + // stay deterministic: the uninstall script recomputes the same addresses from + // the prefix to clean them up. Uses a simple djb2-style hash spread across + // different bit ranges: bits 0-3 → 2nd octet (172.16-31.x.x), bits 4-11 → + // 3rd octet, bits 12-17 → 4th octet base (0-252, aligned to /30). function getTunnelNetwork(prefix) { var h = 0; for (var i = 0; i < prefix.length; i++) @@ -3075,16 +3095,33 @@ var oct2 = 16 + (h & 0xF); var oct3 = (h >>> 4) & 0xFF; var oct4base = ((h >>> 12) & 0x3F) * 4; - var wgPort = 12000 + ((h >>> 18) % 20000); return { vethAddr: '172.' + oct2 + '.' + oct3 + '.' + (oct4base + 2) + '/30', hostAddr: '172.' + oct2 + '.' + oct3 + '.' + (oct4base + 1) + '/30', vethGw: '172.' + oct2 + '.' + oct3 + '.' + (oct4base + 1), - natSrc: '172.' + oct2 + '.' + oct3 + '.' + oct4base + '/30', - wgPort: wgPort + natSrc: '172.' + oct2 + '.' + oct3 + '.' + oct4base + '/30' }; } + // The WG listen-port used to come out of the same hash (bits 18+), but those + // bits don't change when only the trailing digit of the prefix does: every + // awg-proxy-1..5 got 25343 and every awg-server-1..2 got 25081, so a second + // tunnel on the same router could not bind its port. The port is local to the + // router and nothing recomputes it from the prefix, so draw it at random. + function randomWgPort() { + return randomInt(10000, 60000); + } + + // Tunnel subnets used to ship as fixed defaults (10.10.10.0/24 for the hub, + // 10.0.0.0/30 for site-to-site), so a second tunnel on the same router landed + // on addresses the first one already held. Second octet starts at 20 to stay + // clear of the usual 10.0.x/10.1.x/10.10.x home LANs. The share link carries + // the subnet, so add-client runs still follow the server that issued it. + function randomTunnelSubnet(bits) { + var base = '10.' + randomInt(20, 250) + '.' + randomInt(0, 255) + '.'; + return bits === 30 ? base + (randomInt(0, 62) * 4) + '/30' : base + '0/24'; + } + // ============================================================ // Curve25519 key generation (Montgomery ladder, BigInt) // ============================================================ @@ -3289,6 +3326,9 @@ if (!s2sParams) { s2sParams = generateS2SParams(); document.getElementById('s2s-awg-port').value = s2sParams.port; + // Only on first init, never in regenerate*: a subnet typed by hand must + // survive a protocol-level change. + document.getElementById('s2s-tunnel-subnet').value = randomTunnelSubnet(30); showS2SParams(); } return s2sParams; @@ -3312,6 +3352,9 @@ if (!serverParams) { serverParams = generateAWGParams(); document.getElementById('srv-awg-port').value = serverParams.port; + // Add-client runs overwrite this right after onModeChange() with the + // subnet from the share link (see the parseURLParams block on load). + document.getElementById('srv-tunnel-subnet').value = randomTunnelSubnet(24); showSrvParams(); } return serverParams; @@ -3508,6 +3551,14 @@ // Map to v3 field order: [0]=wgPubKey, [1]=endpoint, [2]=prefix, [3]=netMode, [4]=serverLAN fields = [key2, endpoint2, prefix2, String.fromCharCode(netModeN), srvLan2]; } else { + // Version 4+ comes from conf3.0.html, which owns its own format. + // Point the user there instead of silently ignoring the link. + var warn = document.getElementById('link-version-warn'); + if (warn) { + var href = document.getElementById('link-version-href'); + if (href) href.href = 'conf3.0.html' + location.search; + warn.style.display = 'block'; + } return null; // unsupported version } @@ -3645,7 +3696,10 @@ var tun = parseSlash24(tunnelCidr); var vethIP = net.vethAddr.replace(/\/.*/, ''); var awgPort = awgParams.port; - var wgPort = net.wgPort; + // Random per-generation port (see randomWgPort). It lives in awgParams and + // goes into the share link, so clients added from that link keep pointing + // at the same server port. + var wgPort = awgParams.wgListenPort || randomWgPort(); var tunServerIP = tun.ip(1); var tunClientIP = tun.ip(clientNum + 1); @@ -3717,6 +3771,10 @@ ls.push('/container/envs/add list=' + prefix + '-env key=AWG_H2 value="' + awgParams.h2 + '"'); ls.push('/container/envs/add list=' + prefix + '-env key=AWG_H3 value="' + awgParams.h3 + '"'); ls.push('/container/envs/add list=' + prefix + '-env key=AWG_H4 value="' + awgParams.h4 + '"'); + // The hub also initiates handshakes (it sends junk + CPS on the reverse + // path), so I1-I5 belong on the server side too, not just in the client + // .conf -- otherwise the server side comes up without CPS at all (#38). + ls = ls.concat(cpsEnvLines(prefix, awgParams.cps)); ls.push('/container/envs/add list=' + prefix + '-env key=AWG_SERVER_PUB value="' + serverKey.publicKey + '"'); ls.push('# AWG_CLIENT_PUB stays as legacy fallback for proxy-only clients.'); ls.push('# AWG_CLIENT_PUBS lists real direct AmneziaWG clients for multi-peer server mode.'); @@ -3765,13 +3823,16 @@ lc.push('# 2. Network infrastructure'); var cnet = getTunnelNetwork(prefix); var cvethIP = cnet.vethAddr.replace(/\/.*/, ''); + // Client-side WG port is purely local (the peer talks to the container over + // veth), so nothing has to agree on it. + var clientWgPort = randomWgPort(); lc.push('/interface/veth/add name=veth-' + prefix + ' address=' + cnet.vethAddr + ' gateway=' + cnet.vethGw); lc.push('/ip/address/add address=' + cnet.hostAddr + ' interface=veth-' + prefix); lc.push('/ip/firewall/nat/add chain=srcnat action=masquerade src-address=' + cnet.natSrc); lc.push(''); lc.push('# 3. WireGuard client'); - lc.push('/interface/wireguard/add name=wg-' + prefix + ' private-key="' + clientKey.privateKey + '" listen-port=' + cnet.wgPort + ' disabled=yes'); + lc.push('/interface/wireguard/add name=wg-' + prefix + ' private-key="' + clientKey.privateKey + '" listen-port=' + clientWgPort + ' disabled=yes'); lc.push('/interface/wireguard/peers/add interface=wg-' + prefix + ' public-key="' + serverKey.publicKey + '" endpoint-address=' + cvethIP + ' endpoint-port=51820 allowed-address=' + clientAllowed + ' persistent-keepalive=' + randomInt(25, 55)); lc.push('/ip/address/add address=' + tunClientIP + '/24 interface=wg-' + prefix); lc.push('/ip/firewall/filter/add chain=input action=accept in-interface=wg-' + prefix + ' place-before=0 comment=' + prefix + '-wg-mgmt'); @@ -3890,6 +3951,8 @@ var cnet = getTunnelNetwork(prefix); var cvethIP = cnet.vethAddr.replace(/\/.*/, ''); + // Local-only port, same reasoning as in buildServerCommands. + var clientWgPort = randomWgPort(); lc.push('# 2. Network infrastructure'); lc.push('/interface/veth/add name=veth-' + prefix + ' address=' + cnet.vethAddr + ' gateway=' + cnet.vethGw); lc.push('/ip/address/add address=' + cnet.hostAddr + ' interface=veth-' + prefix); @@ -3897,7 +3960,7 @@ lc.push(''); lc.push('# 3. WireGuard client'); - lc.push('/interface/wireguard/add name=wg-' + prefix + ' private-key="' + clientKey.privateKey + '" listen-port=' + cnet.wgPort + ' disabled=yes'); + lc.push('/interface/wireguard/add name=wg-' + prefix + ' private-key="' + clientKey.privateKey + '" listen-port=' + clientWgPort + ' disabled=yes'); lc.push('/interface/wireguard/peers/add interface=wg-' + prefix + ' public-key="' + serverWgPubKey + '" endpoint-address=' + cvethIP + ' endpoint-port=51820 allowed-address=' + clientAllowed + ' persistent-keepalive=' + randomInt(25, 55)); lc.push('/ip/address/add address=' + tunClientIP + '/24 interface=wg-' + prefix); lc.push('/ip/firewall/filter/add chain=input action=accept in-interface=wg-' + prefix + ' place-before=0 comment=' + prefix + '-wg-mgmt'); @@ -4316,9 +4379,11 @@ lines.push(' :if ($arch = "arm") do={'); lines.push(' :set file ("awg-proxy-arm" . $suffix . ".tar.gz")'); lines.push(' :local rbModel ""'); - lines.push(' :do { :set rbModel [/system/routerboard/get model] } on-error={}'); + // See the note above: :parse keeps the CHR/x86 parser from choking on + // /system/routerboard, which only exists on RouterBOARD hardware. + lines.push(' :do { :set rbModel [[:parse ":return [/system/routerboard/get model]"]] } on-error={}'); lines.push(' :local bName [/system/resource/get board-name]'); - lines.push(' :if ($rbModel~"E50UG" || $rbModel~"E60iUGS" || $bName~"^hEX") do={'); + lines.push(' :if ($rbModel~"E50UG" || $rbModel~"E60iUGS" || $bName~"E50UG" || $bName~"E60iUGS" || $bName~"^hEX") do={'); lines.push(' :set file ("awg-proxy-armv5" . $suffix . ".tar.gz")'); lines.push(' }'); lines.push(' }'); @@ -4576,7 +4641,7 @@ document.getElementById('prefix-custom').value = ''; document.getElementById('proxy-ip').value = ''; document.getElementById('s2s-endpoint-b').value = ''; - document.getElementById('s2s-tunnel-subnet').value = '10.0.0.0/30'; + document.getElementById('s2s-tunnel-subnet').value = randomTunnelSubnet(30); document.getElementById('s2s-storage-a').value = '__auto'; document.getElementById('s2s-storage-b').value = '__auto'; document.getElementById('s2s-dns').value = ''; diff --git a/html/amneziawg/configurator/configurator3.0.html b/html/amneziawg/configurator/configurator3.0.html new file mode 100644 index 000000000..c4848ea66 --- /dev/null +++ b/html/amneziawg/configurator/configurator3.0.html @@ -0,0 +1,5836 @@ + + + + + + AWG Proxy 3.0 — Offline MikroTik Command Generator + + + +
+ + + +
+
+
+

AWG Proxy 3.0 — MikroTik Offline Command Generator

+

Paste an AmneziaWG .conf (1.0 through 3.0) to generate ready-to-use MikroTik RouterOS commands

+
+ +
+
+ +
+
AmneziaWG Configuration File
+

All configuration and data is processed locally in your browser. Nothing is transmitted anywhere. Your private keys are safe.

+
+ +
+ + + + +
+
WireGuard client on MikroTik + awg-proxy runs inside a Docker container directly on the router
+
+ + +
+ +
+ + + +
+
Routes traffic to selected services through the tunnel using DNS forwarding (DoH). ⓘ
+
+
FastTrack rules will be modified (out-interface-list=WAN) to keep FastTrack active for non-VPN traffic. Uninstall script restores them.
+ +
+ +
+ + + + + + +
+ +
All services will use this DNS-over-HTTPS (DoH) provider for domain resolution.
+
+
+
+ +
+ + +
+
+
+
+ +
+ + +
+
+
+
+ +
+ +
Monitors tunnel availability by pinging 8.8.8.8 through the WG interface (via a pinned probe route). If the tunnel is down, disables its route — traffic falls back to the next tunnel (by distance) or goes direct. Re-enables the route when the tunnel recovers.
+
+
+ +
Adds AWG_NO_DF=1 to the container ENV: the proxy clears the Don’t Fragment bit on its UDP packets. Some DPI equipment passes DF=0 UDP better than DF=1. Enable only if the tunnel has connectivity issues — with DF=0 large packets may be fragmented along the path.
+
+
+ +
The IPv6 header is 40 bytes instead of 20, so a full-size packet no longer fits a 1500-byte path and the WireGuard MTU has to come down. Ticked automatically when the endpoint is an IPv6 literal. For a DNS name the box stays off (IPv4 MTU) — tick it yourself if you know the name has an AAAA record; the generated script also asks the router with :resolve type=ipv6 and lowers the MTU if it answers.
+
+
+ + + +
+ +
+ + + +
Change the prefix only if you need 2+ tunnels with different routing rules
+
+ + +
+ +
+
+
+ +
+ +
+
Parsed parameters
+
+
+ +
+
+
MikroTik RouterOS Commands
+ +
+

+        
+    
+ + + +
+
+
Uninstall Commands
+ +
+

+        
+    
+ +
+
+
+
Side A (MikroTik 1) — client
+ +
+

+            
+
Uninstall Side A (client)
+

+            
+
+
+
+
Side B (MikroTik 2) — server
+ +
+

+            
+
Uninstall Side B (server)
+

+            
+
+
+ + + +
Works entirely offline — no data leaves your browser.
+
+ + + + -- 2.52.0