From: vados-dev <192440777+vados-dev@users.noreply.github.com> Date: Sat, 12 Sep 2026 08:50:05 +0000 (+0300) Subject: Autocommit in repo: ros.vados.ru, generated by owner: root, in 11:50:04 12.09.2026. X-Git-Url: https://git.vados.ru/gitweb.cgi?a=commitdiff_plain;h=07468b55dc6ed84dc04e4b7e88003b73bd12c3d5;p=Mikrotiks%2Fros.vados.ru.git Autocommit in repo: ros.vados.ru, generated by owner: root, in 11:50:04 12.09.2026. --- diff --git a/html/AM-GlobalFunc.rsc b/html/AM-GlobalFunc.rsc index 695e25223..342ec6c45 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/16713/cbbd0da6"; +:global CommitId "main/16714/4a1cab3a"; :global CommitTAG "unknown"; -:global CommitInfo "Autocommit in repo: ros.vados.ru, generated by owner: root, in 11:45:04 12.09.2026."; +:global CommitInfo "Autocommit in repo: ros.vados.ru, generated by owner: root, in 11:50:04 12.09.2026."; # The variables are received right here. :global GlobalConfVersion 140; diff --git a/html/AM-awg3vdsInstall.rsc b/html/AM-awg3vdsInstall.rsc new file mode 100644 index 000000000..2cf0f494d --- /dev/null +++ b/html/AM-awg3vdsInstall.rsc @@ -0,0 +1,472 @@ +#!rsc by Vados +# RouterOS script: AM-awg3vdsInstall +# Script comment: awg3vds installer +# +# +# requires RouterOS, version=7.19 +# requires device-mode, fetch, scheduler +# ============================================================ +# AWG Proxy -- MikroTik RouterOS (protocol: v3) +# 2026-09-12 08:41:48 +# ============================================================ +# 0. Check prerequisites +:if ([:len [/system/package/find where name="container" disabled=no]] = 0) do={ + :put "Container package is not installed or disabled. Install it and reboot." + :error "Usage: /system/device-mode/update container=yes" +} + +# Check storage device +{ + :local targetDisk "usb1" + :local diskFree 0 + :do { :set diskFree [/disk/get [find where mount-point=$targetDisk] free] } on-error={} + :if ($diskFree = 0) do={ + :local baseDisk $targetDisk + :local dashPos [:find $targetDisk "-part"] + :if ([:typeof $dashPos] != "nil") do={ :set baseDisk [:pick $targetDisk 0 $dashPos] } + :if ([:len [/disk/find where slot=$baseDisk]] > 0) do={ + :put ("Device $baseDisk found but $targetDisk is not available.") + :put "Format $baseDisk as ext4? ALL DATA WILL BE ERASED!" + :put "Press 'y' to confirm, any other key to cancel:" + :local key [/terminal/inkey timeout=30] + :if ($key = 121 || $key = 89) do={ + :put "Formatting $baseDisk as ext4..." + /disk/format-drive $baseDisk file-system=ext4 label=$baseDisk + :delay 3s + :do { :set diskFree [/disk/get [find where mount-point=$targetDisk] free] } on-error={} + :if ($diskFree = 0) do={ + :put ("ERROR: $targetDisk not found after formatting.") + :put "Check mount point: /disk/print" + :error ("Mount point $targetDisk not found after formatting") + } + :put ("Formatted OK. Free: " . ($diskFree / 1048576) . " MB") + } else={ + :error "Formatting cancelled" + } + } else={ + :put ("ERROR: Storage device $targetDisk not found.") + :put "Check available disks: /disk/print" + :error ("Storage not found: " . $targetDisk) + } + } else={ + :put ("Storage OK: $targetDisk (" . ($diskFree / 1048576) . " MB free)") + } +} + +# 1. Uninstall and update scripts +/system/script/add name=awg3vds-uninstall comment=awg3vds source={ + :put "Uninstallimg AmneziaWG..." + :log info "Uninstallimg AmneziaWG..." + :local prevDNS "" + :do { :set prevDNS [/container/envs/get [find where list="awg3vds-env" key="AWG_PREV_DNS"] value] } on-error={} + :local prevTmpdir "" + :do { :set prevTmpdir [/container/envs/get [find where list="awg3vds-env" key="AWG_PREV_TMPDIR"] value] } on-error={} + /ip/route/remove [find where comment=awg3vds-tunnel] + /ip/route/remove [find where comment=awg3vds-dns] + :do { /system/scheduler/remove [find where comment~"awg3vds"] } on-error={} + :do { /system/script/remove [find where comment~"awg3vds" and name!="awg3vds-uninstall"] } on-error={} + /container/stop [find where interface=veth-awg3vds] + :delay 7s + /container/remove [find where interface=veth-awg3vds] + /container/envs/remove [find where list="awg3vds-env"] + :if ($prevDNS != "") do={ + :do { /ip/dns/set servers="$prevDNS" } on-error={} + :put ("DNS restored to: $prevDNS") + } + /container/config set tmpdir=$prevTmpdir + :put ("Container tmpdir restored to: $prevTmpdir") + /ip/firewall/nat/remove [find where out-interface="wg-awg3vds"] + /ip/firewall/nat/remove [find where src-address="172.19.14.100/30"] + /ip/address/remove [find where address="172.19.14.101/30"] + :do { /ipv6/firewall/nat/remove [find where comment=awg3vds-v6-nat] } on-error={} + :do { /ipv6/firewall/nat/remove [find where comment=awg3vds-dstnat6] } on-error={} + :do { /ipv6/firewall/filter/remove [find where comment=awg3vds-v6-out] } on-error={} + :do { /ipv6/firewall/filter/remove [find where comment=awg3vds-awg-in6] } on-error={} + :do { /ipv6/nd/remove [find where interface=veth-awg3vds] } on-error={} + :do { /ipv6/nd/prefix/remove [find where interface=veth-awg3vds] } on-error={} + :do { /ipv6/address/remove [find where comment=awg3vds-v6] } on-error={} + /interface/veth/remove [find where name="veth-awg3vds"] + /interface/wireguard/peers/remove [find where interface="wg-awg3vds"] + /ip/address/remove [find where interface="wg-awg3vds"] + /interface/wireguard/remove [find where name="wg-awg3vds"] + :do { /file/remove [find where name~"awg3vds.+tar"] } on-error={} + :do { /file/remove [find where name="usb1/awg3vds"] } on-error={} + :do { /file/remove [find where name="usb1/ru_ranges_timeout.rsc"] } on-error={} + :do { /file/remove [find where name="usb1/ru_ranges.rsc"] } on-error={} + :do { /file/remove [find where name~"usb1/pull"] } on-error={} + :put "Uninstall AmneziaWG Proxy complete!" + :log info "Uninstall AmneziaWG Proxy complete!" +# /system/script/remove [find where name=awg3vds-uninstall] +} +/system/script/add name=awg3vds-update comment=awg3vds source={ + :local cids [/container/find where interface=veth-awg3vds and !stopped] + :if ([:len $cids] = 0) do={ :set cids [/container/find where interface=veth-awg3vds and start-on-boot=yes] } + :if ([:len $cids] = 0) do={ :set cids [/container/find where interface=veth-awg3vds] } + :if ([:len $cids] = 0) do={ + :put "Container awg3vds not found" + :log warning "awg3vds-update: container not found" + } else={ + :local cid [:pick $cids ([:len $cids] - 1)] + :local img [/container/get $cid remote-image] + :local ver [/system/resource/get version] + :local dotPos [:find $ver "."] + :local rest [:pick $ver ($dotPos + 1) [:len $ver]] + :local endPos [:find $rest "."] + :if ([:typeof $endPos] = "nil") do={ :set endPos [:find $rest " "] } + :local minor [:tonum [:pick $rest 0 $endPos]] + :local wantRunning true + :do { :if ([/container/get $cid start-on-boot] != true) do={ :set wantRunning false } } on-error={} + :local healthy true + :if ([:len [/container/get $cid image-id]] = 0) do={ :set healthy false } + :if ($wantRunning) do={ + :do { :if ([/container/get $cid stopped] = true) do={ :set healthy false } } on-error={} + } + :if (!$healthy && $wantRunning && [:len [/container/get $cid image-id]] > 0) do={ + :put "Container is down - trying to start it" + :do { /container/start $cid } on-error={} + :delay 8s + :set healthy true + :do { :if ([/container/get $cid stopped] = true) do={ :set healthy false } } on-error={} + :if ($healthy) do={ + :put "Container is back up" + :log info "awg3vds: container restarted by the update script" + } + } + :if ($img = "" && $minor >= 22 && !$healthy) do={ + :local imgTag "latest" + :local rbModel "" + :do { :set rbModel [[:parse ":return [/system/routerboard/get model]"]] } on-error={} + :local bName [/system/resource/get board-name] + :if ($rbModel~"E50UG" || $rbModel~"E60iUGS" || $bName~"E50UG" || $bName~"E60iUGS" || $bName~"^hEX") do={ + :set imgTag "latest-armv5" + } + :set img ("ghcr.io/timbrs/awg-proxy:" . $imgTag) + :put ("Container is down and was installed from a file - pointing it at " . $img) + :log warning "awg3vds-update: broken file install, switching to the registry" + :do { /container/set $cid remote-image=$img } on-error={} + } + :if ($img = "") do={ + :put "Installed from a local image file - /container/repull only updates registry installs." + :put "Reinstall with the configurator on RouterOS 7.22+ to switch to one-command updates." + } else={ + :if ($minor < 22) do={ + :put ("/container/repull needs RouterOS 7.22+, this router runs " . $ver) + :if (!$healthy) do={ :log error ("awg3vds-update: container is down, and " . $ver . " has no /container/repull") } + } else={ + :local rootDir [/container/get $cid root-dir] + :if ([:pick $rootDir 0 1] = "/") do={ :set rootDir [:pick $rootDir 1 [:len $rootDir]] } + :local rootDirOrig $rootDir + :local slashPos [:find $rootDir "/"] + :local disk $rootDir + :if ([:typeof $slashPos] != "nil") do={ :set disk [:pick $rootDir 0 $slashPos] } + :local verPath "awg-update-check.json" + :if ($disk != "disk1") do={ + :do { /file/make-directory ($disk . "/pull") } on-error={} + /container/config set tmpdir=($disk . "/pull") + :set verPath ($disk . "/pull/awg-update-check.json") + } + :local newVer "" + :do { + /tool/fetch url="https://api.github.com/repos/timbrs/amneziawg-mikrotik-c/releases/latest" dst-path=$verPath http-max-redirect-count=10 + :local relJson [/file/get [find where name=$verPath] contents] + :local tagPos [:find $relJson "\"tag_name\":\""] + :if ([:typeof $tagPos] != "nil") do={ + :local tagRest [:pick $relJson ($tagPos + 12) [:len $relJson]] + :set newVer [:pick $tagRest 0 [:find $tagRest "\""]] + } + :do { /file/remove [find where name=$verPath] } on-error={} + } on-error={ :put "Could not read the published version" } + :local curVer "" + :do { :set curVer [/container/envs/get [find where list="awg3vds-env" key="AWG_IMAGE_VER"] value] } on-error={} + :local doPull true + :if ($healthy) do={ + :if ($newVer = "") do={ + :set doPull false + :put "Published version unknown - leaving the healthy container alone" + } + :if ($newVer != "" && $newVer = $curVer) do={ + :set doPull false + :put ("Already on " . $curVer . " - nothing to pull, tunnel untouched") + } + } + :if ($doPull) do={ + :if (!$healthy) do={ + :put "Container is not healthy - pulling the image again" + :log warning "awg3vds-update: container unhealthy, forcing a pull" + } + :put ("Updating " . $img . " ...") + :log info "awg3vds: repull started" + :do { /file/remove [find where name~($disk . "/awg3vds.backup")] } on-error={} + :do { [:parse "/container/set $cid ignore-remote-image-change=yes"] } on-error={} + /container/repull $cid + :local waited 0 + :while ([:len [/container/get $cid image-id]] = 0 && $waited < 180) do={ + :delay 3s + :set waited ($waited + 3) + } + :if ([:len [/container/get $cid image-id]] = 0) do={ + :put "Pull failed - retrying once in 15s" + :delay 15s + /container/repull $cid + :set waited 0 + :while ([:len [/container/get $cid image-id]] = 0 && $waited < 180) do={ + :delay 3s + :set waited ($waited + 3) + } + } + :local backUp false + :if ([:len [/container/get $cid image-id]] > 0) do={ + :set backUp true + :if ($wantRunning) do={ + :delay 3s + :do { /container/start $cid } on-error={} + :delay 8s + :set backUp false + :do { :if ([/container/get $cid stopped] != true) do={ :set backUp true } } on-error={} + } + } + :if (!$backUp) do={ + :put "Container did not come back up - rebuilding it from the registry" + :log warning "awg3vds-update: container did not come back, rebuilding" + :do { /container/stop $cid } on-error={} + :delay 5s + :do { /container/remove $cid } on-error={} + :delay 3s + :do { /file/remove [find where name~($disk . "/awg3vds.backup")] } on-error={} + :do { /container/add remote-image=$img interface=veth-awg3vds envlist=awg3vds-env hostname=awg3vds root-dir=$rootDirOrig logging=no start-on-boot=yes comment=awg3vds } on-error={} + :set waited 0 + :local newCids [/container/find where interface=veth-awg3vds and start-on-boot=yes] + :if ([:len $newCids] = 0) do={ :set newCids [/container/find where interface=veth-awg3vds] } + :while ([:len $newCids] > 0 && [:len [/container/get [:pick $newCids ([:len $newCids] - 1)] image-id]] = 0 && $waited < 180) do={ + :delay 3s + :set waited ($waited + 3) + } + :if ([:len $newCids] > 0 && [:len [/container/get [:pick $newCids ([:len $newCids] - 1)] image-id]] > 0) do={ + :do { /container/set [:pick $newCids ([:len $newCids] - 1)] shm-size=4M } on-error={} + :do { [:parse "/container/set [find where interface=veth-awg3vds] ignore-remote-image-change=yes"] } on-error={} + :do { [:parse "/container/set [find where interface=veth-awg3vds] restart-policy=on-failure restart-interval=30s restart-max-count=10"] } on-error={} + :do { /container/start [:pick $newCids ([:len $newCids] - 1)] } on-error={} + :delay 8s + :do { :if ([/container/get [:pick $newCids ([:len $newCids] - 1)] stopped] != true) do={ :set backUp true } } on-error={} + } + :if ($backUp) do={ + :put "Container rebuilt" + :log info "awg3vds: container rebuilt after update" + } else={ + :put "Rebuild failed - the tunnel is down. Netwatch keeps the router online meanwhile." + :put "This script runs again on the next schedule and will retry." + :log error "awg3vds-update: rebuild failed, tunnel is down" + } + } + :if ($backUp && $newVer != "") do={ + :do { /container/envs/remove [find where list="awg3vds-env" key="AWG_IMAGE_VER"] } on-error={} + :do { /container/envs/add list=awg3vds-env key=AWG_IMAGE_VER value=$newVer } on-error={} + } + :do { /file/remove [find where name~($disk . "/awg3vds.backup")] } on-error={} + :if ($backUp) do={ + :put ("Update done: " . $img) + :log info "awg3vds: update done" + } + } + } + } + } +} +# Daily update check. Skipped if scheduler is not allowed by device-mode +{ + :local schedOk true + :do { :set schedOk [/system/device-mode/get scheduler] } on-error={} + :if ($schedOk) do={ + /system/scheduler/add name=awg3vds-update on-event="/system/script/run awg3vds-update" start-time=04:30:00 interval=1d comment=awg3vds + } else={ + :put "WARNING: scheduler not allowed by device-mode, no daily update check." + :put "Update by hand: /system/script/run awg3vds-update" + :put "To allow it: /system/device-mode/update scheduler=yes" + } +} + +# 2. Network infrastructure +/interface/veth/add name=veth-awg3vds address=172.19.14.102/30 gateway=172.19.14.101 +/ip/address/add address=172.19.14.101/30 interface=veth-awg3vds +/ip/firewall/nat/add chain=srcnat action=masquerade src-address=172.19.14.100/30 + +# 3. WireGuard interface (MikroTik derives the public key automatically) +/interface/wireguard/add name=wg-awg3vds private-key="AEU+diR7SCIEOtwOWSWR3pEpkw6v0Qro2LRF0SnPpnw=" listen-port=41430 mtu=1320 disabled=yes +/interface/wireguard/peers/add interface=wg-awg3vds public-key="MMWjD/TPNpupCvhXLCAw0xHXV4N6jgtQkg9Pl6pcQhU=" preshared-key="r9B13bB7gUTqde6zgBDfffFIUN6puP2gOWdK5zVS3nw=" endpoint-address=172.19.14.102 endpoint-port=51820 allowed-address=10.31.31.0/24,0.0.0.0/0 persistent-keepalive=14 +/ip/address/add address=10.31.31.2/24 interface=wg-awg3vds + +# 4. Container environment variables +/container/envs/add list=awg3vds-env key=AWG_LISTEN value=":51820" +/container/envs/add list=awg3vds-env key=AWG_REMOTE value="89.110.101.17:31031" +/container/envs/add list=awg3vds-env key=AWG_JC value="5" +/container/envs/add list=awg3vds-env key=AWG_JMIN value="510" +/container/envs/add list=awg3vds-env key=AWG_JMAX value="952" +/container/envs/add list=awg3vds-env key=AWG_S1 value="138" +/container/envs/add list=awg3vds-env key=AWG_S2 value="105" +/container/envs/add list=awg3vds-env key=AWG_H1 value="457615290-457646150" +/container/envs/add list=awg3vds-env key=AWG_H2 value="1307355386-1307363580" +/container/envs/add list=awg3vds-env key=AWG_H3 value="2441734303-2441781787" +/container/envs/add list=awg3vds-env key=AWG_H4 value="3719180788-3719195844" +/container/envs/add list=awg3vds-env key=AWG_SERVER_PUB value="MMWjD/TPNpupCvhXLCAw0xHXV4N6jgtQkg9Pl6pcQhU=" +/container/envs/add list=awg3vds-env key=AWG_CLIENT_PUB value=[/interface/wireguard/get [find name=wg-awg3vds] public-key] +/container/envs/add list=awg3vds-env key=AWG_S3 value="51" +/container/envs/add list=awg3vds-env key=AWG_S4 value="22" +/container/envs/add list=awg3vds-env key=AWG_I1 value="" +/container/envs/add list=awg3vds-env key=AWG_I2 value="" +/container/envs/add list=awg3vds-env key=AWG_I3 value="" +/container/envs/add list=awg3vds-env key=AWG_I4 value="" +/container/envs/add list=awg3vds-env key=AWG_I5 value="" +/container/envs/add list=awg3vds-env key=AWG_HEADER_PROTECTION_KEY value="FkGxbrW6ds3YPWNl48OWFEccrLC4tF94z9MnoKUZUsM=" +/container/envs/add list=awg3vds-env key=AWG_CONTENT_PADDING value="54-119" +/container/envs/add list=awg3vds-env key=AWG_REKEY_AFTER value="102-130" +/container/envs/add list=awg3vds-env key=AWG_REKEY_TIMEOUT value="6-8" +/container/envs/add list=awg3vds-env key=AWG_REJECT_AFTER value="174-195" +/container/envs/add list=awg3vds-env key=AWG_KEEPALIVE_TIMEOUT value="14-21" +/container/envs/add list=awg3vds-env key=AWG_MAX_HANDSHAKE_ATTEMPTS value="12-14" +/container/envs/add list=awg3vds-env key=AWG_NO_DF value="1" +# Perf: give each forwarding thread its own core (4+ core routers) +{ :if ([/system/resource/get cpu-count] >= 4) do={ /container/envs/add list=awg3vds-env key=AWG_CPU_C2S value="1"; /container/envs/add list=awg3vds-env key=AWG_CPU_S2C value="2" } } +# NOTE on MTU: the value above assumes this tunnel is the last hop. +# If the server forwards your traffic into another tunnel, subtract +# that tunnel's overhead too, or every packet leaves in two fragments. + +# 5. DNS +{ :local rawDNS [/ip/dns/get servers]; :local prevDNS ""; :foreach s in=[:toarray $rawDNS] do={ :if ([:len $prevDNS] > 0) do={ :set prevDNS "$prevDNS,$s" } else={ :set prevDNS $s } }; /container/envs/add list=awg3vds-env key=AWG_PREV_DNS value="$prevDNS" } +# NOTE: replaces existing DNS configuration +/ip/dns/set servers=89.110.101.17,8.8.4.4 +# DNS 89.110.101.17 идёт общим маршрутом (в активный туннель / default), +# без привязки к wg-awg3vds: иначе падение туннеля уносит с собой резолв. +# DNS 8.8.4.4 идёт общим маршрутом (в активный туннель / default), +# без привязки к wg-awg3vds: иначе падение туннеля уносит с собой резолв. + +# 6. Download, create and start container +:local prevTmpdir [/container/config/get tmpdir] +/container/envs/add list=awg3vds-env key=AWG_PREV_TMPDIR value=$prevTmpdir +/container/config set tmpdir=usb1/pull memory-high=200M +{ + :local arch [/system/resource/get architecture-name] + :local ver [/system/resource/get version] + :local dotPos [:find $ver "."] + :local rest [:pick $ver ($dotPos + 1) [:len $ver]] + :local endPos [:find $rest "."] + :if ([:typeof $endPos] = "nil") do={ :set endPos [:find $rest " "] } + :local minor [:tonum [:pick $rest 0 $endPos]] + :local suffix "" + :if ($minor <= 20) do={ :set suffix "-7.20-Docker" } + :local file "" + :local imgTag "latest" + :if ($arch = "arm64") do={ :set file ("awg-proxy-arm64" . $suffix . ".tar.gz") } + :if ($arch = "arm") do={ + :set file ("awg-proxy-arm" . $suffix . ".tar.gz") + :local rbModel "" + :do { :set rbModel [[:parse ":return [/system/routerboard/get model]"]] } on-error={} + :local bName [/system/resource/get board-name] + :if ($rbModel~"E50UG" || $rbModel~"E60iUGS" || $bName~"E50UG" || $bName~"E60iUGS" || $bName~"^hEX") do={ + :set file ("awg-proxy-armv5" . $suffix . ".tar.gz") + :set imgTag "latest-armv5" + } + } + :if ($arch ~ "x86") do={ :set file ("awg-proxy-amd64" . $suffix . ".tar.gz") } + :if ($file = "") do={ :error "Unsupported architecture: $arch" } + :local url "https://github.com/timbrs/amneziawg-mikrotik-c/releases/latest/download/$file" + :local filePath ("usb1/pull/" . $file) + :local altPath ("usb1/" . $file) + :local rootDir "usb1/awg3vds" + :do { /file/make-directory usb1/pull } on-error={} + :if ([:len [/file/find where name=$filePath]] = 0 && [:len [/file/find where name=$altPath]] > 0) do={ + :set filePath $altPath + } + :local added false + :local fetched false + :if ([:len [/file/find where name=$filePath]] > 0) do={ + :put ("Using image already on the router: " . $filePath) + /container/add file=$filePath interface=veth-awg3vds envlist=awg3vds-env hostname=awg3vds root-dir=$rootDir logging=no start-on-boot=yes comment=awg3vds + :set added true + } + :if (!$added && $minor >= 22) do={ + :local img ("ghcr.io/timbrs/awg-proxy:" . $imgTag) + :put ("Pulling " . $img) + /container/add remote-image=$img interface=veth-awg3vds envlist=awg3vds-env hostname=awg3vds root-dir=$rootDir logging=no start-on-boot=yes comment=awg3vds + :local cids [/container/find where interface=veth-awg3vds] + :local waited 0 + :while ([:len $cids] > 0 && [:len [/container/get [:pick $cids 0] image-id]] = 0 && $waited < 120) do={ + :delay 2s + :set waited ($waited + 2) + } + :if ([:len $cids] > 0 && [:len [/container/get [:pick $cids 0] image-id]] > 0) do={ + :set added true + :put ("Pulled from registry in " . $waited . "s") + :do { + :local verPath ($filePath . ".rel") + /tool/fetch url="https://api.github.com/repos/timbrs/amneziawg-mikrotik-c/releases/latest" dst-path=$verPath http-max-redirect-count=10 + :local relJson [/file/get [find where name=$verPath] contents] + :local tagPos [:find $relJson "\"tag_name\":\""] + :local tagRest [:pick $relJson ($tagPos + 12) [:len $relJson]] + /container/envs/add list=awg3vds-env key=AWG_IMAGE_VER value=[:pick $tagRest 0 [:find $tagRest "\""]] + /file/remove [find where name=$verPath] + } on-error={} + } else={ + :put "Registry unavailable, falling back to the release archive" + :do { /container/remove $cids } on-error={} + :delay 2s + } + } + :if (!$added) do={ + :local freeStorage 0 + :do { :set freeStorage [/disk/get [find where mount-point="usb1"] free] } on-error={} + :if ($freeStorage < 262144) do={ + :put ("WARNING: Low disk space (" . ($freeStorage / 1024) . "KB free). Need at least 256KB.") + :put "See: https://github.com/timbrs/amneziawg-mikrotik-c#insufficient-disk-space" + :error "Insufficient disk space" + } + :put ("Fetching: $url -> " . $filePath) + /tool/fetch url=$url dst-path=$filePath http-max-redirect-count=10 + /container/add file=$filePath interface=veth-awg3vds envlist=awg3vds-env hostname=awg3vds root-dir=$rootDir logging=no start-on-boot=yes comment=awg3vds + :set fetched true + } + :if ($minor > 20) do={ [:parse "/container/set [find where interface=veth-awg3vds] shm-size=4M"] } + :do { [:parse "/container/set [find where interface=veth-awg3vds] ignore-remote-image-change=yes"] } on-error={} + :do { [:parse "/container/set [find where interface=veth-awg3vds] restart-policy=on-failure restart-interval=30s restart-max-count=10"] } on-error={} + :if ($fetched) do={ /file/remove $filePath } + :local freeMem [/system/resource/get free-memory] + :if ($freeMem < 16777216) do={ + :put ("WARNING: Low memory (" . ($freeMem / 1048576) . "MB free). 16MB+ recommended.") + } + /container/start [find where interface=veth-awg3vds] + :do { /file/remove [find where name="console-dump.txt"] } on-error={} + :put "Waiting for container to start..." + :delay 5s + /interface/wireguard/enable wg-awg3vds + :put "WireGuard interface enabled" + :put "Installation complete!" + :put "Ping test: 89.110.101.17 via AmneziaWG tunnel. repeat 10 times" + /ping 89.110.101.17 count=10 interval=1 + :put "" + :put "======= NEXT STEPS =======" + :put "" + :put "Route specific traffic through the AmneziaWG tunnel:" + :put "" + :put " Route a single host:" + :put " /ip/route/add dst-address=8.8.8.8/32 gateway=wg-awg3vds comment=awg3vds-tunnel" + :put "" + :put " Route a subnet:" + :put " /ip/route/add dst-address=100.0.0.0/8 gateway=wg-awg3vds comment=awg3vds-tunnel" + :put "" + :put " Remove a route:" + :put " /ip/route/remove [find where comment=awg3vds-tunnel dst-address=8.8.8.8/32]" + :put "" + :put " Show all tunnel routes:" + :put " /ip/route/print where comment=awg3vds-tunnel" + :put "" + :put " Update the container:" + :put " /system/script/run awg3vds-update" + :put "" + :put " Uninstall:" + :put " /system/script/run awg3vds-uninstall" + :put "=========================" +} + +# 7. Verification +# /container/print +# /interface/wireguard/print +# /interface/wireguard/peers/print