From 80ac8e969e1c537c13c85c689036bc28790e6506 Mon Sep 17 00:00:00 2001 From: vados-dev Date: Mon, 17 Aug 2026 11:00:07 +0300 Subject: [PATCH] Backup for MikroMaster created successfully at Aug 17 11:00:07. --- .../20260817/20260817110002-Binary.backup | Bin 0 -> 111955 bytes .../20260817/20260817110002-Config.rsc | 1364 ++++++ .../20260817/20260817110002-Diff-Config.rsc | 3690 +++++++++++++++++ MikroMaster/tmp/Config.rsc | 0 MikroMaster/tmp/Diff-Config.rsc | 65 - 5 files changed, 5054 insertions(+), 65 deletions(-) create mode 100644 MikroMaster/20260817/20260817110002-Binary.backup create mode 100644 MikroMaster/20260817/20260817110002-Config.rsc create mode 100644 MikroMaster/history/20260817/20260817110002-Diff-Config.rsc delete mode 100644 MikroMaster/tmp/Config.rsc delete mode 100644 MikroMaster/tmp/Diff-Config.rsc diff --git a/MikroMaster/20260817/20260817110002-Binary.backup b/MikroMaster/20260817/20260817110002-Binary.backup new file mode 100644 index 0000000000000000000000000000000000000000..e4200862527659640ec206ce3496d69c828ea93f GIT binary patch literal 111955 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

FM`M(Lk>fvIWDT+djmSf08ULiEyG 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"L0J~*PpRkv+l;z>|BV3dhB3j09PHt@NS}}} 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\"data\");\ + \n\ + \n#/usb1/mikro_bak_rsa.pub\ + \n\ + \n\ + \n#:local FetchFile AM-DOHCert.rsc\ + \n\ + \n\ + \n\ + \n:global GlobalScriptsUrl \"https://ros.vados.ru/tmp/\";\ + \n\ + \n:global MkDir;\ + \n\ + \n\ + \n:local FetchFile Manager@id_rsa.pub\ + \n:local localDir \"/\";\ + \n\ + \n\ + \n\ + \n\$MkDir \$localDir;\ + \n\ + \n\ + \n\ + \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \$FetchFile) dst-path=(\ + \$localDir . \$FetchFile);\ + \n" +add comment="Global Config Script" dont-require-permissions=no name=\ + AM-GlobalConfig owner=AM-GlobalConfig policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ + !rsc by Vados\r\ + \n# RouterOS script: AM-GlobalConfig\r\ + \n# Script comment: Global Config Script\r\ + \n# Copyright (c) 2007-2026 Vados \r\ + \n#\r\ + \n#\r\ + \n# Warning: Dont touch this line!\r\ + \n:global Identity [/system/identity/get name];\r\ + \n:global GlobalConfReady false;\r\ + \n#\r\ + \n#\r\ + \n# Global Url For Amster scripts to fetch\r\ + \n# most be defined in AM-Init-Script or AM-setup scripts\r\ + \n:global GlobalScriptsUrl \"https://ros.vados.ru/\";\r\ + \n:global ScriptsUrlSuffix (a);\r\ + \n:global CheckSumsVerify true;\r\ + \n\r\ + \n:global ScriptUpdatesCRLF true;\r\ + \n:global CommentsInScripts true;\r\ + \n\r\ + \n# Debug output:\r\ + \n:global PrintDebug true; #false;\r\ + \n\r\ + \n# Debug output for specific script:\r\ + \n#:set (\$PrintDebugOverride->\"AM-GlobalFunc\") true;\r\ + \n\r\ + \n# Debug logs\r\ + \n# Other actions (disk, email, remote or support) can be used as well.\r\ + \n# I do not recommend using echo - use debug output instead (https://rsc.\ + eworm.de/main/DEBUG.html#debug-output).\r\ + \n#/system/logging/add topics=script,debug action=memory;\r\ + \n\r\ + \n:global MikrotikUpgradeUrl \"https://upgrade.mikrotik.com/routeros\";\r\ + \n:global Domain \"WORKGROUP\";\r\ + \n\r\ + \n:global EmailGeneralTo \"vados@vados.ru\";\r\ + \n#:global EmailGeneralCc \"\";\r\ + \n\r\ + \n# \$ScriptInstallUpdate mod/notification-telegram\r\ + \n:global TelegramTokenId \"8390868324:AAG3_d1hfVR2M6pGAgDK6ZvhOe4J97nyopw\ + \";\r\ + \n:global TelegramChatId \"-1003631309063\"; #\"454403445\";\r\ + \n# Use this to send notifications to a specific topic in group.\r\ + \n#:global TelegramThreadId \"30\";\r\ + \n# Using telegram-chat you have to define trusted chat ids (not group ids\ + !)\r\ + \n# or user names. Groups allow to chat with devices simultaneously.\r\ + \n:global TelegramChatIdsTrusted {\r\ + \n \"454403445\"\r\ + \n \"-1003631309063\"\r\ + \n \"-5124482807\"\r\ + \n \"1087968824\";\r\ + \n};\r\ + \n# \"-5294757340\";\r\ + \n\r\ + \n:global TelegramChatGroups \"(all)\";\r\ + \n#:global TelegramChatGroups \"(all|home|office)\";\r\ + \n\r\ + \n:global NotificationFunctions {\r\ + \n \"email\"\r\ + \n \"telegram\";\r\ + \n};\r\ + \n# Toggle this to disable symbols in notifications.\r\ + \n:global NotificationsWithSymbols true;\r\ + \n:global TerminalColorOutput true;\r\ + \n\r\ + \n:global DetectIpAddrDefault \"https://ipv4.mikrotik.ovh/\";\r\ + \n:global DetectIpAddrFallback \"https://api.ipify.org/\";\r\ + \n\r\ + \n## Update channel. Possible values: stable, long-term, testing, developm\ + ent\r\ + \n:global updateChannel \"stable\";\r\ + \n\r\ + \n:global CertRenewUrl (\$GlobalScriptsUrl . \"certs/\" . \$Identity . \"/\ + \");\r\ + \n:global CertRenewTime 2w;\r\ + \n:global CertRenewPass (a); #{\r\ + \n# \"\";\r\ + \n# \"v3ry-s3cr3t\";\r\ + \n# \"4n0th3r-s3cr3t\";\r\ + \n#};\r\ + \n:global CertWarnTime 1w;\r\ + \n:global CertIssuedExportPass (a); # {\r\ + \n# \"\";\r\ + \n# \"cert1-cn\"=\"v3ry-s3cr3t\";\r\ + \n# \"cert2-cn\"=\"4n0th3r-s3cr3t\";\r\ + \n#};\r\ + \n\r\ + \n# Script BackupAndUpdate mode, possible values: backup,\r\ + \n# updateOnce - Update once as \"osnotify\" and back \"osnotify\" mode (i\ + n terminal run :set OSUpdateMode updateOnce; \$OSUpdateMode;). \r\ + \n# osupdate - Update if available and creates backups before/after update\ + \_(ignores `forceBackup`)\r\ + \n# Set `forceBackup` to true to always create backups, even\ + \_without updates\r\ + \n# osnotify - Set `forceBackup` to always create backups on every run\r\ + \n:global DevInfoIncludeIP true;\r\ + \n:global BackupAndUpdateMode \"osnotify\"\r\ + \n\r\ + \n:global forceBackup true;\r\ + \n:global BackupPassword \"Peskar55\";\r\ + \n\r\ + \n# SFTP Backup Variables\r\ + \n:global BackupRandomDelay 0;\r\ + \n:global BackupUploadUrl \"sftp://amster.vados.ru/upload/\";\r\ + \n:global BackupUploadUser \$Identity;\r\ + \n:global BackupUploadPass \"root.mnuc.backuper\";\r\ + \n\r\ + \n:global BackupSendBinary true;\r\ + \n:global BackupSendExport true;\r\ + \n:global BackupSendGlobalConfig true;\r\ + \n:global BackupSendScripts true;\r\ + \n\r\ + \n# Remove local file after uploading if no errors\r\ + \n:global BackupRmLocal true;\r\ + \n\r\ + \n# Local Backups Root Directory \r\ + \n:global BackupLocalRoot \"tmpfs\";\r\ + \n\r\ + \n# Encrypt Backup\r\ + \n:global BackupEncrypt true;\r\ + \n\r\ + \n# Sensitive information in Backups\r\ + \n:global BackupSens true;\r\ + \n\r\ + \n# User Export\r\ + \n:global BackupUser true;\r\ + \n\r\ + \n# License Export (not for CHR, will silently skip)\r\ + \n:global BackupLicense false;\r\ + \n\r\ + \n# SSH Keys\r\ + \n:global BackupSshKeys true;\r\ + \n\r\ + \n# Certificate Export\r\ + \n:global BackupCerts true;\r\ + \n\r\ + \n# Certificate Password\r\ + \n:global BackupCertsPasswd \"\";\r\ + \n\r\ + \n# User-Manager Export\r\ + \n:global BackupUserMan false;\r\ + \n\r\ + \n# The Dude Export\r\ + \n:global BackupDude false;\r\ + \n\r\ + \n# User Files to export, comma-separated string or array of strings\r\ + \n# User Files are not removed on backup\r\ + \n# Any directory paths will be removed (/ -> _) on remote file\r\ + \n# Nonpresent files are silently skipped\r\ + \n:global BackupUserList \"autosupout.rif,autosupout.old.rif\";\r\ + \n\r\ + \n# load functions and any custom scripts\r\ + \n# [ /system/script/find where name=\"global-config-ov\ + erlay\" ], \\\r\ + \n# [ /system/script/find where name~\"^global-config-o\ + verlay\\\\.d/.\" ]\r\ + \n#\r\ + \n#:foreach Script in=([ /system/script/find where name=\"Amster-TGglobalV\ + ars\" ], [ /system/script/find where name=\"Amster-TGglobalFunc\" ]) do={\ + \r\ + \n# :onerror Err {\r\ + \n# /system/script/run \$Script;\r\ + \n# } do={\r\ + \n# :log error (\"Loading configuration from configs and functions\"\ + \_. [ /system/script/get \$Script name ] . \" failed: \" . \$Err);\r\ + \n# }\r\ + \n#}\r\ + \n#:log info \"\\ndevMode = \$devMode\";\r\ + \n#:log info \"\\ndevRunning = \$devRunning\";\r\ + \n:foreach Script in=[ /system/script/find where source~\"^#!rsc by Vados \ + GlobalRUN\\r\?\\n\" ] do={\r\ + \n :onerror Err {\r\ + \n /system/script/run \$Script;\r\ + \n } do={\r\ + \n :log error (\"Run script \" . [ /system/script/get \$Script name \ + ] . \" width marker \\\" GlobalRUN\\\" failed: \" . \$Err);\r\ + \n }\r\ + \n}\r\ + \n\r\ + \n# signal we are ready\r\ + \n:set GlobalConfReady true;\r\ + \n:while (\$GlobalConfReady != true) do={:delay 500ms};\r\ + \n" +add comment=GENERATOR dont-require-permissions=no name=awg2vds owner=vados \ + policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \ + source="# ============================================================\ + \n# AWG Proxy -- MikroTik RouterOS (protocol: v2)\ + \n# 2026-07-21 10:33:39\ + \n# ============================================================\ + \n\ + \n# 0. Check prerequisites\ + \n:if ([:len [/system/package/find where name=\"container\" disabled=no]] \ + = 0) do={\ + \n :put \"Container package is not installed or disabled. Install it and \ + reboot.\"\ + \n :error \"Usage: /system/device-mode/update container=yes\"\ + \n}\ + \n\ + \n# Check storage device\ + \n{\ + \n :local targetDisk \"usb1\"\ + \n :local diskFree 0\ + \n :do { :set diskFree [/disk/get [find where mount-point=\$targetDisk] f\ + ree] } on-error={}\ + \n :if (\$diskFree = 0) do={\ + \n :local baseDisk \$targetDisk\ + \n :local dashPos [:find \$targetDisk \"-part\"]\ + \n :if ([:typeof \$dashPos] != \"nil\") do={ :set baseDisk [:pick \$tar\ + getDisk 0 \$dashPos] }\ + \n :if ([:len [/disk/find where slot=\$baseDisk]] > 0) do={\ + \n :put (\"Device \$baseDisk found but \$targetDisk is not available.\ + \")\ + \n :put \"Format \$baseDisk as ext4\? ALL DATA WILL BE ERASED!\"\ + \n :put \"Press 'y' to confirm, any other key to cancel:\"\ + \n :local key [/terminal/inkey timeout=30]\ + \n :if (\$key = 121 || \$key = 89) do={\ + \n :put \"Formatting \$baseDisk as ext4...\"\ + \n /disk/format-drive \$baseDisk file-system=ext4 label=\$baseDisk\ + \n :delay 3s\ + \n :do { :set diskFree [/disk/get [find where mount-point=\$targetD\ + isk] free] } on-error={}\ + \n :if (\$diskFree = 0) do={\ + \n :put (\"ERROR: \$targetDisk not found after formatting.\")\ + \n :put \"Check mount point: /disk/print\"\ + \n :error (\"Mount point \$targetDisk not found after formatting\ + \")\ + \n }\ + \n :put (\"Formatted OK. Free: \" . (\$diskFree / 1048576) . \" MB\ + \")\ + \n } else={\ + \n :error \"Formatting cancelled\"\ + \n }\ + \n } else={\ + \n :put (\"ERROR: Storage device \$targetDisk not found.\")\ + \n :put \"Check available disks: /disk/print\"\ + \n :error (\"Storage not found: \" . \$targetDisk)\ + \n }\ + \n } else={\ + \n :put (\"Storage OK: \$targetDisk (\" . (\$diskFree / 1048576) . \" M\ + B free)\")\ + \n }\ + \n}\ + \n\ + \n# 1. Uninstall script\ + \n/system/script/add name=awg2vds-uninstall comment=awg2vds source={\ + \n :put \"Uninstallimg AmneziaWG...\"\ + \n :log info \"Uninstallimg AmneziaWG...\"\ + \n :local prevDNS \"\"\ + \n :do { :set prevDNS [/container/envs/get [find where list=\"awg2vds-env\ + \" key=\"AWG_PREV_DNS\"] value] } on-error={}\ + \n :local prevTmpdir \"\"\ + \n :do { :set prevTmpdir [/container/envs/get [find where list=\"awg2vds-\ + env\" key=\"AWG_PREV_TMPDIR\"] value] } on-error={}\ + \n /ip/route/remove [find where comment=awg2vds-tunnel]\ + \n /ip/route/remove [find where comment=awg2vds-dns]\ + \n /container/stop [find where interface=veth-awg2vds]\ + \n :delay 7s\ + \n /container/remove [find where interface=veth-awg2vds]\ + \n /container/envs/remove [find where list=\"awg2vds-env\"]\ + \n :if (\$prevDNS != \"\") do={\ + \n :do { /ip/dns/set servers=\"\$prevDNS\" } on-error={}\ + \n :put (\"DNS restored to: \$prevDNS\")\ + \n }\ + \n /container/config set tmpdir=\$prevTmpdir\ + \n :put (\"Container tmpdir restored to: \$prevTmpdir\")\ + \n /ip/firewall/nat/remove [find where out-interface=\"wg-awg2vds\"]\ + \n /ip/firewall/nat/remove [find where src-address=\"172.20.200.68/30\"]\ + \n /ip/address/remove [find where address=\"172.20.200.69/30\"]\ + \n /interface/veth/remove [find where name=\"veth-awg2vds\"]\ + \n /interface/wireguard/peers/remove [find where interface=\"wg-awg2vds\"\ + ]\ + \n /ip/address/remove [find where interface=\"wg-awg2vds\"]\ + \n /interface/wireguard/remove [find where name=\"wg-awg2vds\"]\ + \n :do { /file/remove [find where name~\"awg2vds.+tar\"] } on-error={}\ + \n :do { /file/remove [find where name=\"usb1/awg2vds\"] } on-error={}\ + \n :do { /file/remove [find where name=\"usb1/ru_ranges_timeout.rsc\"] } \ + on-error={}\ + \n :do { /file/remove [find where name~\"usb1/pull\"] } on-error={}\ + \n :put \"Uninstall AmneziaWG Proxy complete!\"\ + \n :log info \"Uninstall AmneziaWG Proxy complete!\"\ + \n /system/script/remove [find where name=awg2vds-uninstall]\ + \n}\ + \n\ + \n# 2. Network infrastructure\ + \n/interface/veth/add name=veth-awg2vds address=172.20.200.70/30 gateway=1\ + 72.20.200.69\ + \n/ip/address/add address=172.20.200.69/30 interface=veth-awg2vds\ + \n/ip/firewall/nat/add chain=srcnat action=masquerade src-address=172.20.2\ + 00.68/30\ + \n\ + \n# 3. WireGuard interface (MikroTik derives the public key automatically)\ + \n/interface/wireguard/add name=wg-awg2vds private-key=\"4LNSJJNEDeT2LFXkF\ + x0XyrNp2Mp7YXlS8SawhqNfKGQ=\" listen-port=26084 disabled=yes\ + \n/interface/wireguard/peers/add interface=wg-awg2vds public-key=\"qHFd72X\ + DJJ5UrUZCZ0vRFQmzxP7eUYcOuaGL9ZbHtyg=\" preshared-key=\"ckhzjCcr15ve+IeDRY\ + veYITR7a/CMZCcOZ2Z0cABKD8=\" endpoint-address=172.20.200.70 endpoint-port=\ + 51820 allowed-address=10.10.10.1/24,10.30.30.0/24,0.0.0.0/0 persistent-kee\ + palive=10\ + \n/ip/address/add address=10.10.10.2/24 interface=wg-awg2vds\ + \n\ + \n# 4. Container environment variables\ + \n/container/envs/add list=awg2vds-env key=AWG_LISTEN value=\":51820\"\ + \n/container/envs/add list=awg2vds-env key=AWG_REMOTE value=\"109.107.177.\ + 79:443\"\ + \n/container/envs/add list=awg2vds-env key=AWG_JC value=\"6\"\ + \n/container/envs/add list=awg2vds-env key=AWG_JMIN value=\"171\"\ + \n/container/envs/add list=awg2vds-env key=AWG_JMAX value=\"481\"\ + \n/container/envs/add list=awg2vds-env key=AWG_S1 value=\"50\"\ + \n/container/envs/add list=awg2vds-env key=AWG_S2 value=\"139\"\ + \n/container/envs/add list=awg2vds-env key=AWG_H1 value=\"1189447486-11894\ + 48396\"\ + \n/container/envs/add list=awg2vds-env key=AWG_H2 value=\"538303610-538304\ + 276\"\ + \n/container/envs/add list=awg2vds-env key=AWG_H3 value=\"101001960-101002\ + 598\"\ + \n/container/envs/add list=awg2vds-env key=AWG_H4 value=\"1783887443-17838\ + 87851\"\ + \n/container/envs/add list=awg2vds-env key=AWG_SERVER_PUB value=\"qHFd72XD\ + JJ5UrUZCZ0vRFQmzxP7eUYcOuaGL9ZbHtyg=\"\ + \n/container/envs/add list=awg2vds-env key=AWG_CLIENT_PUB value=[/interfac\ + e/wireguard/get [find name=wg-awg2vds] public-key]\ + \n/container/envs/add list=awg2vds-env key=AWG_S3 value=\"17\"\ + \n/container/envs/add list=awg2vds-env key=AWG_S4 value=\"6\"\ + \n/container/envs/add list=awg2vds-env key=AWG_I1 value=\"\"\ + \n/container/envs/add list=awg2vds-env key=AWG_I2 value=\"\"\ + \n/container/envs/add list=awg2vds-env key=AWG_I3 value=\"\"\ + \n/container/envs/add list=awg2vds-env key=AWG_I4 value=\"\"\ + \n/container/envs/add list=awg2vds-env key=AWG_I5 value=\"\"\ + \n\ + \n# 5. DNS\ + \n{ :local rawDNS [/ip/dns/get servers]; :local prevDNS \"\"; :foreach s i\ + n=[:toarray \$rawDNS] do={ :if ([:len \$prevDNS] > 0) do={ :set prevDNS \"\ + \$prevDNS,\$s\" } else={ :set prevDNS \$s } }; /container/envs/add list=aw\ + g2vds-env key=AWG_PREV_DNS value=\"\$prevDNS\" }\ + \n# NOTE: replaces existing DNS configuration\ + \n/ip/dns/set servers=10.10.10.1\ + \n/ip/route/add dst-address=10.10.10.1/32 gateway=wg-awg2vds distance=1 co\ + mment=awg2vds-dns\ + \n\ + \n# 6. Download, create and start container\ + \n:local prevTmpdir [/container/config/get tmpdir]\ + \n/container/envs/add list=awg2vds-env key=AWG_PREV_TMPDIR value=\$prevTmp\ + dir\ + \n/container/config set tmpdir=usb1/pull memory-high=200M\ + \n{\ + \n :local arch [/system/resource/get architecture-name]\ + \n :local ver [/system/resource/get version]\ + \n :local dotPos [:find \$ver \".\"]\ + \n :local rest [:pick \$ver (\$dotPos + 1) [:len \$ver]]\ + \n :local endPos [:find \$rest \".\"]\ + \n :if ([:typeof \$endPos] = \"nil\") do={ :set endPos [:find \$rest \" \ + \"] }\ + \n :local minor [:tonum [:pick \$rest 0 \$endPos]]\ + \n :local suffix \"\"\ + \n :if (\$minor <= 20) do={ :set suffix \"-7.20-Docker\" }\ + \n :local file \"\"\ + \n :if (\$arch = \"arm64\") do={ :set file (\"awg-proxy-arm64\" . \$suffi\ + x . \".tar.gz\") }\ + \n :if (\$arch = \"arm\") do={ :set file (\"awg-proxy-arm\" . \$suffix . \ + \".tar.gz\") }\ + \n :if (\$arch ~ \"x86\") do={ :set file (\"awg-proxy-amd64\" . \$suffix \ + . \".tar.gz\") }\ + \n :if (\$file = \"\") do={ :error \"Unsupported architecture: \$arch\" }\ + \n :local url \"https://github.com/timbrs/amneziawg-mikrotik-c/releases/l\ + atest/download/\$file\"\ + \n :local filePath (\"usb1/pull/\" . \$file)\ + \n :do { /file/make-directory usb1/pull } on-error={}\ + \n :if ([:len [/file/find where name=\$filePath]] = 0) do={\ + \n :local freeStorage 0\ + \n :do { :set freeStorage [/disk/get [find where mount-point=\"usb1\"] \ + free] } on-error={}\ + \n :if (\$freeStorage < 262144) do={\ + \n :put (\"WARNING: Low disk space (\" . (\$freeStorage / 1024) . \"K\ + B free). Need at least 256KB.\")\ + \n :put \"See: https://github.com/timbrs/amneziawg-mikrotik-c#insuffi\ + cient-disk-space\"\ + \n :error \"Insufficient disk space\"\ + \n }\ + \n :put (\"Fetching: \$url -> \" . \$filePath)\ + \n /tool/fetch url=\$url dst-path=\$filePath http-max-redirect-count=10\ + \n } else={\ + \n :put (\"File already exists: \" . \$filePath)\ + \n }\ + \n /container/add file=\$filePath interface=veth-awg2vds envlist=awg2vds-\ + env hostname=awg2vds root-dir=usb1/awg2vds logging=no start-on-boot=yes co\ + mment=awg2vds\ + \n :if (\$minor > 20) do={ [:parse \"/container/set [find where interface\ + =veth-awg2vds] shm-size=4M\"] }\ + \n /file/remove \$filePath\ + \n :local freeMem [/system/resource/get free-memory]\ + \n :if (\$freeMem < 16777216) do={\ + \n :put (\"WARNING: Low memory (\" . (\$freeMem / 1048576) . \"MB free)\ + . 16MB+ recommended.\")\ + \n }\ + \n /container/start [find where interface=veth-awg2vds]\ + \n :do { /file/remove [find where name=\"console-dump.txt\"] } on-error={\ + }\ + \n :put \"Waiting for container to start...\"\ + \n :delay 5s\ + \n /interface/wireguard/enable wg-awg2vds\ + \n :put \"WireGuard interface enabled\"\ + \n :put \"Installation complete!\"\ + \n :put \"Ping test: 10.10.10.1 via AmneziaWG tunnel. repeat 10 times\"\ + \n /ping 10.10.10.1 count=10 interval=1\ + \n :put \"\"\ + \n :put \"======= NEXT STEPS =======\"\ + \n :put \"\"\ + \n :put \"Route specific traffic through the AmneziaWG tunnel:\"\ + \n :put \"\"\ + \n :put \" Route a single host:\"\ + \n :put \" /ip/route/add dst-address=8.8.8.8/32 gateway=wg-awg2vds com\ + ment=awg2vds-tunnel\"\ + \n :put \"\"\ + \n :put \" Route a subnet:\"\ + \n :put \" /ip/route/add dst-address=100.0.0.0/8 gateway=wg-awg2vds co\ + mment=awg2vds-tunnel\"\ + \n :put \"\"\ + \n :put \" Remove a route:\"\ + \n :put \" /ip/route/remove [find where comment=awg2vds-tunnel dst-add\ + ress=8.8.8.8/32]\"\ + \n :put \"\"\ + \n :put \" Show all tunnel routes:\"\ + \n :put \" /ip/route/print where comment=awg2vds-tunnel\"\ + \n :put \"\"\ + \n :put \" Uninstall:\"\ + \n :put \" /system/script/run awg2vds-uninstall\"\ + \n :put \"=========================\"\ + \n}\ + \n\ + \n# 7. Verification\ + \n# /container/print\ + \n# /interface/wireguard/print\ + \n# /interface/wireguard/peers/print\ + \n" +/user group +add name=backup policy="telnet,ssh,ftp,read,write,policy,test,sniff,sensitive,\ + !local,!reboot,!winbox,!password,!web,!api,!romon,!rest-api" +add name=manager policy="local,ssh,ftp,read,write,policy,api,rest-api,!telnet,\ + !reboot,!test,!winbox,!password,!web,!sniff,!sensitive,!romon" +/certificate settings +set builtin-trust-store=fetch +/container config +set memory-high=200.0MiB +/disk settings +set auto-media-interface=Bridge-Lan +/ip smb +set domain=WORKGROUP enabled=no interfaces=lo +/interface bridge port +add bridge=Bridge-Lan interface=ether2 +add bridge=Bridge-Lan interface=ether3 +add bridge=Bridge-Lan interface=ether4 +add bridge=Bridge-Lan interface=ether5 +add bridge=Bridge-Lan interface=wlan1 +add bridge=Bridge-Lan interface=wlan2 +/interface bridge settings +set allow-fast-path=no use-ip-firewall=yes +/ip neighbor discovery-settings +set discover-interface-list=LAN +/ip settings +set accept-redirects=yes allow-fast-path=no +/ipv6 settings +set accept-router-advertisements-on=none allow-fast-path=no disable-ipv6=yes \ + disable-link-local-address=yes +/interface detect-internet +set detect-interface-list=static internet-interface-list=WAN \ + lan-interface-list=LAN wan-interface-list=WAN +/interface list member +add interface="ether1 - Unet" list=Internet +add interface=Bridge-Lan list=LAN +/interface wireless cap +# +set bridge=Bridge-Lan caps-man-addresses=10.30.30.10 \ + caps-man-certificate-common-names=CAPsMAN-ABE2F4E9EE17 certificate=\ + CAP-18FD746E5814 discovery-interfaces=Bridge-Lan enabled=yes interfaces=\ + wlan1,wlan2 lock-to-caps-man=yes +/ip address +add address=10.30.30.81/24 interface=Bridge-Lan network=10.30.30.0 +/ip cloud +set ddns-enabled=yes +/ip dhcp-client +add check-gateway=bfd default-route-tables=main:1 dhcp-options=\ + clientid,clientid_duid interface="ether1 - Unet" name=client1 \ + use-peer-dns=no use-peer-ntp=no +/ip dhcp-server config +set accounting=no +/ip dhcp-server lease +add address=10.30.30.101 client-id=1:48:8f:5a:8e:ee:a8 mac-address=\ + 48:8F:5A:8E:EE:A8 server=masterDHCP +add address=10.30.30.107 client-id=1:f0:de:f1:91:d:1e mac-address=\ + F0:DE:F1:91:0D:1E server=masterDHCP +add address=10.30.30.83 client-id=1:0:80:77:ec:43:86 mac-address=\ + 00:80:77:EC:43:86 server=masterDHCP +add address=10.30.30.50 client-id=1:4:7c:16:36:f5:37 mac-address=\ + 04:7C:16:36:F5:37 server=masterDHCP +add address=10.30.30.71 client-id=1:10:2d:41:2c:20:c2 mac-address=\ + 10:2D:41:2C:20:C2 server=masterDHCP +add address=10.30.30.61 client-id=1:10:8:c1:81:59:5f mac-address=\ + 10:08:C1:81:59:5F server=masterDHCP +add address=10.30.30.72 client-id=1:10:38:1f:d2:5f:13 mac-address=\ + 10:38:1F:D2:5F:13 server=masterDHCP +add address=10.30.30.99 client-id=1:10:b1:df:e9:d0:d5 mac-address=\ + 10:B1:DF:E9:D0:D5 server=masterDHCP +add address=10.30.30.111 client-id=1:fe:2:52:be:3f:16 mac-address=\ + FE:02:52:BE:3F:16 server=masterDHCP +add address=10.30.30.92 client-id=1:d4:6d:6d:fd:e5:49 mac-address=\ + D4:6D:6D:FD:E5:49 server=masterDHCP +add address=10.30.30.93 client-id=1:7e:8b:1e:cb:b8:cb mac-address=\ + CC:42:10:12:46:94 server=masterDHCP +add address=10.30.30.94 client-id=1:50:cc:f8:85:96:a mac-address=\ + 50:CC:F8:85:96:0A server=masterDHCP +add address=10.30.30.82 client-id=1:e4:18:6b:58:34:ab mac-address=\ + E4:18:6B:58:34:AB server=masterDHCP +add address=10.30.30.75 client-id=1:0:27:15:41:97:a9 mac-address=\ + 00:27:15:41:97:A9 server=masterDHCP +add address=10.30.30.77 dhcp-option=HostName dhcp-option-set=StartLife1 \ + mac-address=C4:82:E1:03:49:10 server=masterDHCP +add address=10.30.30.73 client-id=1:10:38:1f:82:81:f2 mac-address=\ + 10:38:1F:82:81:F2 server=masterDHCP +add address=10.30.30.96 client-id=iPhone mac-address=4A:91:ED:0E:1F:39 \ + server=masterDHCP +add address=10.30.30.74 client-id=MiTV dhcp-option=HostName dhcp-option-set=\ + MiTV mac-address=20:72:A9:D3:34:36 server=masterDHCP +/ip dhcp-server network +add address=10.30.30.0/24 caps-manager=10.30.30.10 dhcp-option=\ + domain-search-list dhcp-option-set=domain-search-set dns-server=\ + 10.30.30.81 domain=WORKGROUP gateway=10.30.30.81 netmask=24 ntp-server=\ + 10.30.30.81,10.30.30.10 wins-server=10.30.30.95,10.30.30.98 +/ip dns +set allow-remote-requests=yes servers=89.110.101.17,10.30.30.33,8.8.4.4 +/ip dns static +add address=10.30.30.81 comment=defconf name=router.lan type=A +add address=10.30.30.81 comment=defconf name=master type=A +add address=10.30.30.33 comment=amster name=amster.vados.ru type=A +add address=8.8.8.8 name=dns.google type=A +add address=8.8.4.4 name=dns.google type=A +add address=1.0.0.1 comment="CloudFlare-doh IPv4 2" name=\ + security.cloudflare-dns.com type=A +add address=1.1.1.1 comment="CloudFlare-doh IPv4 1" disabled=yes name=\ + security.cloudflare-dns.com type=A +add address=149.112.112.112 comment="Cuad9-dns IPv4 2" disabled=yes name=\ + dns.quad9.net type=A +add address=9.9.9.9 comment="Cuad9-dns IPv4 1" disabled=yes name=\ + dns.quad9.net type=A +add address=91.192.189.2 comment=Unet-DNS disabled=yes name=ns1.unet.ws type=\ + A +add address=91.192.189.2 comment=Unet-DNS disabled=yes name=ns1.unet.ws type=\ + A +/ip firewall address-list +add address=10.0.0.0/8 list=RFC1918 +add address=172.16.0.0/12 list=RFC1918 +add address=192.168.0.0/16 list=RFC1918 +add address=91.215.120.206 list=TRUSTED +add address=185.71.70.78 disabled=yes list=TRUSTED +add address=176.53.203.171 disabled=yes list=TRUSTED +add address=176.53.203.170 disabled=yes list=TRUSTED +add address=176.53.202.194 disabled=yes list=TRUSTED +add address=8.8.4.4 disabled=yes list=to_vpn +add address=10.30.30.98 comment=vados-len list=Local2Vpn +add address=89.110.101.17 list=VDS +add address=109.107.177.79 list=TRUSTED +add address=185.71.70.78 disabled=yes list=TRUSTED +add address=176.53.203.171 disabled=yes list=TRUSTED +add address=176.53.203.170 disabled=yes list=TRUSTED +add address=176.53.202.194 disabled=yes list=TRUSTED +add address=2ip.ru list=Test +add address=89.110.101.17 comment=VDSIna list=TRUSTED +add address=10.8.0.0/24 comment="WG VDSIna" list=TRUSTED +add address=ikus.pesc.ru comment=ikus.pesc.ru list=NoVdsina +add address=love.ru comment=love.ru list=NoVdsina +add address=gosuslugi.ru comment=gosuslugi.ru list=NoVdsina +add address=pochta.ru comment=pochta.ru list=NoVdsina +add address=vdsina.com comment=vdsina.com list=NoVdsina +add address=vdsina.ru comment=vdsina.ru list=NoVdsina +add address=youla.ru comment=youla.ru list=NoVdsina +add address=kupiprodai.ru comment=kupiprodai.ru list=NoVdsina +add address=myip.ru list=Test +add address=geoip.co comment=geoip.co list=NoVdsina +add address=x.com list=Twitter +add address=facebook.com list=facebook +add address=fbcd.net list=facebook +add address=comp-lenta.ru comment=comp-lenta.ru list=NoVdsina +add address=128.85.102.70 comment=update.microsoft.com list=\ + windowsupdateslist +add address=wu-b-net.trafficmanager.net. comment=\ + ctldl.windowsupdate.com.delivery.microsoft.com list=windowsupdateslist +add address=ctldl.windowsupdate.com.delivery.microsoft.com. comment=\ + ctldl.windowsupdate.com list=windowsupdateslist +add address=redir.update.msft.com.trafficmanager.net. comment=\ + update.microsoft.com list=windowsupdateslist +add address=geo.prod.do.dsp.trafficmanager.net. comment=\ + geo.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=13.74.139.29 comment=array605.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=kv801.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + kv801.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=e12437.d.akamaiedge.net. comment=\ + kv801.prod.do.dsp.mp.microsoft.com.edgekey.net list=windowsupdateslist +add address=displaycatalog-rp.md.mp.microsoft.com.akadns.net. comment=\ + displaycatalog.mp.microsoft.com list=windowsupdateslist +add address=rp-consumer-prod-displaycatalog-geomap.trafficmanager.net. \ + comment=displaycatalog-rp.md.mp.microsoft.com.akadns.net list=\ + windowsupdateslist +add address=sls.update.microsoft.com. comment=slscr.update.microsoft.com \ + list=windowsupdateslist +add address=glb.sls.prod.dcat.dsp.trafficmanager.net. comment=\ + sls.update.microsoft.com list=windowsupdateslist +add address=fe3.delivery.mp.microsoft.com. comment=\ + fe3cr.delivery.mp.microsoft.com list=windowsupdateslist +add address=glb.cws.prod.dcat.dsp.trafficmanager.net. comment=\ + fe3.delivery.mp.microsoft.com list=windowsupdateslist +add address=fe2cr.update.msft.com.trafficmanager.net. comment=\ + fe2cr.update.microsoft.com list=windowsupdateslist +add address=download.windowsupdate.com.delivery.microsoft.com. comment=\ + download.windowsupdate.com list=windowsupdateslist +add address=wu-f-net.trafficmanager.net. comment=\ + download.windowsupdate.com.delivery.microsoft.com list=windowsupdateslist +add address=tsfe.trafficmanager.net. comment=\ + tsfe.trafficshaping.dsp.mp.microsoft.com list=windowsupdateslist +add address=edge.ds-c7110-microsoft.global.dns.qwilted-cds.cqloud.com. \ + comment=9.au.download.windowsupdate.com list=windowsupdateslist +add address=52.158.227.125 comment=array812.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=au.download.windowsupdate.com.delivery.microsoft.com. comment=\ + au.download.windowsupdate.com list=windowsupdateslist +add address=a767.dspw65.akamai.net. comment=\ + download.windowsupdate.com.edgesuite.net list=windowsupdateslist +add address=52.151.58.88 comment=array810.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=consumer-licensing-aks2aks.md.mp.microsoft.com.akadns.net. \ + comment=licensing.mp.microsoft.com list=windowsupdateslist +add address=licensing-prod-frontdoor-geomap.trafficmanager.net. comment=\ + consumer-licensing-aks2aks.md.mp.microsoft.com.akadns.net list=\ + windowsupdateslist +add address=star.f.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedge.f.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=cdp-f-nlu-net.trafficmanager.net. comment=\ + star.f.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=star.b.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedge.b.tlu.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=cdp-f-tlu-net.trafficmanager.net. comment=\ + star.b.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=storeedgefd.xbetservices.akadns.net. comment=\ + storeedgefd.dsx.mp.microsoft.com list=windowsupdateslist +add address=\ + storeedgefd.dsx.mp.microsoft.com.edgekey.net.globalredir.akadns.net. \ + comment=storeedgefd.dsx.mp.microsoft.com.edgekey.net list=\ + windowsupdateslist +add address=e16646.dscg.akamaiedge.net. comment=\ + storeedgefd.dsx.mp.microsoft.com.edgekey.net.globalredir.akadns.net list=\ + windowsupdateslist +add address=40.69.76.189 comment=array621.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=bg.microsoft.map.fastly.net. comment=\ + 3.au.download.windowsupdate.com list=windowsupdateslist +add list=windowsupdateslist +add address=40.69.75.33 comment=array613.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=star.sf.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedgeextensions.sf.tlu.dl.delivery.mp.microsoft.com list=\ + windowsupdateslist +add address=cdp-f-ssl-tlu-net.trafficmanager.net. comment=\ + star.sf.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=a2033.dscd.akamai.net. comment=\ + star.sb.tlu.dl.delivery.mp.microsoft.com.edgesuite.net list=\ + windowsupdateslist +add address=13.74.138.242 comment=array602.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=dl.delivery.mp.microsoft.com.delivery.microsoft.com. comment=\ + dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=dcat-f-nlu-net.trafficmanager.net. comment=\ + dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=1d.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=1D.tlu.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=dcat-b-tlu-net.trafficmanager.net. comment=\ + 1d.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=a122.dscg3.akamai.net. comment=\ + tlu.dl.delivery.mp.microsoft.com.edgesuite.net list=windowsupdateslist +add address=geover.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + geover.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=e10370.d.akamaiedge.net. comment=\ + geover.prod.do.dsp.mp.microsoft.com.edgekey.net list=windowsupdateslist +add address=52.232.182.21 comment=array511.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.70.77.95 comment=array519.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=a1683.dscd.akamai.net. comment=\ + dl.delivery.mp.microsoft.com-c.edgesuite.net list=windowsupdateslist +add address=consumer-collections-aks2eap.md.mp.microsoft.com.akadns.net. \ + comment=collections.mp.microsoft.com list=windowsupdateslist +add address=a1847.dscd.akamai.net. comment=\ + wildcard.f.tlu.dl.delivery.mp.microsoft.com.edgesuite.net list=\ + windowsupdateslist +add address=13.74.142.6 comment=array607.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=au.download.windowsupdate.com.edgesuite.net. comment=\ + 2.au.download.windowsupdate.com list=windowsupdateslist +add address=a767.dscg3.akamai.net. comment=\ + au.download.windowsupdate.com.edgesuite.net list=windowsupdateslist +add address=52.156.123.84 comment=array818.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.69.78.254 comment=array610.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=4.au.download.windowsupdate.com.delivery.microsoft.com. comment=\ + 4.au.download.windowsupdate.com list=windowsupdateslist +add address=cl-glcb907925.gcdn.co. comment=\ + 4.au.download.windowsupdate.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=52.167.167.111 comment=array510.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=40.69.70.43 comment=array623.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=tsfe.trafficshaping.dsp.mp.microsoft.com.delivery.microsoft.com. \ + comment=tsfe.trafficshaping.dsp.mp.microsoft.com list=windowsupdateslist +add address=ts-frontend.trafficmanager.net. comment=\ + tsfe.trafficshaping.dsp.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=40.69.75.248 comment=array616.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.69.74.84 comment=array615.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=sds.trafficmanager.net. comment=software-download.microsoft.com \ + list=windowsupdateslist +add address=40.69.74.80 comment=array611.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.175.242.182 comment=array804.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=dlc-shim.trafficmanager.net. comment=download.microsoft.com list=\ + windowsupdateslist +add address=e12671.dscd.akamaiedge.net. comment=\ + download.microsoft.com.edgekey.net list=windowsupdateslist +add address=20.187.55.34 comment=array808.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.167.231 comment=array513.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=52.167.222.13 comment=array518.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=kv601.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + kv601.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=e12358.d.akamaiedge.net. comment=\ + kv601.prod.do.dsp.mp.microsoft.com.edgekey.net list=windowsupdateslist +add address=tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. comment=\ + tlu.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=dcat-f-tlu-net.trafficmanager.net. comment=\ + tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=a1856.dspw65.akamai.net. comment=\ + tlu.dl.delivery.mp.microsoft.com-c.edgesuite.net list=windowsupdateslist +add address=52.167.164.252 comment=array506.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=13.74.137.54 comment=array601.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=kv501.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + kv501.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=collections-prod-frontdoor-geomap.trafficmanager.net. comment=\ + consumer-collections-aks2eap.md.mp.microsoft.com.akadns.net list=\ + windowsupdateslist +add address=52.167.160.173 comment=array509.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=40.70.77.148 comment=array516.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.200.126 comment=array507.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=52.167.167.59 comment=array508.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.69.76.172 comment=array620.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=82.202.162.184 comment=comp-lenta.ru list=NoWG +add address=smtp.mail.me.com.akadns.net. comment=smtp.mail.me.com list=NoWG +add address=17.57.155.37 comment=smtp.mail.me.com.akadns.net list=NoWG +add address=smtp.mail.me.com comment=smtp.mail.me.com list=NoVdsina +add address=40.70.76.5 comment=array514.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=13.74.186.119 comment=array618.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.177.176.186 comment=array520.prod.do.dsp.mp.microsoft.com \ + list=windowsupdateslist +add address=40.70.76.27 comment=array515.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.160.43 comment=array503.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.110 comment=array817.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=13.74.142.8 comment=array614.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=13.74.138.254 comment=array603.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.167.96 comment=array501.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.69.76.215 comment=array622.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=13.74.143.200 comment=array606.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.111 comment=array818.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.112 comment=array819.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=13.74.137.53 comment=array608.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.98 comment=array805.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.96 comment=array803.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.104 comment=array811.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.101 comment=array808.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.99 comment=array806.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.17 comment=array802.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.97 comment=array804.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.103 comment=array810.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.16 comment=array801.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=40.70.77.177 comment=array517.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.164.84 comment=array512.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.105 comment=array812.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.107 comment=array814.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.232.161.82 comment=array502.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.108 comment=array815.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=52.167.161.91 comment=array505.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.102 comment=array809.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.109 comment=array816.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.106 comment=array813.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.117 comment=array622.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.107 comment=array612.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.108 comment=array613.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.105 comment=array610.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.113 comment=array618.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.116 comment=array621.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.98 comment=array603.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.114 comment=array619.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.111 comment=array616.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.97 comment=array602.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.106 comment=array611.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.110 comment=array615.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.119 comment=array624.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.135 comment=array514.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.97 comment=array503.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.99 comment=array604.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.61 comment=array504.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.131 comment=array510.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.132 comment=array511.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.96 comment=array601.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.104 comment=array609.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.138 comment=array517.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.60 comment=array501.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.139 comment=array518.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.118 comment=array623.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.113 comment=array820.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.103 comment=array608.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.154.7.100 comment=array807.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.129 comment=array508.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.134 comment=array513.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.62 comment=array505.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.137 comment=array516.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.101 comment=array606.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.96 comment=array502.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.130 comment=array509.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.112 comment=array617.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.100 comment=array605.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.115 comment=array620.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.136 comment=array515.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=purchase.md.mp.microsoft.com.akadns.net. comment=\ + purchase.mp.microsoft.com list=windowsupdateslist +add address=e110219.a.akamaiedge.net. comment=\ + purchase.mp.microsoft.com.edgekey.net list=windowsupdateslist +add address=72.153.5.140 comment=array519.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.141 list=windowsupdateslist +add address=72.153.5.63 comment=array506.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.128 comment=array507.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.102 comment=array607.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=storesdk.xbetservices.akadns.net. comment=\ + storesdk.dsx.mp.microsoft.com list=windowsupdateslist +add address=e16646.g.akamaiedge.net. comment=\ + storesdk.dsx.mp.microsoft.com.edgekey.net list=windowsupdateslist +add address=software-download.microsoft.com.delivery.microsoft.com. comment=\ + software-download.microsoft.com list=windowsupdateslist +add address=download.prss.microsoft.com.akamaized.net. comment=\ + software-download.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=72.145.35.109 comment=array614.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=72.153.5.133 comment=array512.prod.do.dsp.mp.microsoft.com list=\ + windowsupdateslist +add address=213.180.192.0/19 comment=YandexDisk list=NoVdsina +add address=87.250.250.50 comment=YandexDisk list=NoVdsina +add address=consumer-prod-bcfd-v7-afd.trafficmanager.net. comment=\ + displaycatalog.mp.microsoft.com list=windowsupdateslist +add address=purchase-europeeap.md.mp.microsoft.com.akadns.net. comment=\ + purchase.md.mp.microsoft.com.akadns.net list=windowsupdateslist +add address=ne-az-conspurchase-mp.trafficmanager.net. comment=\ + purchase-europeeap.md.mp.microsoft.com.akadns.net list=windowsupdateslist +add address=storeedgefd.dsx.mp.microsoft.com.edgekey.net. comment=\ + cdn.storeedgefd.dsx.mp.microsoft.com list=windowsupdateslist +add address=star.f.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedge.f.tlu.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=a1996.dscd.akamai.net. comment=\ + wildcard.f.dl.delivery.mp.microsoft.com.edgesuite.net list=\ + windowsupdateslist +add address=cp801.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + cp801.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=glb.tas02.sls-prod.dcat.dsp.mp.microsoft.com. comment=\ + tas02.sls.update.microsoft.com list=windowsupdateslist +add address=cp601.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + cp601.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=star.sb.tlu.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedgeextensions.sb.tlu.dl.delivery.mp.microsoft.com list=\ + windowsupdateslist +add address=star.sf.dl.delivery.mp.microsoft.com.delivery.microsoft.com. \ + comment=msedge.sf.dl.delivery.mp.microsoft.com list=windowsupdateslist +add address=cdp-f-ssl-nlu-net.trafficmanager.net. comment=\ + star.sf.dl.delivery.mp.microsoft.com.delivery.microsoft.com list=\ + windowsupdateslist +add address=tm-pifd-prod-gbl-weight.trafficmanager.net. comment=\ + paymentinstruments.mp.microsoft.com list=windowsupdateslist +add address=10.30.30.33 comment=NUC disabled=yes list=NoWG +add address=10.30.30.10 comment=MikroNUC disabled=yes list=NoWG +add address=89.110.101.17 comment=!!!VDSINA!!!! disabled=yes list=NoWG +add address=wg.vados.ru comment=VDSina-vpn list=Trusted-VPN +add address=80.85.244.9 list=TRUSTED +add address=disc801.prod.do.dsp.mp.microsoft.com.edgekey.net. comment=\ + disc801.prod.do.dsp.mp.microsoft.com list=windowsupdateslist +add address=185.71.70.78 disabled=yes list=TRUSTED +add address=176.53.203.171 disabled=yes list=TRUSTED +add address=176.53.203.170 disabled=yes list=TRUSTED +add address=176.53.202.194 disabled=yes list=TRUSTED +add address=vdsina.vados.ru comment="!!!VDSina Server!!!" list=NoVdsina +add address=dns.quad9.net comment=Quad9-dns disabled=yes list=Trusted-DNS +add address=dns.google comment=Google-dns list=Trusted-DNS +add address=security.cloudflare-dns.com comment=CloudFlare-dns list=\ + Trusted-DNS +add address=time.google.com comment=Google-time list=Trusted-NTP +add address=0.ru.pool.ntp.org comment=ru.pool.ntp.org disabled=yes list=\ + Trusted-NTP +add address=1.ru.pool.ntp.org disabled=yes list=Trusted-NTP +add address=2.ru.pool.ntp.org comment=2.ru.pool.ntp.org disabled=yes list=\ + Trusted-NTP +add address=3.ru.pool.ntp.org comment=3.ru.pool.ntp.org disabled=yes list=\ + Trusted-NTP +add address=cp.vdsina.com comment=VDSina-vpn list=Trusted-VPN +add address=vdsina.ru comment=VDSina-vpn list=Trusted-VPN +add address=ns.vados.ru comment=VDSina-vpn list=Trusted-VPN +add address=vdsina.com comment=VDSina-vpn list=Trusted-VPN +add address=cp.vdsina.ru comment=VDSina-vpn list=Trusted-VPN +add address=ns1.vdsina.ru comment=VDSina-vpn list=Trusted-VPN +add address=ghcr.io comment=GitHub list=Trusted-VPN +add address=github.com comment=GitHub list=Trusted-VPN +add address=149.154.164.13 comment=telegra.ph list=FuckRKN +add address=194.85.61.76 comment=grani.ru list=FuckRKN +add address=109.70.26.37 comment=grani.ru list=FuckRKN +add address=104.16.4.81 comment=xhamster.com list=FuckRKN +add address=104.16.3.81 comment=xhamster.com list=FuckRKN +add address=188.114.96.1 comment=lostfilm.tv list=FuckRKN +add address=188.114.97.1 comment=lostfilm.tv list=FuckRKN +add address=172.67.182.196 comment=rutracker.org list=FuckRKN +add address=104.21.32.39 comment=rutracker.org list=FuckRKN +add address=104.247.81.99 comment=lurkmore.to list=FuckRKN +add address=8.47.69.6 comment=dou.ua list=FuckRKN +add address=8.6.112.6 comment=dou.ua list=FuckRKN +add address=66.254.114.79 comment=youporn.com list=FuckRKN +add address=185.110.92.40 comment=pornolab.net list=FuckRKN +add address=185.110.92.41 comment=pornolab.net list=FuckRKN +add address=104.21.71.238 comment=crimerussia.com list=FuckRKN +add address=172.67.172.95 comment=crimerussia.com list=FuckRKN +add address=149.154.167.99 comment=telegram.org list=FuckRKN +add address=149.154.166.110 comment=api.telegram.org list=FuckRKN +add address=myip.ru comment="!!! Check IP (MYIP.RU) !!!" disabled=yes list=\ + NoVdsina +add address=ipinfo.io comment="!!! Check IP (IPINFO.IO) !!!" list=NoVdsina +/ip firewall filter +add action=add-src-to-address-list address-list="Honeypot Hacker" \ + address-list-timeout=12h chain=input comment="block honeypot DNS UDP" \ + connection-state=new dst-port=53 in-interface="ether1 - Unet" protocol=\ + udp src-address-list=!VDS +add action=add-src-to-address-list address-list="Honeypot Hacker" \ + address-list-timeout=4w2d chain=input comment="block honeypot DNS TCP" \ + connection-state=new dst-port=53 in-interface="ether1 - Unet" protocol=\ + tcp src-address-list=!VDS +add action=add-src-to-address-list address-list="Honeypot Hacker" \ + address-list-timeout=4w2d chain=input comment="block honeypot NTP" \ + connection-state=new dst-port=123 in-interface="ether1 - Unet" protocol=\ + udp +add action=add-src-to-address-list address-list="Honeypot Hacker" \ + address-list-timeout=4w2d chain=input comment="block honeypot asterisk" \ + connection-state=new dst-port=5060 in-interface="ether1 - Unet" protocol=\ + udp +add action=add-src-to-address-list address-list="Honeypot Hacker" \ + address-list-timeout=4w2d chain=input comment=\ + "block honeypot ssh rdp winbox" connection-state=new dst-port=22,8291 \ + in-interface-list=WAN protocol=tcp src-address-list=!TRUSTED +add action=accept chain=input comment=\ + "defconf: accept established,related,untracked" connection-state=\ + established,related,untracked +add action=drop chain=input comment="defconf: drop invalid" connection-state=\ + invalid +add action=accept chain=input comment="defconf: accept ICMP" protocol=icmp +add action=accept chain=input comment=\ + "defconf: accept to local loopback (for CAPsMAN)" disabled=yes \ + dst-address=127.0.0.1 in-interface=lo src-address=127.0.0.1 +add action=drop chain=input comment="defconf: drop all not coming from LAN" \ + in-interface-list=!LAN +add action=accept chain=forward comment="defconf: accept in ipsec policy" \ + disabled=yes ipsec-policy=in,ipsec +add action=accept chain=forward comment="defconf: accept out ipsec policy" \ + disabled=yes ipsec-policy=out,ipsec +add action=accept chain=forward comment=\ + "defconf: accept established,related, untracked" connection-state=\ + established,related,untracked +add action=drop chain=forward comment="defconf: drop invalid" \ + connection-state=invalid +add action=drop chain=forward comment=\ + "defconf: drop all from WAN not DSTNATed" connection-nat-state=!dstnat \ + in-interface-list=WAN +/ip firewall mangle +add action=accept chain=prerouting dst-address-list=RFC1918 \ + in-interface-list=!WAN +add action=mark-connection chain=prerouting comment="NO VPN" disabled=yes \ + dst-address-list=NoVdsina in-interface-list=!WAN new-connection-mark=\ + To-ISP +add action=mark-routing chain=prerouting comment=All2vpn connection-mark=\ + !To-ISP disabled=yes dst-address=!89.110.101.17 dst-address-list=\ + !NoVdsina new-routing-mark=To-VPN src-address=10.30.30.0/24 \ + src-address-list=!NoWG +add action=change-mss chain=forward comment="MSS on WG" connection-mark=\ + !To-ISP disabled=yes in-interface-list=!WAN new-mss=1380 protocol=tcp \ + tcp-flags=syn tcp-mss=1381-65535 +add action=mark-routing chain=prerouting connection-mark=to-vpn-conn \ + disabled=yes new-routing-mark=To-VPN routing-mark=To-VPN src-address=\ + 10.30.30.0/24 +add action=mark-connection chain=prerouting comment=\ + "Mark VPN connections to exclude from FastTrack" disabled=yes \ + in-interface=*B log-prefix=Mark-VPN-FT new-connection-mark=\ + VPN_No_FastTrack +add action=accept chain=prerouting comment="SSH To ME" disabled=yes \ + dst-address=10.30.30.81 dst-port=2222 in-interface-list=!WAN protocol=tcp \ + src-address=10.30.30.0/24 +add action=mark-routing chain=prerouting comment="VPN Network" disabled=yes \ + dst-address=10.8.0.0/24 log-prefix=VPN-Net new-routing-mark=To-VPN \ + src-address=10.30.30.0/24 +/ip firewall nat +add action=masquerade chain=srcnat comment="Default NAT" dst-address=\ + !10.30.30.0/24 ipsec-policy=out,none out-interface="ether1 - Unet" \ + routing-mark=!To-VPN src-address=10.30.30.0/24 +add action=masquerade chain=srcnat comment="NAT for VPN" disabled=yes \ + out-interface=lo routing-mark=To-VPN +add action=dst-nat chain=dstnat comment="dst-nat for acme" dst-port=80 \ + in-interface="ether1 - Unet" protocol=tcp to-addresses=10.30.30.33 \ + to-ports=80 +add action=dst-nat chain=dstnat comment="dst-nat for amster HTTPS" dst-port=\ + 443 in-interface="ether1 - Unet" protocol=tcp to-addresses=10.30.30.33 \ + to-ports=443 +add action=dst-nat chain=dstnat comment="dst-nat for amster ssh" disabled=yes \ + dst-port=22 protocol=tcp src-address-list=VDS to-addresses=10.30.30.33 \ + to-ports=22 +add action=dst-nat chain=dstnat comment="dst-nat for amster DNS (TCP)" \ + dst-port=53 in-interface="ether1 - Unet" protocol=tcp src-address-list=\ + VDS to-addresses=10.30.30.33 to-ports=53 +add action=dst-nat chain=dstnat comment="dst-nat for amster DNS (UDP)" \ + dst-port=53 in-interface="ether1 - Unet" protocol=udp src-address-list=\ + VDS to-addresses=10.30.30.33 to-ports=53 +/ip firewall service-port +set ftp disabled=yes +set tftp disabled=yes +set irc disabled=no +set sip disabled=yes +set pptp disabled=yes +set rtsp disabled=no +/ip hotspot user profile +set [ find default=yes ] address-pool=dhcp +/ip route +add check-gateway=ping disabled=yes distance=1 dst-address=10.10.10.0/24 \ + gateway=10.30.30.33 routing-table=main scope=30 target-scope=10 +add comment=awg2all-dns disabled=yes distance=1 dst-address=10.9.0.1/32 \ + gateway="" +add comment=awg2all-dns disabled=yes distance=1 dst-address=8.8.4.4/32 \ + gateway="" +/ip service +set ftp disabled=yes +set telnet disabled=yes +set www disabled=yes port=188 +set reverse-proxy disabled=yes +set ssh port=2222 +set api disabled=yes +set api-ssl disabled=yes +/ip service webserver +set acme-plain=no crl-plain=no graphs-plain=no graphs-secure=no index-plain=\ + no index-secure=no rest-plain=no rest-secure=no scep-plain=no \ + webfig-plain=no webfig-secure=no +/ip ssh +set forwarding-enabled=both publickey-authentication-options=verify-required \ + strong-crypto=yes +/ip upnp +set enabled=yes +/ip upnp interfaces +add interface="ether1 - Unet" type=external +/ipv6 firewall filter +add action=accept chain=input comment=\ + "defconf: accept established,related,untracked" connection-state=\ + established,related,untracked disabled=yes +add action=drop chain=input comment="defconf: drop invalid" connection-state=\ + invalid disabled=yes +add action=accept chain=input comment="defconf: accept ICMPv6" disabled=yes \ + protocol=icmpv6 +add action=accept chain=input comment="defconf: accept UDP traceroute" \ + disabled=yes dst-port=33434-33534 protocol=udp +add action=accept chain=input comment=\ + "defconf: accept DHCPv6-Client prefix delegation." disabled=yes dst-port=\ + 546 protocol=udp src-address=fe80::/10 +add action=accept chain=input comment="defconf: accept IKE" disabled=yes \ + dst-port=500,4500 protocol=udp +add action=accept chain=input comment="defconf: accept ipsec AH" disabled=yes \ + protocol=ipsec-ah +add action=accept chain=input comment="defconf: accept ipsec ESP" disabled=\ + yes protocol=ipsec-esp +add action=accept chain=input comment=\ + "defconf: accept all that matches ipsec policy" disabled=yes \ + ipsec-policy=in,ipsec +add action=drop chain=input comment=\ + "defconf: drop everything else not coming from LAN" disabled=yes \ + in-interface-list=!LAN +add action=fasttrack-connection chain=forward comment="defconf: fasttrack6" \ + connection-state=established,related +add action=accept chain=forward comment=\ + "defconf: accept established,related,untracked" connection-state=\ + established,related,untracked +add action=drop chain=forward comment="defconf: drop invalid" \ + connection-state=invalid +add action=drop chain=forward comment=\ + "defconf: drop packets with bad src ipv6" src-address-list=bad_ipv6 +add action=drop chain=forward comment=\ + "defconf: drop packets with bad dst ipv6" dst-address-list=bad_ipv6 +add action=drop chain=forward comment="defconf: rfc4890 drop hop-limit=1" \ + hop-limit=equal:1 protocol=icmpv6 +add action=accept chain=forward comment="defconf: accept ICMPv6" protocol=\ + icmpv6 +add action=accept chain=forward comment="defconf: accept HIP" protocol=139 +add action=accept chain=forward comment="defconf: accept IKE" dst-port=\ + 500,4500 protocol=udp +add action=accept chain=forward comment="defconf: accept ipsec AH" protocol=\ + ipsec-ah +add action=accept chain=forward comment="defconf: accept ipsec ESP" protocol=\ + ipsec-esp +add action=accept chain=forward comment=\ + "defconf: accept all that matches ipsec policy" ipsec-policy=in,ipsec +add action=drop chain=forward comment=\ + "defconf: drop everything else not coming from LAN" in-interface-list=\ + !LAN +/system clock +set time-zone-autodetect=no time-zone-name=Europe/Moscow +/system identity +set name=MikroMaster +/system ntp client +set enabled=yes +/system ntp server +set enabled=yes manycast=yes multicast=yes use-local-clock=yes +/system ntp client servers +add address=time.google.com +/system scheduler +add comment="Every Day Set Global Environment Variables" name=AM-SetGlobalEnv \ + on-event="/system/script { run AM-GlobalConfig; run AM-GlobalFunc; }" \ + policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \ + start-time=startup +add comment="Every Day Check For Update Scripts" interval=1d name=\ + AM-ScriptInstallUpdate on-event=\ + ":global ScriptInstallUpdate; \$ScriptInstallUpdate;" policy=\ + ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \ + start-time=startup +/tool e-mail +set certificate-verification=no from=MikroVados port=587 \ + server=smtp.mail.me.com tls=starttls user=vadossio@icloud.com +/tool netwatch +add comment="doh-fallback, doh-url=https://security.cloudflare-dns.com/dns-que\ + ry, doh-cert=DigiCert Global Root CA, notify, name=CloudFlare-doh IPv4 1" \ + disabled=yes host=1.1.1.1 type=simple +add comment="doh, doh-url=https://security.cloudflare-dns.com/dns-query, doh-c\ + ert=DigiCert Global Root CA, notify, name=CloudFlare-doh IPv4 2" \ + disabled=yes host=1.0.0.1 type=simple +add comment="doh-fallback, dns-fallback, doh-url=https://dns.google/dns-query,\ + \_doh-cert=DigiCert Global Root G2, notify, name=Google-doh IPv4 1" \ + disabled=yes host=8.8.8.8 type=simple +add comment="doh-fallback, dns-fallback, doh-url=https://dns.google/dns-query,\ + \_doh-cert=DigiCert Global Root G2, notify, name=Google-doh IPv4 2" \ + disabled=yes host=8.8.4.4 type=simple +add comment="doh-fallback, dns-fallback, doh-url=https://dns.quad9.net/dns-que\ + ry, doh-cert=DigiCert Global Root G3, notify, name=Cuad9-doh IPv4 1" \ + disabled=yes host=9.9.9.9 type=simple +add comment="doh-fallback, dns-fallback, doh-url=https://dns.quad9.net/dns-que\ + ry, doh-cert=DigiCert Global Root G3, notify, name=Cuad9-doh IPv4 2" \ + disabled=yes host=149.112.112.112 type=simple +add comment="dns, notify, name=ns1.unet.ws" disabled=yes host=91.192.189.2 \ + type=simple +/user aaa +set accounting=no diff --git a/MikroMaster/history/20260817/20260817110002-Diff-Config.rsc b/MikroMaster/history/20260817/20260817110002-Diff-Config.rsc new file mode 100644 index 0000000..e9e6f10 --- /dev/null +++ b/MikroMaster/history/20260817/20260817110002-Diff-Config.rsc @@ -0,0 +1,3690 @@ +1,2c1,2 +< # 2026-08-17 11:00:03 by RouterOS 7.23.3 +< # software id = 2961-C4ZZ +--- +> # 2026-07-15 07:40:20 by RouterOS 7.23.1 +> # software id = A8L5-07YF +4,5c4,5 +< # model = RBD52G-5HacD2HnD +< # serial number = HCX084RAVFA +--- +> # model = RB952Ui-5ac2nD +> # serial number = D3D50CEDCD38 +7,12c7,9 +< add name=Bridge-Lan +< /interface wireless +< # managed by CAPsMAN +< set [ find default-name=wlan1 ] ssid=MikroTik +< # managed by CAPsMAN +< set [ find default-name=wlan2 ] ssid=MikroTik +--- +> add admin-mac=48:8F:5A:8E:1A:BF auto-mac=no dhcpv6-agent-circuit-id=\ +> "\$(INTERFACE):\$(VID)" dhcpv6-agent-remote-id="\$(BRIDGEMAC)" name=\ +> Bridge-LAN port-cost-mode=short +14,15c11,30 +< set [ find default-name=ether1 ] mac-address=48:8F:5A:8E:1A:BC name=\ +< "ether1 - Unet" +--- +> set [ find default-name=ether1 ] advertise="10M-baseT-half,10M-baseT-full,100M\ +> -baseT-half,100M-baseT-full,1G-baseT-full,1G-baseX" comment=Unet-cable \ +> loop-protect=on name=Unet-ether1 rx-flow-control=auto tx-flow-control=\ +> auto +> set [ find default-name=ether2 ] comment=LAN-2 +> set [ find default-name=ether3 ] advertise="10M-baseT-half,10M-baseT-full,100M\ +> -baseT-half,100M-baseT-full,1G-baseT-full,1G-baseX" comment=LAN-3 +> set [ find default-name=ether4 ] comment=LAN-4 +> set [ find default-name=ether5 ] advertise="10M-baseT-half,10M-baseT-full,100M\ +> -baseT-half,100M-baseT-full,1G-baseT-full,1G-baseX" comment=LAN-5 \ +> loop-protect=on poe-out=off rx-flow-control=auto tx-flow-control=auto +> /interface wireless +> set [ find default-name=wlan1 ] country=belarus disabled=no mode=ap-bridge \ +> ssid=vados wireless-protocol=802.11 +> set [ find default-name=wlan2 ] country=belarus disabled=no mode=ap-bridge \ +> ssid=vados5g wireless-protocol=802.11 +> /interface wireguard +> add comment=WG listen-port=13231 mtu=1360 name=WG +> add comment="WG interface for Amnezia route" disabled=yes listen-port=33033 \ +> mtu=1360 name=wg-nuc +17,19c32,33 +< add comment=defconf name=WAN +< add comment=defconf name=LAN +< add exclude=LAN include=WAN name=Internet +--- +> add include=static name=LAN +> add name=Internet +21c35,38 +< set [ find default=yes ] supplicant-identity=MikroTik +--- +> set [ find default=yes ] authentication-types=wpa-psk,wpa2-psk mode=\ +> dynamic-keys supplicant-identity=MikroTik +> /iot wiliot servers +> set *1 address=mqtt.us-east-2.prod.wiliot.cloud name="Wiliot US East" +39a57 +> add name=iVados options=HostName +41,47c59,70 +< add dns-servers=1.1.1.1,1.0.0.1 name=blsp.at verify-doh-cert=no +< add comment=Kra dns-servers=1.0.0.1,1.1.1.1 name=slon2.to verify-doh-cert=no +< add dns-servers=1.1.1.1,1.0.0.1 name=slon3.at verify-doh-cert=no +< add dns-servers=1.0.0.1,1.1.1.1 name=slon3.cc verify-doh-cert=no +< add dns-servers=1.1.1.1,1.0.0.1 name=bs2web.at verify-doh-cert=no +< add dns-servers=1.1.1.1,1.0.0.1 name=bs2best.at verify-doh-cert=no +< add dns-servers=1.0.0.1,1.1.1.1 name=psrms.is verify-doh-cert=no +--- +> add disabled=yes dns-servers=1.0.0.1,1.1.1.1 name=blsp.at verify-doh-cert=no +> add comment=Kra disabled=yes dns-servers=1.0.0.1,1.1.1.1 name=slon2.to \ +> verify-doh-cert=no +> add disabled=yes dns-servers=1.1.1.1,1.0.0.1 name=slon3.at verify-doh-cert=no +> add disabled=yes dns-servers=1.0.0.1,1.1.1.1 name=slon3.cc verify-doh-cert=no +> add disabled=yes dns-servers=1.1.1.1,1.0.0.1 name=bs2web.at verify-doh-cert=\ +> no +> add disabled=yes dns-servers=1.1.1.1,1.0.0.1 name=bs2best.at verify-doh-cert=\ +> no +> add disabled=yes dns-servers=1.0.0.1,1.1.1.1 name=psrms.is verify-doh-cert=no +> /ip ipsec proposal +> set [ find default=yes ] disabled=yes +49c72 +< add name=dhcp ranges=10.30.30.150-10.30.30.200 +--- +> add name=dhcp ranges=10.30.30.83-10.30.30.254 +51,52c74,76 +< add address-pool=dhcp bootp-support=dynamic dhcp-option-set=domain-search-set \ +< interface=Bridge-Lan name=masterDHCP server-address=10.30.30.81 +--- +> add add-arp=yes address-pool=dhcp always-broadcast=yes bootp-support=none \ +> dhcp-option-set=domain-search-set interface=Bridge-LAN lease-time=10m \ +> name=masterDHCP server-address=10.30.30.81 +55a80,93 +> /ipv6 dhcp-client option +> add code=119 name=domain-search-list value="0x03'WORKGROUP'0x00" +> add code=12 name=HostName value="\$(HOSTNAME)" +> add code=61 name=DUID value=0x00030001488f5a8e1abc +> add code=61 name=clientid +> /ipv6 dhcp-server option +> add code=119 name=domain-search-list value="0x03'WORKGROUP'0x00" +> add code=12 name=HostName value="\$(HOSTNAME)" +> add code=61 name=CLIENT_DUID +> add code=61 name=CLIENT_MAC +> /ppp profile +> set *FFFFFFFE use-upnp=no +> /routing bgp template +> set default disabled=no output.network=bgp-networks +57c95,98 +< add disabled=yes fib name=To-VPN +--- +> add disabled=no fib name=To-VPN +> add disabled=yes name=r_to_vpn +> /system logging action +> add email-start-tls=yes email-to=vados@vados.ru name=email target=email +59,63c100,111 +< add dont-require-permissions=no name=fetchCustom owner=admin policy=\ +< ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ +< \n\ +< \n/tool/fetch mode=https url=(\$GlobalScriptsUrl . \".bak/mikro_bak_rsa@10\ +< .30.30.10.pub\") dst-path=\"/mikro_bak_rsa@10.30.30.10.pub\";\ +--- +> add dont-require-permissions=no name=fetchCustom owner=vados policy=\ +> ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source=":\ +> global GlobalScriptsUrl \"https://ros.vados.ru/\";\r\ +> \n\r\ +> \n#/tool/fetch mode=https url=(\$GlobalScriptsUrl . \".bak/mikro_bak_rsa@1\ +> 0.30.30.86.pub\") dst-path=\"/mikro_bak_rsa@10.30.30.86.pub\";\ +> \n\r\ +> \n#:local Script AM-setup\ +> \n;\r\ +> \n#/system/script/add name=\$Script owner=\$Script source=([ /tool/fetch c\ +> heck-certificate=yes-without-crl url=(\$GlobalScriptsUrl . \$Script . \".r\ +> sc\") output=user as-value ]->\"data\");\r\ +64a113 +> \n#/usb1/mikro_bak_rsa.pub\ +65a115 +> \n\r\ +66a117,121 +> \n\r\ +> \n#/tool/fetch mode=https url=(\$GlobalScriptsUrl . \".bak/mikro_bak_rsa@1\ +> 0.30.30.10.pub\") dst-path=\"/mikro_bak_rsa@10.30.30.10.pub\";\ +> \n\r\ +> \n#\r\ +70,71c125 +< \n\ +< \n\ +--- +> \n\r\ +73,74c127 +< .30.30.81.pub\") dst-path=\"/mikro_bak_rsa@10.30.30.81.pub\";\ +< \n\ +--- +> .30.30.81.pub\") dst-path=\"/mikro_bak_rsa@10.30.30.81.pub\";\r\ +77c130 +< \n\ +--- +> \n\r\ +80c133 +< sc\") output=user as-value ]->\"data\");\ +--- +> sc\") output=user as-value ]->\"data\");\r\ +83,84d135 +< \n\ +< \n\ +87,90c138,140 +< \n\ +< \n\ +< \n:global GlobalScriptsUrl \"https://ros.vados.ru/tmp/\";\ +< \n\ +--- +> \n\r\ +> \n\r\ +> \n#\ +91a142 +> \n\r\ +92a144,145 +> \n#:local FetchFile Binary.backup\ +> \n:local localDir \"\";\ +94,101c147,148 +< \n:local FetchFile Manager@id_rsa.pub\ +< \n:local localDir \"/\";\ +< \n\ +< \n\ +< \n\ +< \n\$MkDir \$localDir;\ +< \n\ +< \n\ +--- +> \n\r\ +> \n#\$MkDir \$localDir;\r\ +102a150 +> \n#\ +104c152 +< \$localDir . \$FetchFile);\ +--- +> \$localDir . \$FetchFile);\r\ +293c341,2276 +< add comment=GENERATOR dont-require-permissions=no name=awg2vds owner=vados \ +--- +> add comment="Global functions" dont-require-permissions=no name=AM-GlobalFunc \ +> owner=AM-GlobalFunc policy=\ +> ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ +> !rsc by Vados\r\ +> \n# RouterOS script: AM-GglobalFunc\r\ +> \n# Script comment: Global functions\r\ +> \n# Copyright (c) 2005-2026 Vados \r\ +> \n#\r\ +> \n#\r\ +> \n# requires RouterOS, version=7.19\r\ +> \n# requires device-mode, fetch, scheduler\r\ +> \n:local ExitOK false;\r\ +> \n:local ScriptName [ :jobname ];\r\ +> \n#:global checkRunJob \$SriptName;\r\ +> \n#:global fixCRLF;\r\ +> \n#:if (\$fixCRLF != false) do={\r\ +> \n#:foreach fixScript in=([ /system/script/find where name~\"*\" ]) do={/s\ +> ystem/script/set source=[ :tocrlf [ get \$fixScript source ] ] \$fixScript\ +> }\r\ +> \n#:if (\$fixCRLF != \"LF\") do={ /system/script/set source=[ :tocrlf [ g\ +> et \$fixScript source ] ] \$fixScript};};\r\ +> \n#}\r\ +> \n:global GlobalFuncReady false;\r\ +> \n\r\ +> \n# Git commit id & info, expected configuration version\r\ +> \n:global CommitId \"main/729/f42d43ae\";\r\ +> \n:global CommitTAG \"unknown\";\r\ +> \n:global CommitInfo \"Autocommit in repo: ros.vados.ru, generated by owne\ +> r: root, in 00:05:03 01.07.2026.\";\r\ +> \n\r\ +> \n# The variables are received right here.\r\ +> \n:global GlobalConfVersion 140;\r\ +> \n\r\ +> \n:global SumsDirAndFileName \"tmp/checksums.json\";\r\ +> \n\r\ +> \n:global Identity [/system/identity/get name];\r\ +> \n:global IdentityShort [:pick \$Identity 0 18];\r\ +> \n\r\ +> \n:global devBoardName [/system/resource/get board-name];\r\ +> \n:global devMode [/system/device-mode/get mode];\r\ +> \n:global devCurArch [/system/resource/get architecture-name];\r\ +> \n:global devCurVersion [/system/resource/get version];\r\ +> \n\r\ +> \n# Variables defined in AM-GlobalConfig.rsc\r\ +> \n:global TerminalColorOutput;\r\ +> \n:global CommentsInScripts;\r\ +> \n:global DetectIpAddrDefault;\r\ +> \n:global DetectIpAddrFallback;\r\ +> \n:global updateChannel;\r\ +> \n:global Domain;\r\ +> \n:global EmailGeneralTo;\r\ +> \n:global BackupAndUpdateMode;\r\ +> \n\r\ +> \n# Single functions, without nested functions.\r\ +> \n:global MiniDateTimeStamp;\r\ +> \n:global MicroDateTimeStamp;\r\ +> \n\r\ +> \n# Include globals \$PrintDebug and \$PrintDebugOverride\r\ +> \n:global LogPrint;\r\ +> \n\r\ +> \n# DeviceInfo and Updates\r\ +> \n:global IsCheckUpdates;\r\ +> \n:global WaitCheckUpdates;\r\ +> \n:global GetPubIp;\r\ +> \n\r\ +> \n:global GetArrDeviceInfo;\r\ +> \n:global WaitArrDeviceInfo;\r\ +> \n\r\ +> \n:global devModel;\r\ +> \n:global devRunningMode;\r\ +> \n\r\ +> \n:global devRbRevision;\r\ +> \n:global devRbSerialNumber;\r\ +> \n:global devRbVerAvail;\r\ +> \n\r\ +> \n:global runningChannelVersion;\r\ +> \n:global runningChannel;\r\ +> \n:global runningVersion;\r\ +> \n\r\ +> \n:global devBuildTime;\r\ +> \n:global ROsVerAvail;\r\ +> \n:global PkgUpdStatus;\r\ +> \n:global currentUpdateChannel;\r\ +> \n\r\ +> \n:global ScriptInstallUpdate;\r\ +> \n\r\ +> \n:global DeviceInfo;\r\ +> \n\r\ +> \n:global OldMode;\r\ +> \n\r\ +> \n:global ParseKeyValueStore;\r\ +> \n:global RandomDelay;\r\ +> \n:global GetRandomNumber;\r\ +> \n:global EscapeForRegEx;\r\ +> \n:global CharacterMultiply;\r\ +> \n:global CharacterReplace;\r\ +> \n:global CleanFilePath;\r\ +> \n:global CleanName;\r\ +> \n\r\ +> \n:global CommitBrief;\r\ +> \n\r\ +> \n:global EitherOr;\r\ +> \n:global FormatLine;\r\ +> \n:global GetRandom20CharAlNum;\r\ +> \n:global GetRandom20CharHex;\r\ +> \n:global GetRandomNumber;\r\ +> \n:global Grep;\r\ +> \n:global IfThenElse;\r\ +> \n:global MAX;\r\ +> \n:global MIN;\r\ +> \n:global HumanReadableNum;\r\ +> \n\r\ +> \n:global IsFullyConnected;\r\ +> \n:global IsDNSResolving;\r\ +> \n:global IsTimeSync;\r\ +> \n:global IsTimeSyncCached;\r\ +> \n:global IsTimeSyncResetNtp;\r\ +> \n\r\ +> \n:global MkDir;\r\ +> \n:global RmDir;\r\ +> \n:global RmFile;\r\ +> \n:global FileGet;\r\ +> \n:global Unix2Dos;\r\ +> \n:global UrlEncode;\r\ +> \n:global WaitForFile;\r\ +> \n:global ScriptLock;\r\ +> \n:global SendTelegram;\r\ +> \n:global NotificationFunctions;\r\ +> \n:global SendNotification;\r\ +> \n:global SendNotification2;\r\ +> \n:global SymbolForNotification;\r\ +> \n:global SymbolByUnicodeName;\r\ +> \n:global ValidateSyntax;\r\ +> \n:global CheckSumsVerify;\r\ +> \n:global GlobalConfChanges;\r\ +> \n:global GlobalConfMigration;\r\ +> \n:global VersionToNum;\r\ +> \n:global RequiredRouterOS;\r\ +> \n:global ExitError;\r\ +> \n:global ExitOnError;\r\ +> \n\r\ +> \n:global FetchHugeFiles;\r\ +> \n:global FetchUserAgentStr;\r\ +> \n:global FileExists;\r\ +> \n:global CertificateAvailable;\r\ +> \n:global CertificateDownload;\r\ +> \n:global CertificateNameByCN;\r\ +> \n:global CharacterMultiply;\r\ +> \n\r\ +> \n:global InspectVar;\r\ +> \n:global InspectVarRet;\r\ +> \n:global ParseCustom;\r\ +> \n\r\ +> \n:set IsCheckUpdates do={\r\ +> \n :local isInfo [:tobool \$1];\r\ +> \n :global updateChannel;\r\ +> \n :global PkgUpdStatus;\r\ +> \n :global currentUpdateChannel;\r\ +> \n :global ROsVerAvail;\r\ +> \n :global arrDeviceInfo;\r\ +> \n :log info (\$0 . \" \\\$isInfo = \" . \$isInfo); \r\ +> \n :local CurrentChannel [ /system/package/update/get channel ];\r\ +> \n :if ([ :len \$updateChannel ] > 0 && \$CurrentChannel != \$updateChann\ +> el) do={\r\ +> \n :retry command={/system/package/update set channel=\$updateChannel} \ +> \_delay=300ms max=5 on-error={};\r\ +> \n :log info (\$0 . \" Set updates channel to: \$updateChannel\");\r\ +> \n }\r\ +> \n :local Update [ /system/package/update/get ];\r\ +> \n :local Channel [ :tostr (\$Update->\"channel\") ];\r\ +> \n :set currentUpdateChannel \$Channel;\r\ +> \n :log info (\$0 . \" Update Channel: \" . \$Channel . \".\");\r\ +> \n :local StatusPkg \"undefined\";\r\ +> \n :log info (\$0 . \" Checking for updates...\");\r\ +> \n :retry command={:set \$StatusPkg ([/system/package/update/check-for-up\ +> dates without-paging as-value]->\"status\")} \\\r\ +> \n delay=300ms max=5 on-error={};\r\ +> \n :log info (\$0 . \" \\\$StatusPkg = \" . \$StatusPkg);\r\ +> \n :if (\$StatusPkg = \"New version is available\") do={ :set PkgUpdStatu\ +> s true; } else={ :set PkgUpdStatus false; }\r\ +> \n :set ROsVerAvail [ :tostr [ /system/package/update/get latest-version \ +> ] ];\r\ +> \n :log info (\$0 . \" \\\$PkgUpdStatus = \" . \$PkgUpdStatus);\r\ +> \n :if (\$isInfo != false || \$PkgUpdStatus = true) do={\r\ +> \n :log info (\$0 . \" \\\$PkgUpdStatus = \" . \$PkgUpdStatus);\r\ +> \n :if ([ :typeof \$arrDeviceInfo ] != \"array\") do={\r\ +> \n :set arrDeviceInfo [:toarray \$arrDeviceInfo];\r\ +> \n }\r\ +> \n :retry command={:set (\$arrDeviceInfo->\"devUpdates\") [ /system/pac\ +> kage/update/get ]} delay=500ms max=5 on-error={:log error (\"Error\")};\r\ +> \n :return true;\r\ +> \n } else={\r\ +> \n :return \$PkgUpdStatus;\r\ +> \n }\r\ +> \n}\r\ +> \n\r\ +> \n:set WaitCheckUpdates do={\r\ +> \n :global IsCheckUpdates;\r\ +> \n :global PkgUpdStatus;\r\ +> \n :global currentUpdateChannel;\r\ +> \n :global ROsVerAvail;\r\ +> \n :global arrDeviceInfo;\r\ +> \n :local Status \"\";\r\ +> \n :local Update;\r\ +> \n :local WaitCount 0;\r\ +> \n :if ([ \$IsCheckUpdates true ] = false) do={\r\ +> \n :return false;\r\ +> \n }\r\ +> \n :set Status [ :tostr [ /system/package/update/get status ] ];\r\ +> \n :while ((\$Status = \"\" || \$Status = \"finding out latest version...\ +> \") && \$WaitCount < 60) do={\r\ +> \n :delay 1s;\r\ +> \n :set WaitCount (\$WaitCount + 1);\r\ +> \n :set Status [ :tostr [ /system/package/update/get status ] ];\r\ +> \n }\r\ +> \n :set Update [ /system/package/update/get ];\r\ +> \n :set currentUpdateChannel [ :tostr (\$Update->\"channel\") ];\r\ +> \n :set ROsVerAvail [ :tostr (\$Update->\"latest-version\") ];\r\ +> \n :if ((\$Update->\"status\") = \"New version is available\") do={\r\ +> \n :set PkgUpdStatus true;\r\ +> \n } else={\r\ +> \n :set PkgUpdStatus false;\r\ +> \n }\r\ +> \n :if ([ :typeof \$arrDeviceInfo ] != \"array\") do={\r\ +> \n :set arrDeviceInfo [:toarray \$arrDeviceInfo];\r\ +> \n }\r\ +> \n :set (\$arrDeviceInfo->\"devUpdates\") \$Update;\r\ +> \n :if (\$Status = \"\" || \$Status = \"finding out latest version...\") \ +> do={\r\ +> \n :return false;\r\ +> \n }\r\ +> \n :return true;\r\ +> \n}\r\ +> \n\r\ +> \n:set WaitArrDeviceInfo do={\r\ +> \n :global GetArrDeviceInfo;\r\ +> \n :while ([ \$GetArrDeviceInfo ] = false) do={\r\ +> \n :delay 1s;\r\ +> \n }\r\ +> \n}\r\ +> \n\r\ +> \n:set GetArrDeviceInfo do={\r\ +> \n :global LogPrint;\r\ +> \n :global arrDeviceInfo;\r\ +> \n :global devBoardName;\r\ +> \n :global devModel;\r\ +> \n :global devRunning;\r\ +> \n :global devCurArch;\r\ +> \n :global devRbRevision;\r\ +> \n :global devRbSerialNumber;\r\ +> \n :global devBuildTime;\r\ +> \n :global runningChannelVersion;\r\ +> \n :global runningChannel;\r\ +> \n :global runningVersion;\r\ +> \n :global currentUpdateChannel;\r\ +> \n :global ROsVerAvail;\r\ +> \n\r\ +> \n :local DeviceInfo;\r\ +> \n :local Resource [/system/resource/get];\r\ +> \n :local Update [ /system/package/update/get ];\r\ +> \n :local VersionString [ :tostr (\$Resource->\"version\") ];\r\ +> \n :local ChannelStart [ :find \$VersionString \" (\" ];\r\ +> \n :local RouterBoard;\r\ +> \n :local IsRouterBoard false;\r\ +> \n :local RunningMode \"\";\r\ +> \n\r\ +> \n :set devCurArch [ :tostr (\$Resource->\"architecture-name\") ];\r\ +> \n :set devBuildTime [ :tostr (\$Resource->\"build-time\") ];\r\ +> \n :set runningChannelVersion \$VersionString;\r\ +> \n :set runningVersion \$VersionString;\r\ +> \n :set runningChannel \"\";\r\ +> \n\r\ +> \n :if ([ :typeof \$ChannelStart ] = \"num\" && \$ChannelStart >= 0) do=\ +> {\r\ +> \n :set runningVersion [ :pick \$VersionString 0 \$ChannelStart ];\r\ +> \n :local ChannelRest [ :pick \$VersionString (\$ChannelStart + 2) [ :\ +> len \$VersionString ] ];\r\ +> \n :local ChannelEnd [ :find \$ChannelRest \")\" ];\r\ +> \n :if ([ :typeof \$ChannelEnd ] = \"num\" && \$ChannelEnd >= 0) do={\ +> \r\ +> \n :set runningChannel [ :pick \$ChannelRest 0 \$ChannelEnd ];\r\ +> \n }\r\ +> \n }\r\ +> \n\r\ +> \n :if ([:pick \$devBoardName 0 3] != \"CHR\" or [:pick \$devBoardName 0\ +> \_3] != \"x86\") do={\r\ +> \n :do {\r\ +> \n :set RouterBoard [[ :parse \"/system/routerboard/get\" ]];\r\ +> \n# :set RouterBoard [ /system/routerboard/get ];\r\ +> \n :if ((\$RouterBoard->\"routerboard\") = true) do={\r\ +> \n :set IsRouterBoard true;\r\ +> \n }\r\ +> \n } on-error={}\r\ +> \n }\r\ +> \n\r\ +> \n :do {\r\ +> \n :set RunningMode [ /system/device-mode/get mode ];\r\ +> \n } on-error={\r\ +> \n :do {\r\ +> \n :set RunningMode [ /system/device-mode/get running ];\r\ +> \n } on-error={\r\ +> \n :set RunningMode \"\";\r\ +> \n }\r\ +> \n }\r\ +> \n :set devRunning \$RunningMode;\r\ +> \n\r\ +> \n :if (\$IsRouterBoard = true) do={\r\ +> \n :set devModel [ :tostr (\$RouterBoard->\"model\") ];\r\ +> \n :set devRbRevision [ :tostr (\$RouterBoard->\"revision\") ];\r\ +> \n :set devRbSerialNumber [ :tostr (\$RouterBoard->\"serial-number\") \ +> ];\r\ +> \n } else={\r\ +> \n :set devModel \$devBoardName;\r\ +> \n :set devRbRevision \"\";\r\ +> \n :set devRbSerialNumber \"\";\r\ +> \n }\r\ +> \n\r\ +> \n :set currentUpdateChannel [ :tostr (\$Update->\"channel\") ];\r\ +> \n :set ROsVerAvail [ :tostr (\$Update->\"latest-version\") ];\r\ +> \n\r\ +> \n :set (\$DeviceInfo->\"board-name\") \$devBoardName;\r\ +> \n :set (\$DeviceInfo->\"architecture-name\") \$devCurArch;\r\ +> \n :set (\$DeviceInfo->\"model\") \$devModel;\r\ +> \n :set (\$DeviceInfo->\"revision\") \$devRbRevision;\r\ +> \n :set (\$DeviceInfo->\"serial-number\") \$devRbSerialNumber;\r\ +> \n :set (\$DeviceInfo->\"running-mode\") \$devRunning;\r\ +> \n :set (\$DeviceInfo->\"build-time\") \$devBuildTime;\r\ +> \n :set (\$DeviceInfo->\"running-channel-version\") \$runningChannelVers\ +> ion;\r\ +> \n :set (\$DeviceInfo->\"running-version\") \$runningVersion;\r\ +> \n :set (\$DeviceInfo->\"running-channel\") \$runningChannel;\r\ +> \n :set (\$DeviceInfo->\"routerboard\") \$IsRouterBoard;\r\ +> \n :set (\$DeviceInfo->\"current-firmware\") [ :tostr (\$RouterBoard->\"\ +> current-firmware\") ];\r\ +> \n :set (\$DeviceInfo->\"upgrade-firmware\") [ :tostr (\$RouterBoard->\"\ +> upgrade-firmware\") ];\r\ +> \n :set (\$DeviceInfo->\"package-channel\") \$currentUpdateChannel;\r\ +> \n :set (\$DeviceInfo->\"installed-version\") [ :tostr (\$Update->\"inst\ +> alled-version\") ];\r\ +> \n :set (\$DeviceInfo->\"latest-version\") \$ROsVerAvail;\r\ +> \n :set (\$DeviceInfo->\"update-status\") [ :tostr (\$Update->\"status\"\ +> ) ];\r\ +> \n\r\ +> \n :set arrDeviceInfo \$DeviceInfo;\r\ +> \n :return \$DeviceInfo;\r\ +> \n}\r\ +> \n\r\ +> \n:set DeviceInfo do={\r\ +> \n :global GetArrDeviceInfo;\r\ +> \n :global GlobalConfVersion;\r\ +> \n :global Identity;\r\ +> \n :global IfThenElse;\r\ +> \n :global FormatLine;\r\ +> \n :global CommitBrief;\r\ +> \n\r\ +> \n :local License [/system/license/get];\r\ +> \n :local Snmp [ /snmp/get ];\r\ +> \n :local Info [ \$GetArrDeviceInfo ];\r\ +> \n\r\ +> \n :if ([ :typeof \$Info ] != \"array\") do={\r\ +> \n :return false;\r\ +> \n }\r\ +> \n\r\ +> \n :return ( \\\r\ +> \n [ \$FormatLine \"Hostname\" \$Identity ] . \"\\n\" . \\\r\ +> \n [ \$IfThenElse ([ :len (\$Snmp->\"location\") ] > 0) \\\r\ +> \n ([ \$FormatLine \"Location\" (\$Snmp->\"location\") ] . \"\\n\") ]\ +> \_. \\\r\ +> \n [ \$IfThenElse ([ :len (\$Snmp->\"contact\") ] > 0) \\\r\ +> \n ([ \$FormatLine \"Contact\" (\$Snmp->\"contact\") ] . \"\\n\") ] .\ +> \_\\\r\ +> \n \"Hardware:\\n\" . \\\r\ +> \n [ \$FormatLine \" Board\" (\$Info->\"board-name\") ] . \"\\n\" . \ +> \\\r\ +> \n [ \$FormatLine \" Arch\" (\$Info->\"architecture-name\") ] . \"\\\ +> n\" . \\\r\ +> \n [ \$FormatLine \" Model\" (\$Info->\"model\") ] . \\\r\ +> \n [ \$IfThenElse ([ :len (\$Info->\"revision\") ] > 0) \\\r\ +> \n (\" \" . (\$Info->\"revision\")) ] . \"\\n\" . \\\r\ +> \n [ \$IfThenElse ([ :len (\$Info->\"serial-number\") ] > 0) \\\r\ +> \n ([ \$FormatLine \" Serial\" (\$Info->\"serial-number\") ] . \"\ +> \\n\") ] . \\\r\ +> \n [ \$IfThenElse ([ :len (\$License->\"nlevel\") ] > 0) \\\r\ +> \n ([ \$FormatLine \" License\" (\"level \" . (\$License->\"nlevel\ +> \")) ] . \"\\n\") ] . \\\r\ +> \n \"RouterOS:\\n\" . \\\r\ +> \n [ \$IfThenElse ([ :len (\$License->\"level\") ] > 0) \\\r\ +> \n ([ \$FormatLine \" License\" (\"level \" . (\$License->\"level\ +> \")) ] . \"\\n\") ] . \\\r\ +> \n [ \$FormatLine \" Channel\" (\$Info->\"package-channel\") ] . \"\ +> \\n\" . \\\r\ +> \n [ \$FormatLine \" Installed\" (\$Info->\"installed-version\") ] .\ +> \_\"\\n\" . \\\r\ +> \n [ \$IfThenElse ([ :len (\$Info->\"running-channel\") ] > 0) \\\r\ +> \n ([ \$FormatLine \" Running\" ((\$Info->\"running-version\") . \ +> \" (\" . (\$Info->\"running-channel\") . \")\") ] . \"\\n\") \\\r\ +> \n ([ \$FormatLine \" Running\" (\$Info->\"running-version\") ] . \ +> \"\\n\") ] . \\\r\ +> \n [ \$IfThenElse ([ :len (\$Info->\"latest-version\") ] > 0 && \\\r\ +> \n (\$Info->\"installed-version\") != (\$Info->\"latest-version\"))\ +> \_\\\r\ +> \n ([ \$FormatLine \" Available\" (\$Info->\"latest-version\") ] .\ +> \_\"\\n\") ] . \\\r\ +> \n [ \$IfThenElse ((\$Info->\"routerboard\") = true && \\\r\ +> \n (\$Info->\"current-firmware\") != (\$Info->\"upgrade-firmware\")\ +> ) \\\r\ +> \n ([ \$FormatLine \" Firmware\" ((\$Info->\"current-firmware\") .\ +> \_\" -> \" . (\$Info->\"upgrade-firmware\")) ] . \"\\n\") ] . \\\r\ +> \n \"RouterOS-Scripts:\\n\" . \\\r\ +> \n [ \$FormatLine \" Commit\" [ \$CommitBrief ] ] . \"\\n\" . \\\r\ +> \n [ \$FormatLine \" Version\" \$GlobalConfVersion ]);\r\ +> \n}\r\ +> \n\r\ +> \n:if ([ :typeof \$NotificationFunctions ] != \"array\") do={:set Notifica\ +> tionFunctions ({})}\r\ +> \n\r\ +> \n:set GetRandom20CharAlNum do={\r\ +> \n :global EitherOr;\r\ +> \n :return [ :rndstr length=[ \$EitherOr [ :tonum \$1 ] 20 ] from=\"ABCDE\ +> FGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\" ];\r\ +> \n}\r\ +> \n\r\ +> \n:set GetRandom20CharHex do={:global EitherOr; :return [ :rndstr length=[\ +> \_\$EitherOr [ :tonum \$1 ] 20 ] from=\"0123456789abcdef\" ]; }\r\ +> \n:set GetRandomNumber do={:global EitherOr; :return [ :rndnum from=0 to=[\ +> \_\$EitherOr [ :tonum \$1 ] 4294967295 ] ]; }\r\ +> \n\r\ +> \n:global checkRunJob;\r\ +> \n:set checkRunJob do={\r\ +> \n :local Script [ :tostr \$1 ];\r\ +> \n :global ScriptLock; \r\ +> \n :if ([ \$ScriptLock \$Script ] = false) do={:return false}\r\ +> \n :foreach Job in=[ /system/script/job/find where script=\$Script ] do={\ +> :set Job [ /system/script/job/get \$Job ];\r\ +> \n :while ([ :typeof (\$Job->\"parent\") ] = \"id\") do={:set Job [ /sy\ +> stem/script/job/get [ find where .id=(\$Job->\"parent\") ] ]}\r\ +> \n :if ((\$Job->\"type\") = \"login\") do={:return true};}; :return fa\ +> lse; \r\ +> \n}\r\ +> \n\r\ +> \n:set InspectVar do={\r\ +> \n :global InspectVarRet;\r\ +> \n :put [ :tocrlf [ \$InspectVarRet \$1 ] ];\r\ +> \n}\r\ +> \n\r\ +> \n:set CommitBrief do={\r\ +> \n :global CommitId;\r\ +> \n :global CommitInfo;\r\ +> \n :if (\$CommitId = \"unknown\") do={\r\ +> \n :return \"unknown\";\r\ +> \n }\r\ +> \n :return (\$CommitInfo . \"/\" . [ :pick \$CommitId 0 8 ]);\r\ +> \n}\r\ +> \n\r\ +> \n:set InspectVarRet do={\r\ +> \n :local Input \$1;\r\ +> \n :local Level (0 + [ :tonum \$2 ]);\r\ +> \n :global CharacterReplace;\r\ +> \n :global IfThenElse;\r\ +> \n :global InspectVarRet;\r\ +> \n :local IndentReturn do={\r\ +> \n :local Prefix [ :tostr \$1 ];\r\ +> \n :local Value [ :tostr \$2 ];\r\ +> \n :local Level [ :tonum \$3 ];\r\ +> \n :global CharacterMultiply;\r\ +> \n :return ([ \$CharacterMultiply \" \" (\$Level * 2) ] . \"-\" . \$Pre\ +> fix . \"-> \" . \$Value);\r\ +> \n }\r\ +> \n :local TypeOf [ :typeof \$Input ];\r\ +> \n :local Len [ :len \$Input ];\r\ +> \n :local Return [ \$IndentReturn \"type\" \$TypeOf \$Level ];\r\ +> \n :if (\$TypeOf = \"array\") do={\r\ +> \n :foreach Key,Value in=\$Input do={\r\ +> \n :set \$Return (\$Return . \"\\n\" . \\\r\ +> \n [ \$IndentReturn \"key\" \$Key (\$Level + 1) ] . \"\\n\" . \\\r\ +> \n [ \$InspectVarRet \$Value (\$Level + 2) ]);\r\ +> \n }\r\ +> \n } else={\r\ +> \n :if (\$TypeOf = \"str\") do={\r\ +> \n :set \$Return (\$Return . \"\\n\" . \\\r\ +> \n [ \$IndentReturn \"len\" \$Len \$Level ]);\r\ +> \n :if ([ :typeof [ :find \$Input (\"\\r\") ] ] = \"num\") do={\r\ +> \n :set Input [ \$CharacterReplace \$Input (\"\\r\") \"\" ];\r\ +> \n }\r\ +> \n :if ([ :typeof [ :find \$Input (\"\\n\") ] ] = \"num\") do={\r\ +> \n :set Input [ \$CharacterReplace \$Input (\"\\n\") \" \" ];\r\ +> \n }\r\ +> \n }\r\ +> \n :if (\$TypeOf != \"nothing\") do={\r\ +> \n :set \$Return (\$Return . \"\\n\" . \\\r\ +> \n [ \$IndentReturn \"value\" [ \$IfThenElse ([ :len \$Input ] > 80)\ +> \_\\\r\ +> \n ([ :pick \$Input 0 77 ] . \"...\") \$Input ] \$Level ]);\r\ +> \n }\r\ +> \n }\r\ +> \n :return \$Return;\r\ +> \n}\r\ +> \n\r\ +> \n:set GetPubIp do={\r\ +> \n :global DetectIpAddrDefault;\r\ +> \n :global DetectIpAddrFallback;\r\ +> \n\r\ +> \n :local PubIpAddr false;\r\ +> \n :local Url \$DetectIpAddrDefault;\r\ +> \n :local JobName [ :jobname ];\r\ +> \n\r\ +> \n :do {\r\ +> \n :log debug (\$0 . \" Trying to detect public IP using default serv\ +> ice: \" . \$Url . \"...\");\r\ +> \n :retry command={:set PubIpAddr ([ /tool/fetch http-method=\"get\"\ +> \_check-certificate=yes-without-crl \$Url output=user as-value ]->\"data\"\ +> )} \\\r\ +> \n delay=50ms max=5 on-error={:log error (\$JobName . \" Failed to \ +> detect public IP using default service: \" . \$Url . \".\")}\r\ +> \n } on-error={\r\ +> \n :log error (\$0 . \" Failed to detect public IP using default serv\ +> ice: \" . \$Url . \".\");\r\ +> \n :set Url \$DetectIpAddrFallBack;\r\ +> \n :log debug (\$0 . \" Trying to detect public IP using fallback ser\ +> vice: \" . \$Url . \"...\");\r\ +> \n :retry command={:set PubIpAddr ([ /tool/fetch http-method=\"get\"\ +> \_check-certificate=yes-without-crl \$Url output=user as-value ]->\"data\"\ +> )} \\\r\ +> \n delay=200ms max=5 on-error={:log error (\$JobName . \" Failed to\ +> \_detect public IP using fallback service: \" . \$Url . \".\")}\r\ +> \n };\r\ +> \n :local IpLen ([ :len \$PubIpAddr ] -1);\r\ +> \n :if (\$PubIpAddr = false) do={:set PubIpAddr \"not-detected\"} else=\ +> {:set PubIpAddr [:pick \$PubIpAddr 0 \$IpLen]}\r\ +> \n :return \$PubIpAddr;\r\ +> \n}\r\ +> \n\r\ +> \n:set FormatLine do={\r\ +> \n :local Key [ :tostr \$1 ];\r\ +> \n :local Value [ :tostr \$2 ];\r\ +> \n :local Indent [ :tonum \$3 ];\r\ +> \n :local Spaces;\r\ +> \n :local Return \"\";\r\ +> \n :global CharacterMultiply;\r\ +> \n :global EitherOr;\r\ +> \n :set Indent [ \$EitherOr \$Indent 16 ];\r\ +> \n :local Spaces [ \$CharacterMultiply \" \" \$Indent ];\r\ +> \n :if ([ :len \$Key ] > 0) do={ :set Return (\$Key . \":\")}\r\ +> \n :if ([ :len \$Key ] > (\$Indent - 2)) do={:set Return (\$Return . \"\\\ +> n\" . [ :pick \$Spaces 0 \$Indent ] . \$Value);\r\ +> \n } else={:set Return (\$Return . [ :pick \$Spaces 0 (\$Indent - [ :len \ +> \$Return ]) ] . \$Value)}\r\ +> \n :return \$Return;\r\ +> \n}\r\ +> \n\r\ +> \n:set ParseCustom do={\r\ +> \n :local Str [ :tostr \$1 ];\r\ +> \n :local Start [:find [ \$Str ] [:tostr \$2]];\r\ +> \n :local End [ :tostr \$3 ];\r\ +> \n :local Num [ :tonum \$4 ];\r\ +> \n :local Return;\r\ +> \n :if ([:len \$Num] = 0) do={:set Num \"0\"}\r\ +> \n :local rest [:pick \$Str (\$Start+\$Num) [:len \$Str]]; \r\ +> \n :if ([:len \$End ] = 0) do={:set Return [:pick \$Str \$Num \$Start]} e\ +> lse={\r\ +> \n :set End [:find \$rest \$End];\r\ +> \n :set Return [:pick \$rest 0 \$End];\r\ +> \n }\r\ +> \n:return \$Return;\r\ +> \n}\r\ +> \n\r\ +> \n:set LogPrint do={\r\ +> \n :local Severity [ :tostr \$1 ];\r\ +> \n :local Name [ :tostr \$2 ];\r\ +> \n :local Message [ :tostr \$3 ];\r\ +> \n :global PrintDebug;\r\ +> \n :global PrintDebugOverride;\r\ +> \n :global EitherOr;\r\ +> \n :local Debug [ \$EitherOr (\$PrintDebugOverride->\$Name) \$PrintDebug \ +> ];\r\ +> \n :local PrintSeverity do={\r\ +> \n :global TerminalColorOutput;\r\ +> \n :if (\$TerminalColorOutput != true) do={:return \$1}\r\ +> \n :local Color { debug=96; info=97; warning=93; error=91 };\r\ +> \n :return (\"\\1B[\" . \$Color->\$1 . \"m\" . \$1 . \"\\1B[0m\");\r\ +> \n}\r\ +> \n :local Log ([ \$EitherOr \$Name \"\" ] . \": \" . \$Message);\ +> \r\ +> \n :if (\$Severity ~ (\"^(custom|debug|error|info)\\\$\")) do={\r\ +> \n :if (\$Severity = \"debug\") do={:log debug \$Log}\r\ +> \n :if (\$Severity = \"error\") do={:log error \$Log}\r\ +> \n :if (\$Severity = \"info\" ) do={:log info \$Log}\r\ +> \n } else={:log warning \$Log; :set Severity \"warning\"}\r\ +> \n :if (\$Severity != \"debug\" || \$Debug = true) do={:put ([ \$PrintSev\ +> erity \$Severity ] . \": \" . \$Message)}\r\ +> \n}\r\ +> \n\r\ +> \n:set CertificateAvailable do={\r\ +> \n :local CommonName [ :tostr \$1 ];\r\ +> \n :local UseFor [ :tostr \$2 ];\r\ +> \n\r\ +> \n :global CertificateDownload;\r\ +> \n :global ParseKeyValueStore;\r\ +> \n\r\ +> \n :if ([ :len \$UseFor ] = 0) do={\r\ +> \n :log warning (\$0 . \"The intended use is undefined!\");\r\ +> \n :set UseFor \"undefined\";\r\ +> \n }\r\ +> \n :if ([ /system/resource/get free-hdd-space ] < 8388608 && \\\r\ +> \n [ /certificate/settings/get crl-download ] = true && \\\r\ +> \n [ /certificate/settings/get crl-store ] = \"system\") do={\r\ +> \n :log warning (\$0 . \"This system has low free flash space but \" . \ +> \\\r\ +> \n \"is configured to download certificate CRLs to system!\");\r\ +> \n }\r\ +> \n :if ([ :len \$CommonName ] = 0) do={\r\ +> \n :log warning (\$0 . \"No CommonName given!\");\r\ +> \n :return false;\r\ +> \n }\r\ +> \n :local CertSettings [ /certificate/settings/get ];\r\ +> \n :if (((\$CertSettings->\"builtin-trust-anchors\") = \"trusted\" || \\\ +> \r\ +> \n (\$CertSettings->\"builtin-trust-store\") ~ \$UseFor || \\\r\ +> \n (\$CertSettings->\"builtin-trust-store\") = \"all\") && \\\r\ +> \n [ :len [ /certificate/builtin/find where common-name=\$CommonName\ +> \_] ] > 0) do={\r\ +> \n :return true;\r\ +> \n }\r\ +> \n :if ([ :len [ /certificate/find where common-name=\$CommonName ] ] = 0\ +> ) do={\r\ +> \n :log info (\$0 . \"Certificate with CommonName '\" . \$CommonName . \ +> \"' not available.\");\r\ +> \n :if ([ \$CertificateDownload \$CommonName ] = false) do={\r\ +> \n :return false;\r\ +> \n }\r\ +> \n }\r\ +> \n :if ([ :len [ /certificate/find where common-name=\$CommonName ] ] > 1\ +> ) do={\r\ +> \n :log info (\$0 . \"There are \" . \$CertCount . \" Certificates with\ +> \_CommonName '\" . \$CommonName . \"'. Should be ok.\");\r\ +> \n :return true;\r\ +> \n }\r\ +> \n :local CertVal [ /certificate/get [ find where common-name=\$CommonNam\ +> e ] ];\r\ +> \n :while ((\$CertVal->\"akid\") != \"\" && (\$CertVal->\"akid\") != (\$C\ +> ertVal->\"skid\")) do={\r\ +> \n :if ([ :len [ /certificate/find where skid=(\$CertVal->\"akid\") ] ]\ +> \_= 0) do={\r\ +> \n :local IssuerCN ([ \$ParseKeyValueStore (\$CertVal->\"issuer\") ]-\ +> >\"CN\");\r\ +> \n :log info (\$0 . \"Certificate chain for '\" . \$CommonName . \"' \ +> is incomplete, missing '\" . \$IssuerCN . \"'.\");\r\ +> \n :if ([ \$CertificateDownload \$IssuerCN ] = false) do={\r\ +> \n :return false;\r\ +> \n }\r\ +> \n }\r\ +> \n :set CertVal [ /certificate/get [ find where skid=(\$CertVal->\"akid\ +> \") ] ];\r\ +> \n }\r\ +> \n :return true;\r\ +> \n}\r\ +> \n\r\ +> \n:set CertificateDownload do={\r\ +> \n :local CommonName [ :tostr \$1 ];\r\ +> \n :global ScriptUpdatesBaseUrl;\r\ +> \n :global ScriptUpdatesUrlSuffix;\r\ +> \n :global CertificateNameByCN;\r\ +> \n :global CleanName;\r\ +> \n :global FetchUserAgentStr;\r\ +> \n :global RmFile;\r\ +> \n :global WaitForFile;\r\ +> \n\r\ +> \n :log info (\$0 . \"Downloading and importing certificate with \" . \\\ +> \r\ +> \n \"CommonName '\" . \$CommonName . \"'.\");\r\ +> \n :local FileName ([ \$CleanName \$CommonName ] . \".pem\");\r\ +> \n :do {\r\ +> \n /tool/fetch check-certificate=yes-without-crl mode=https http-header\ +> -field=({ [ \$FetchUserAgentStr \$0 ] }) \\\r\ +> \n (\$ScriptUpdatesBaseUrl . \"certs/\" . \$FileName . \$ScriptUpdate\ +> sUrlSuffix) \\\r\ +> \n dst-path=\$FileName as-value;\r\ +> \n \$WaitForFile \$FileName;\r\ +> \n } on-error={\r\ +> \n :log warning (\$0 . \" Failed downloading certificate with CommonNam\ +> e '\" . \$CommonName . \\\r\ +> \n \"' from repository! Trying fallback to mkcert.org...\");\r\ +> \n :do {\r\ +> \n :local CertSettings [ /certificate/settings/get ];\r\ +> \n :if ([ :len [ /certificate/find where common-name=\"ISRG Root X1\"\ +> \_] ] = 0 && \\\r\ +> \n !(((\$CertSettings->\"builtin-trust-anchors\") = \"trusted\" \ +> || \\\r\ +> \n (\$CertSettings->\"builtin-trust-store\") ~ \"fetch\" || \ +> \\\r\ +> \n (\$CertSettings->\"builtin-trust-store\") = \"all\") && \\\ +> \r\ +> \n [ :len [ /certificate/builtin/find where common-name=\"ISRG\ +> \_Root X1\" ] ] > 0)) do={\r\ +> \n :log error (\$0 . \" Required certificate is not available.\");\ +> \r\ +> \n :return false;\r\ +> \n }\r\ +> \n /tool/fetch check-certificate=yes-without-crl mode=https http-head\ +> er-field=({ [ \$FetchUserAgentStr \$0 ] }) \\\r\ +> \n url=\"https://mkcert.org/generate/\" http-data=[ :serialize to=jso\ +> n ({ \$CommonName }) ] \\\r\ +> \n dst-path=\$FileName as-value;\r\ +> \n \$WaitForFile \$FileName;\r\ +> \n :if ([ /file/get \$FileName size ] = 0) do={\r\ +> \n \$RmFile \$FileName;\r\ +> \n :error false;\r\ +> \n }\r\ +> \n } on-error={\r\ +> \n :log error (\$0 . \" Failed downloading certificate with CommonNam\ +> e '\" . \$CommonName . \"'!\");\r\ +> \n :return false;\r\ +> \n }\r\ +> \n }\r\ +> \n /certificate/import file-name=\$FileName passphrase=\"\" as-value;\r\ +> \n :delay 1s;\r\ +> \n \$RmFile \$FileName;\r\ +> \n :if ([ :len [ /certificate/find where common-name=\$CommonName ] ] = 0\ +> ) do={\r\ +> \n /certificate/remove [ find where name~(\"^\" . \$FileName . \"_[0-9]\ +> +\\\$\") ];\r\ +> \n :log warning (\$0 . \" Certificate with CommonName '\" . \$CommonNam\ +> e . \"' still unavailable!\");\r\ +> \n :return false;\r\ +> \n }\r\ +> \n :foreach Cert in=[ /certificate/find where name~(\"^\" . \$FileName . \ +> \"_[0-9]+\\\$\") ] do={\r\ +> \n \$CertificateNameByCN [ /certificate/get \$Cert common-name ];\r\ +> \n }\r\ +> \n :return true;\r\ +> \n}\r\ +> \n\r\ +> \n:set CertificateNameByCN do={\r\ +> \n :local Match [ :tostr \$1 ];\r\ +> \n :global CleanName;\r\ +> \n :local Cert ([ /certificate/find where (common-name=\$Match or fingerp\ +> rint=\$Match or name=\$Match) ]->0);\r\ +> \n :if ([ :len \$Cert ] = 0) do={\r\ +> \n :log warning (\$0 .\" No matching certificate found.\");\r\ +> \n :return false;\r\ +> \n }\r\ +> \n :local CommonName [ /certificate/get \$Cert common-name ];\r\ +> \n /certificate/set \$Cert name=[ \$CleanName \$CommonName ];\r\ +> \n :return true;\r\ +> \n}\r\ +> \n\r\ +> \n:set CharacterMultiply do={\r\ +> \n :local Str [ :tostr \$1 ];\r\ +> \n :local Num [ :tonum \$2 ];\r\ +> \n :if (\$Num = 0) do={:return \"\"}\r\ +> \n :local Return \"\";\r\ +> \n :for I from=1 to=\$Num do={:set Return (\$Return . \$Str)}\r\ +> \n :return \$Return;\r\ +> \n}\r\ +> \n\r\ +> \n:set FileExists do={\r\ +> \n :local FileName [ :tostr \$1 ];\r\ +> \n :local Type [ :tostr \$2 ];\r\ +> \n :global FileGet;\r\ +> \n :local FileVal [ \$FileGet \$FileName ];\r\ +> \n :if (\$FileVal = false) do={ :return false; }\r\ +> \n :if ([ :len (\$FileVal->\"size\") ] = 0) do={ :return false; }\r\ +> \n :if ([ :len \$Type ] = 0 || \$FileVal->\"type\" = \$Type) do={ :return\ +> \_true; }\r\ +> \n :return false;\r\ +> \n}\r\ +> \n\r\ +> \n:set Grep do={\r\ +> \n :local Input ([ :tostr \$1 ] . \"\\n\");\r\ +> \n :local Pattern [ :tostr \$2 ];\r\ +> \n :if ([ :typeof [ :find \$Input \$Pattern ] ] = \"nil\") do={:return []\ +> }\r\ +> \n :do {\r\ +> \n :local Line [ :pick \$Input 0 [ :find \$Input \"\\n\" ] ];\r\ +> \n :if ([ :typeof [ :find \$Line \$Pattern ] ] = \"num\") do={:return \ +> \$Line}\r\ +> \n :set Input [ :pick \$Input ([ :find \$Input \"\\n\" ] + 1) [ :len \$\ +> Input ] ];\r\ +> \n } while=([ :len \$Input ] > 0);\r\ +> \n :return [];\r\ +> \n}\r\ +> \n\r\ +> \n:set HumanReadableNum do={\r\ +> \n :local Input [ :tonum \$1 ];\r\ +> \n :local Base [ :tonum \$2 ];\r\ +> \n :global EitherOr;\r\ +> \n :global IfThenElse;\r\ +> \n :local Prefix \"kMGTPE\";\r\ +> \n :local Pow 1;\r\ +> \n :set Base [ \$EitherOr \$Base 1024 ];\r\ +> \n :local Bin [ \$IfThenElse (\$Base = 1024) \"i\" \"\" ];\r\ +> \n :if (\$Input < \$Base) do={:return \$Input}\r\ +> \n :for I from=0 to=[ :len \$Prefix ] do={\r\ +> \n :set Pow (\$Pow * \$Base);\r\ +> \n :if (\$Input / \$Base < \$Pow) do={\r\ +> \n :set Prefix [ :pick \$Prefix \$I ];\r\ +> \n :local Tmp1 (\$Input * 100 / \$Pow);\r\ +> \n :local Tmp2 (\$Tmp1 / 100);\r\ +> \n :if (\$Tmp2 >= 100) do={:return (\$Tmp2 . \$Prefix . \$Bin)}\r\ +> \n :return (\$Tmp2 . \".\" . \\\r\ +> \n [ :pick \$Tmp1 [ :len \$Tmp2 ] ([ :len \$Tmp1 ] - [ :len \$Tmp\ +> 2 ] + 1) ] . \\\r\ +> \n \$Prefix . \$Bin);\r\ +> \n }\r\ +> \n }\r\ +> \n}\r\ +> \n\r\ +> \n:set CleanFilePath do={\r\ +> \n :local Path [ :tostr \$1 ];\r\ +> \n :global CharacterReplace;\r\ +> \n :while (\$Path ~ \"//\") do={ :set \$Path [ \$CharacterReplace \$Path \ +> \"//\" \"/\" ]; }\r\ +> \n :if ([ :pick \$Path 0 ] = \"/\") do={ :set Path [ :pick \$Path 1 [ :le\ +> n \$Path ] ]; }\r\ +> \n :if ([ :pick \$Path ([ :len \$Path ] - 1) ] = \"/\") do={ :set Path [ \ +> :pick \$Path 0 ([ :len \$Path ] - 1) ]; }\r\ +> \n :return \$Path;\r\ +> \n}\r\ +> \n\r\ +> \n:set CleanName do={\r\ +> \n :local Input [ :tostr \$1 ];\r\ +> \n :local Return \"\";\r\ +> \n :for I from=0 to=([ :len \$Input ] - 1) do={\r\ +> \n :local Char [ :pick \$Input \$I ];\r\ +> \n :if ([ :typeof [ find \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr\ +> stuvwxyz0123456789\" \$Char ] ] = \"nil\") do={\r\ +> \n :do {:if ([ :len \$Return ] = 0) do={:error true};\r\ +> \n :if ([ :pick \$Return ([ :len \$Return ] - 1) ] = \"-\") do={:er\ +> ror true}; :set Char \"-\"} on-error={:set Char \"\"}; \r\ +> \n };\r\ +> \n :set Return (\$Return . \$Char)};\r\ +> \n :return \$Return;\r\ +> \n}\r\ +> \n\r\ +> \n:set RandomDelay do={\r\ +> \n :local Time [ :tonum \$1 ];\r\ +> \n :local Unit [ :tostr \$2 ];\r\ +> \n :global EitherOr;\r\ +> \n :global GetRandomNumber;\r\ +> \n :global MAX;\r\ +> \n :if (\$Time = 0) do={:return false}\r\ +> \n :delay ([ \$MAX 10 [ \$GetRandomNumber ([ :tonsec [ :totime (\$Time . \ +> [ \$EitherOr \$Unit \"s\" ]) ] ] / 1000000) ] ] . \"ms\");\r\ +> \n}\r\ +> \n\r\ +> \n:set EscapeForRegEx do={\r\ +> \n :local Input [ :tostr \$1 ];\r\ +> \n :if ([ :len \$Input ] = 0) do={:return \"\"}\r\ +> \n :local Return \"\";\r\ +> \n :local Chars (\"^.[]\\\$()|*+\?{}\\\\\");\r\ +> \n :for I from=0 to=([ :len \$Input ] - 1) do={\r\ +> \n :local Char [ :pick \$Input \$I ];\r\ +> \n :if ([ :find \$Chars \$Char ]) do={:set Char (\"\\\\\" . \$Char)}\r\ +> \n :set Return (\$Return . \$Char);\r\ +> \n }\r\ +> \n :return \$Return;\r\ +> \n}\r\ +> \n\r\ +> \n:set ExitError do={\r\ +> \n :local ExitOK [ :tostr \$1 ];\r\ +> \n :local Name [ :tostr \$2 ];\r\ +> \n :local Error [ :tostr \$3 ];\r\ +> \n :global IfThenElse;\r\ +> \n :if (\$ExitOK = \"false\") do={\r\ +> \n :log error (\$Name [ \$IfThenElse ([ :pick \$Name 0 1 ] = \"\\\$\") \ +> \\\r\ +> \n \"Function\" \"Script\" ] . \" '\" . \$Name . \"' exited with er\ +> ror\" . \\\r\ +> \n [ \$IfThenElse (!(\$Error ~ \"^(|true|false)\\\$\")) (\": \" . \ +> \$Error) \".\" ]);\r\ +> \n }\r\ +> \n}\r\ +> \n\r\ +> \n:set ExitOnError do={\r\ +> \n :local Name [ :tostr \$1 ];\r\ +> \n :local Error [ :tostr \$2 ];\r\ +> \n :global IfThenElse;\r\ +> \n :log error (\$Name . \" \" . [ \$IfThenElse ([ :pick \$Name 0 1 ] = \"\ +> \\\$\") \\\r\ +> \n \"Function\" \"Script\" ] . \" '\" . \$Name . \"' exited with erro\ +> r\" . \\\r\ +> \n [ \$IfThenElse (!(\$Error ~ \"^(|true|false)\\\$\")) (\": \" . \$E\ +> rror) \".\" ]);\r\ +> \n}\r\ +> \n\r\ +> \n:set MiniDateTimeStamp do={\r\ +> \n :local mikro [ :tobool \$1 ];\r\ +> \n /system/clock;\r\ +> \n :local vdate [get date];\r\ +> \n :local vtime [get time];\r\ +> \n :local vdoff [:toarray \"0,4,5,7,8,10\"];\r\ +> \n :local MM [:pick \$vdate (\$vdoff->2) (\$vdoff->3)];\r\ +> \n :local M [:tonum \$MM];\r\ +> \n :if (\$vdate ~ \".../../....\") do={\r\ +> \n :set vdoff [:toarray \"7,11,1,3,4,6\"];\r\ +> \n :set M ([:find \"xxanebarprayunulugepctovecANEBARPRAYUNULUGE\ +> PCTOVEC\" [:pick \$vdate (\$vdoff->2) (\$vdoff->3)] -1] / 2);\r\ +> \n :if (\$M>12) do={:set M (\$M - 12)}\r\ +> \n :set MM [:pick (100 + \$M) 1 3];\r\ +> \n }\r\ +> \n :local yyyy [:pick \$vdate (\$vdoff->0) (\$vdoff->1)];\r\ +> \n :local dd [:pick \$vdate (\$vdoff->4) (\$vdoff->5)];\r\ +> \n :local HH [:pick \$vtime 0 2];\r\ +> \n :local mm [:pick \$vtime 3 5];\r\ +> \n :local ss [:pick \$vtime 6 8];\r\ +> \n :local Return;\r\ +> \n :if (\$mikro = true) do={\r\ +> \n :set Return ([:pick \$yyyy 2 4] . [:pick \$dd 0 1] . [:pick \$HH 0\ +> \_1] . [:pick \$mm 3 4] . [:pick \$ss 6 7]);\r\ +> \n } else={\r\ +> \n :set Return ([\$yyyy] . [\$MM] . [\$dd] . [\$HH] . [\$mm] . [\$ss]);\ +> \r\ +> \n }\r\ +> \n :return \$Return;\r\ +> \n}\r\ +> \n\r\ +> \n:set WaitForFile do={\r\ +> \n :local FileName [ :tostr \$1 ];\r\ +> \n :local WaitTime [ :totime \$2 ];\r\ +> \n :global CleanFilePath;\r\ +> \n :global EitherOr;\r\ +> \n :global MAX;\r\ +> \n :set FileName [ \$CleanFilePath \$FileName ];\r\ +> \n :local Delay ([ \$MAX [ \$EitherOr \$WaitTime 2s ] 100ms ] / 9);\r\ +> \n :do {\r\ +> \n :retry {\r\ +> \n /file/get \$FileName;\r\ +> \n :return true;\r\ +> \n } delay=\$Delay max=10;\r\ +> \n } on-error={ }\r\ +> \n :while ([ :len [ /file/find where name=\$FileName ] ] > 0) do={\r\ +> \n :do {\r\ +> \n /file/get \$FileName;\r\ +> \n :return true;\r\ +> \n } on-error={ }\r\ +> \n :delay \$Delay;\r\ +> \n :set Delay (\$Delay * 3 / 2);\r\ +> \n }\r\ +> \n :return false;\r\ +> \n}\r\ +> \n\r\ +> \n:set FileGet do={\r\ +> \n :local FileName [ :tostr \$1 ];\r\ +> \n :global WaitForFile;\r\ +> \n :if ([ \$WaitForFile \$FileName 0s ] = false) do={\r\ +> \n :return false;\r\ +> \n }\r\ +> \n :local FileVal false;\r\ +> \n :do {\r\ +> \n :set FileVal [ /file/get \$FileName ];\r\ +> \n } on-error={ }\r\ +> \n :return \$FileVal;\r\ +> \n}\r\ +> \n\r\ +> \n:set RmDir do={\r\ +> \n :local DirName [ :tostr \$1 ];\r\ +> \n :global FileGet;\r\ +> \n :log debug (\$0 . \" Removing directory: \". \$DirName);\r\ +> \n :local DirVal [ \$FileGet \$DirName ];\r\ +> \n :if (\$DirVal = false) do={\r\ +> \n :log debug (\$0 . \" ... which does not exist.\");\r\ +> \n :return true;\r\ +> \n };\r\ +> \n :if (\$DirVal->\"type\" != \"directory\") do={\r\ +> \n :log error (\$0 . \" Directory '\" . \$DirName . \"' is not a direct\ +> ory.\");\r\ +> \n :return false;\r\ +> \n };\r\ +> \n :onerror Err {\r\ +> \n /file/remove \$DirName;\r\ +> \n } do={\r\ +> \n :log error (\$0 . \" Removing directory '\" . \$DirName . \"' failed\ +> : \" . \$Err);\r\ +> \n :return false;\r\ +> \n };\r\ +> \n :return true;\r\ +> \n}\r\ +> \n\r\ +> \n:set RmFile do={\r\ +> \n :local FileName [ :tostr \$1 ];\r\ +> \n :global FileGet;\r\ +> \n :log debug (\$0 . \" Removing file: \". \$FileName);\r\ +> \n :local FileVal [ \$FileGet \$FileName ];\r\ +> \n :if (\$FileVal = false) do={\r\ +> \n :log debug (\$0 . \" ... which does not exist.\");\r\ +> \n :return true;\r\ +> \n }\r\ +> \n :if (\$FileVal->\"type\" = \"directory\" || \$FileVal->\"type\" = \"di\ +> sk\") do={\r\ +> \n :log error (\$0 . \" File '\" . \$FileName . \"' is not a file.\");\ +> \r\ +> \n :return false;\r\ +> \n }\r\ +> \n :onerror Err {\r\ +> \n /file/remove \$FileName;\r\ +> \n } do={\r\ +> \n :log error (\$0 . \" Removing file '\" . \$FileName . \"' failed: \"\ +> \_. \$Err); :return false;\r\ +> \n }\r\ +> \n :return true;\r\ +> \n}\r\ +> \n\r\ +> \n:set MkDir do={\r\ +> \n :local Path [ :tostr \$1 ];\r\ +> \n :global CleanFilePath;\r\ +> \n :global FileGet;\r\ +> \n :global RmDir;\r\ +> \n :global WaitForFile;\r\ +> \n\r\ +> \n :local MkTmpfs do={\r\ +> \n :global WaitForFile;\r\ +> \n :local TmpFs [ /disk/find where slot=tmpfs type=tmpfs ];\r\ +> \n :if ([ :len \$TmpFs ] = 1) do={\r\ +> \n :if ([ /disk/get \$TmpFs disabled ] = true) do={\r\ +> \n :log info (\$0 . \" The tmpfs is disabled, enabling.\");\r\ +> \n /disk/enable \$TmpFs;\r\ +> \n }\r\ +> \n :return true;\r\ +> \n }\r\ +> \n :log info (\$0 . \" Creating disk of type tmpfs.\");\r\ +> \n \$RmDir \"tmpfs\";\r\ +> \n :onerror Err {\r\ +> \n /disk/add slot=tmpfs type=tmpfs tmpfs-max-size=([ /system/resource\ +> /get total-memory ] / 3);\r\ +> \n \$WaitForFile \"tmpfs\";\r\ +> \n } do={\r\ +> \n :log warning (\$0 . \" Creating disk of type tmpfs failed: \" . \$\ +> Err);\r\ +> \n :return false;\r\ +> \n }\r\ +> \n :return true;\r\ +> \n }\r\ +> \n :set Path [ \$CleanFilePath \$Path ];\r\ +> \n :if (\$Path = \"\") do={\r\ +> \n :return true;\r\ +> \n }\r\ +> \n :log debug (\$0 . \" Making directory: \" . \$Path);\r\ +> \n :local PathVal [ \$FileGet \$Path ];\r\ +> \n :if (\$PathVal->\"type\" = \"directory\") do={\r\ +> \n :log debug (\$0 . \" ... which already exists.\");\r\ +> \n :return true;\r\ +> \n }\r\ +> \n :if ([ :pick \$Path 0 5 ] = \"tmpfs\") do={\r\ +> \n :if ([ \$MkTmpfs ] = false) do={\r\ +> \n :return false;\r\ +> \n }\r\ +> \n }\r\ +> \n :onerror Err {\r\ +> \n /file/add type=\"directory\" name=\$Path;\r\ +> \n \$WaitForFile \$Path;\r\ +> \n } do={\r\ +> \n :log warning (\$0 . \" Making directory '\" . \$Path . \"' failed: \ +> \" . \$Err);\r\ +> \n :return false;\r\ +> \n }\r\ +> \n :return true;\r\ +> \n}\r\ +> \n\r\ +> \n:set MAX do={:if (\$1 > \$2) do={:return \$1}\r\ +> \n :return \$2;\r\ +> \n}\r\ +> \n:set MIN do={:if (\$1 < \$2) do={:return \$1}\r\ +> \n :return \$2;\r\ +> \n}\r\ +> \n\r\ +> \n:set CharacterMultiply do={\r\ +> \n :local Str [ :tostr \$1 ];\r\ +> \n :local Num [ :tonum \$2 ];\r\ +> \n :if (\$Num = 0) do={:return \"\"}\r\ +> \n :local Return \"\";\r\ +> \n :for I from=1 to=\$Num do={:set Return (\$Return . \$Str)}\r\ +> \n :return \$Return;\r\ +> \n}\r\ +> \n\r\ +> \n:set CharacterReplace do={\r\ +> \n :local String [ :tostr \$1 ];\r\ +> \n :local ReplaceFrom [ :tostr \$2 ];\r\ +> \n :local ReplaceWith [ :tostr \$3 ];\r\ +> \n :local Return \"\";\r\ +> \n :if (\$ReplaceFrom = \"\") do={:return \$String}\r\ +> \n :while ([ :typeof [ :find \$String \$ReplaceFrom ] ] != \"nil\") do={\ +> \r\ +> \n :local Pos [ :find \$String \$ReplaceFrom ];\r\ +> \n :set Return (\$Return . [ :pick \$String 0 \$Pos ] . \$ReplaceWith);\ +> \r\ +> \n :set String [ :pick \$String (\$Pos + [ :len \$ReplaceFrom ]) [ :len\ +> \_\$String ] ];\r\ +> \n }\r\ +> \n :return (\$Return . \$String);\r\ +> \n}\r\ +> \n\r\ +> \n:set IfThenElse do={\r\ +> \n :if ([ :tostr \$1 ] = \"true\" || [ :tobool \$1 ] = true) do={:return \ +> \$2};\r\ +> \n :return \$3;\r\ +> \n}\r\ +> \n\r\ +> \n:set EitherOr do={\r\ +> \n :global IfThenElse;\r\ +> \n :if ([ :typeof \$1 ] = \"num\") do={:return [ \$IfThenElse (\$1 != 0) \ +> \$1 \$2 ]}\r\ +> \n :if ([ :typeof \$1 ] = \"time\") do={:return [ \$IfThenElse (\$1 > 0s)\ +> \_\$1 \$2 ]}\r\ +> \n# this works for boolean values, literal ones with parentheses\r\ +> \n :return [ \$IfThenElse ([ :len [ :tostr \$1 ] ] > 0) \$1 \$2 ];\r\ +> \n}\r\ +> \n\r\ +> \n:set ParseKeyValueStore do={\r\ +> \n :local Source \$1;\r\ +> \n :if ([ :pick \$Source 0 1 ] = \"{\") do={\r\ +> \n :do {\r\ +> \n :return [ :deserialize from=json \$Source ];\r\ +> \n } on-error={ }\r\ +> \n } \r\ +> \n :if ([ :typeof \$Source ] != \"array\") do={:set Source [ :tostr \$1 ]\ +> }\r\ +> \n :local Result ({});\r\ +> \n :foreach KeyValue in=[ :toarray \$Source ] do={\r\ +> \n :if ([ :find \$KeyValue \"=\" ]) do={\r\ +> \n :local Key [ :pick \$KeyValue 0 [ :find \$KeyValue \"=\" ] ];\r\ +> \n :local Value [ :pick \$KeyValue ([ :find \$KeyValue \"=\" ] + 1) [\ +> \_:len \$KeyValue ] ];\r\ +> \n :if (\$Value=\"true\") do={:set Value true}\r\ +> \n :if (\$Value=\"false\") do={:set Value false}\r\ +> \n :set (\$Result->\$Key) \$Value;\r\ +> \n } else={:set (\$Result->\$KeyValue) true}\r\ +> \n }\r\ +> \n :return \$Result;\r\ +> \n}\r\ +> \n:set RequiredRouterOS do={\r\ +> \n :local Caller [ :tostr \$1 ];\r\ +> \n :local Required [ :tostr \$2 ];\r\ +> \n :local Warn [ :tostr \$3 ];\r\ +> \n :global IfThenElse;\r\ +> \n :global VersionToNum;\r\ +> \n :if (!(\$Required ~ \"^\\\\d+\\\\.\\\\d+((alpha|beta|rc|\\\\.)\\\\d+|)\ +> \\\$\")) do={\r\ +> \n :log error (\$0 . \" No valid RouterOS version: \" . \$Required);\r\ +> \n :return false;\r\ +> \n }\r\ +> \n :if ([ \$VersionToNum \$Required ] > [ \$VersionToNum [ /system/packag\ +> e/update/get installed-version ] ]) do={\r\ +> \n :if (\$Warn = \"true\") do={\r\ +> \n :log warning (\$0 . \" This \" . [ \$IfThenElse ([ :pick \$Caller \ +> 0 ] = (\"\\\$\")) \"function\" \"script\" ] . \\\r\ +> \n \" '\" . \$Caller . \"' (at least specific functionality) requir\ +> es RouterOS \" . \$Required . \". Please update!\");\r\ +> \n }\r\ +> \n :return false;\r\ +> \n }\r\ +> \n :return true;\r\ +> \n}\r\ +> \n\r\ +> \n:set ValidateSyntax do={\r\ +> \n :local Code [ :tostr \$1 ];\r\ +> \n :global LogPrint;\r\ +> \n :onerror Err {\r\ +> \n [ :parse (\":local Validate do={\\n\" . \$Code . \"\\n}\") ];\r\ +> \n } do={\r\ +> \n \$LogPrint debug \$0 (\"Valdation failed: \" . \$Err);\r\ +> \n :return false;\r\ +> \n }\r\ +> \n :return true;\r\ +> \n}\r\ +> \n\r\ +> \n:set VersionToNum do={\r\ +> \n :local Input [ :tostr \$1 ];\r\ +> \n :local Multi 0x1000000;\r\ +> \n :local Return 0;\r\ +> \n :global CharacterReplace;\r\ +> \n :set Input [ \$CharacterReplace \$Input \".\" \",\" ];\r\ +> \n :foreach I in={ \"zero\"; \"alpha\"; \"beta\"; \"rc\" } do={\r\ +> \n :set Input [ \$CharacterReplace \$Input \$I (\",\" . \$I . \",\") ];\ +> \r\ +> \n }\r\ +> \n :foreach Value in=([ :toarray \$Input ], 0) do={\r\ +> \n :local Num [ :tonum \$Value ];\r\ +> \n :if (\$Multi = 0x100) do={\r\ +> \n :if ([ :typeof \$Num ] = \"num\") do={\r\ +> \n :set Return (\$Return + 0xff00);\r\ +> \n :set Multi (\$Multi / 0x100);\r\ +> \n } else={\r\ +> \n :if (\$Value = \"zero\") do={ }\r\ +> \n :if (\$Value = \"alpha\") do={ :set Return (\$Return + 0x3f00); \ +> }\r\ +> \n :if (\$Value = \"beta\") do={ :set Return (\$Return + 0x5f00); }\ +> \r\ +> \n :if (\$Value = \"rc\") do={ :set Return (\$Return + 0x7f00); }\r\ +> \n }\r\ +> \n }\r\ +> \n :if ([ :typeof \$Num ] = \"num\") do={ :set Return (\$Return + (\$Va\ +> lue * \$Multi)); }\r\ +> \n :set Multi (\$Multi / 0x100);\r\ +> \n }\r\ +> \n :return \$Return;\r\ +> \n}\r\ +> \n\r\ +> \n:set ScriptLock do={\r\ +> \n :local Script [ :tostr \$1 ];\r\ +> \n :local WaitMax [ :totime \$2 ];\r\ +> \n :global GetRandom20CharAlNum;\r\ +> \n :global IfThenElse;\r\ +> \n :global ScriptLockOrder;\r\ +> \n :if ([ :typeof \$ScriptLockOrder ] = \"nothing\") do={\r\ +> \n :set ScriptLockOrder ({});\r\ +> \n }\r\ +> \n :if ([ :typeof (\$ScriptLockOrder->\$Script) ] = \"nothing\") do={\r\ +> \n :set (\$ScriptLockOrder->\$Script) ({});\r\ +> \n }\r\ +> \n :local JobCount do={\r\ +> \n :local Script [ :tostr \$1 ];\r\ +> \n :return [ :len [ /system/script/job/find where script=\$Script ] ];\ +> \r\ +> \n }\r\ +> \n :local TicketCount do={\r\ +> \n :local Script [ :tostr \$1 ];\r\ +> \n :global ScriptLockOrder;\r\ +> \n :local Count 0;\r\ +> \n :foreach Ticket in=(\$ScriptLockOrder->\$Script) do={\r\ +> \n :if ([ :typeof \$Ticket ] != \"nothing\") do={:set Count (\$Count \ +> + 1)}\r\ +> \n }\r\ +> \n :return \$Count;\r\ +> \n }\r\ +> \n :local IsFirstTicket do={\r\ +> \n :local Script [ :tostr \$1 ];\r\ +> \n :local Check [ :tostr \$2 ];\r\ +> \n :global ScriptLockOrder;\r\ +> \n :foreach Ticket in=(\$ScriptLockOrder->\$Script) do={\r\ +> \n :if (\$Ticket = \$Check) do={:return true}\r\ +> \n :if ([ :typeof \$Ticket ] != \"nothing\" && \$Ticket != \$Check) d\ +> o={:return false}\r\ +> \n }\r\ +> \n :return false;\r\ +> \n }\r\ +> \n :local AddTicket do={\r\ +> \n :local Script [ :tostr \$1 ];\r\ +> \n :local Add [ :tostr \$2 ];\r\ +> \n :global ScriptLockOrder;\r\ +> \n :while (true) do={\r\ +> \n :local Pos [ :len (\$ScriptLockOrder->\$Script) ];\r\ +> \n :set (\$ScriptLockOrder->\$Script->\$Pos) \$Add;\r\ +> \n :delay 10ms;\r\ +> \n :if ((\$ScriptLockOrder->\$Script->\$Pos) = \$Add) do={:return tru\ +> e}\r\ +> \n }\r\ +> \n }\r\ +> \n :local RemoveTicket do={\r\ +> \n :local Script [ :tostr \$1 ];\r\ +> \n :local Remove [ :tostr \$2 ];\r\ +> \n :global ScriptLockOrder;\r\ +> \n :foreach Id,Ticket in=(\$ScriptLockOrder->\$Script) do={\r\ +> \n :while ((\$ScriptLockOrder->\$Script->\$Id) = \$Remove) do={\r\ +> \n :set (\$ScriptLockOrder->\$Script->\$Id);\r\ +> \n :delay 10ms;\r\ +> \n }\r\ +> \n }\r\ +> \n }\r\ +> \n :local CleanupTickets do={\r\ +> \n :local Script [ :tostr \$1 ];\r\ +> \n :global ScriptLockOrder;\r\ +> \n :foreach Ticket in=(\$ScriptLockOrder->\$Script) do={\r\ +> \n :if ([ :typeof \$Ticket ] != \"nothing\") do={:return false}\r\ +> \n }\r\ +> \n :set (\$ScriptLockOrder->\$Script) ({});\r\ +> \n }\r\ +> \n :if ([ :typeof \$WaitMax ] = \"nil\" ) do={:set WaitMax 0s}\r\ +> \n :if ([ :len [ /system/script/find where name=\$Script ] ] = 0) do={\r\ +> \n :log error (\$0 . \" A script named '\" . \$Script . \"' does not ex\ +> ist!\");\r\ +> \n :error false;\r\ +> \n }\r\ +> \n :if ([ \$JobCount \$Script ] = 0) do={\r\ +> \n \$LogPrint error \$0 (\"No script '\" . \$Script . \"' is running!\"\ +> );\r\ +> \n :error false;\r\ +> \n }\r\ +> \n :if ([ \$TicketCount \$Script ] >= [ \$JobCount \$Script ]) do={\r\ +> \n :log error (\$0 . \" More tickets than running scripts '\" . \$Scrip\ +> t . \"', resetting!\");\r\ +> \n :set (\$ScriptLockOrder->\$Script) ({});\r\ +> \n /system/script/job/remove [ find where script=\$Script ];\r\ +> \n }\r\ +> \n :local MyTicket [ \$GetRandom20CharAlNum 6 ];\r\ +> \n \$AddTicket \$Script \$MyTicket;\r\ +> \n :local WaitInterval (\$WaitMax / 20);\r\ +> \n :local WaitTime \$WaitMax;\r\ +> \n :while (\$WaitTime > 0 && \\\r\ +> \n ([ \$IsFirstTicket \$Script \$MyTicket ] = false || \\\r\ +> \n [ \$TicketCount \$Script ] < [ \$JobCount \$Script ])) do={\r\ +> \n :set WaitTime (\$WaitTime - \$WaitInterval);\r\ +> \n :delay \$WaitInterval;\r\ +> \n }\r\ +> \n :if ([ \$IsFirstTicket \$Script \$MyTicket ] = true && \\\r\ +> \n [ \$TicketCount \$Script ] = [ \$JobCount \$Script ]) do={\r\ +> \n \$RemoveTicket \$Script \$MyTicket;\r\ +> \n \$CleanupTickets \$Script;\r\ +> \n :return true;\r\ +> \n }\r\ +> \n \$RemoveTicket \$Script \$MyTicket;\r\ +> \n \$LogPrint debug \$0 (\"Script '\" . \$Script . \"' started more than \ +> once\" . \\\r\ +> \n [ \$IfThenElse (\$WaitTime < \$WaitMax) \" and timed out waiting for\ +> \_lock\" \"\" ] . \"...\");\r\ +> \n :return false;\r\ +> \n}\r\ +> \n\r\ +> \n:set SendNotification do={ :onerror Err {\r\ +> \n :global SendNotification2;\r\ +> \n \$SendNotification2 ({ origin=\$0; subject=\$1; message=\$2; link=\$3;\ +> \_silent=\$4 });\r\ +> \n} do={:global ExitOnError; \$ExitOnError \$0 \$Err}\r\ +> \n}\r\ +> \n\r\ +> \n:set SendNotification2 do={\r\ +> \n :local Notification \$1;\r\ +> \n :global NotificationFunctions;\r\ +> \n :foreach FunctionName,Discard in=\$NotificationFunctions do={\r\ +> \n (\$NotificationFunctions->\$FunctionName) (\"\\\$NotificationFunctio\ +> ns->\\\"\" . \$FunctionName . \"\\\"\") \$Notification;\r\ +> \n }\r\ +> \n}\r\ +> \n\r\ +> \n:set SymbolByUnicodeName do={\r\ +> \n :local Name [ :tostr \$1 ];\r\ +> \n :global EitherOr;\r\ +> \n :global SymbolsExtra;\r\ +> \n :local Symbols ({\r\ +> \n \"abacus\"=\"\\F0\\9F\\A7\\AE\";\r\ +> \n \"alarm-clock\"=\"\\E2\\8F\\B0\";\r\ +> \n \"arrow-down\"=\"\\E2\\AC\\87\";\r\ +> \n \"arrow-up\"=\"\\E2\\AC\\86\";\r\ +> \n \"calendar\"=\"\\F0\\9F\\93\\85\";\r\ +> \n \"card-file-box\"=\"\\F0\\9F\\97\\83\";\r\ +> \n \"chart-decreasing\"=\"\\F0\\9F\\93\\89\";\r\ +> \n \"chart-increasing\"=\"\\F0\\9F\\93\\88\";\r\ +> \n \"cloud\"=\"\\E2\\98\\81\";\r\ +> \n \"cross-mark\"=\"\\E2\\9D\\8C\";\r\ +> \n \"earth\"=\"\\F0\\9F\\8C\\8D\";\r\ +> \n \"fire\"=\"\\F0\\9F\\94\\A5\";\r\ +> \n \"floppy-disk\"=\"\\F0\\9F\\92\\BE\";\r\ +> \n \"gear\"=\"\\E2\\9A\\99\";\r\ +> \n \"heart\"=\"\\E2\\99\\A5\";\r\ +> \n \"high-voltage-sign\"=\"\\E2\\9A\\A1\";\r\ +> \n \"incoming-envelope\"=\"\\F0\\9F\\93\\A8\";\r\ +> \n \"information\"=\"\\E2\\84\\B9\";\r\ +> \n \"large-orange-circle\"=\"\\F0\\9F\\9F\\A0\";\r\ +> \n \"large-red-circle\"=\"\\F0\\9F\\94\\B4\";\r\ +> \n \"link\"=\"\\F0\\9F\\94\\97\";\r\ +> \n \"lock-with-ink-pen\"=\"\\F0\\9F\\94\\8F\";\r\ +> \n \"memo\"=\"\\F0\\9F\\93\\9D\";\r\ +> \n \"mobile-phone\"=\"\\F0\\9F\\93\\B1\";\r\ +> \n \"pushpin\"=\"\\F0\\9F\\93\\8C\";\r\ +> \n \"scissors\"=\"\\E2\\9C\\82\";\r\ +> \n \"scroll\"=\"\\F0\\9F\\93\\9C\";\r\ +> \n \"smiley-partying-face\"=\"\\F0\\9F\\A5\\B3\";\r\ +> \n \"smiley-smiling-face\"=\"\\E2\\98\\BA\";\r\ +> \n \"smiley-winking-face-with-tongue\"=\"\\F0\\9F\\98\\9C\";\r\ +> \n \"sparkles\"=\"\\E2\\9C\\A8\";\r\ +> \n \"speech-balloon\"=\"\\F0\\9F\\92\\AC\";\r\ +> \n \"star\"=\"\\E2\\AD\\90\";\r\ +> \n \"warning-sign\"=\"\\E2\\9A\\A0\";\r\ +> \n \"white-heavy-check-mark\"=\"\\E2\\9C\\85\"\r\ +> \n }, \$SymbolsExtra);\r\ +> \n :local Magic [ :pick [ /system/clock/get date ] 4 10 ];\r\ +> \n :local Special {\r\ +> \n \"information-04-01\"=\"\\F0\\9F\\9A\\BB\";\r\ +> \n \"large-orange-circle-04-01\"=\"\\F0\\9F\\8D\\8A\";\r\ +> \n \"large-orange-circle-10-31\"=\"\\F0\\9F\\8E\\83\";\r\ +> \n \"large-red-circle-04-01\"=\"\\F0\\9F\\8D\\92\" };\r\ +> \n :if ([ :len (\$Symbols->\$Name) ] = 0) do={\r\ +> \n :log warning (\$0 . \"No symbol available for name '\" . \$Name . \"\ +> '!\");\r\ +> \n :return \"\";\r\ +> \n }\r\ +> \n :return ([ \$EitherOr (\$Special->(\$Name . \$Magic)) (\$Symbols->\$Na\ +> me) ] . \"\\EF\\B8\\8F\");\r\ +> \n}\r\ +> \n\r\ +> \n:set SymbolForNotification do={\r\ +> \n :global NotificationsWithSymbols;\r\ +> \n :global SymbolByUnicodeName;\r\ +> \n :global IfThenElse;\r\ +> \n :if (\$NotificationsWithSymbols != true) do={:return [ \$IfThenElse ([\ +> \_:len \$2 ] > 0) ([ :tostr \$2 ] . \" \") \"\" ]}\r\ +> \n :local Return \"\";\r\ +> \n :foreach Symbol in=[ :toarray \$1 ] do={:set Return (\$Return . [ \$Sy\ +> mbolByUnicodeName \$Symbol ])}\r\ +> \n :return (\$Return . \" \");\r\ +> \n}\r\ +> \n\r\ +> \n:set Unix2Dos do={:return [ :tocrlf [ :tostr \$1 ] ]}\r\ +> \n:set UrlEncode do={\r\ +> \n :local Input [ :tostr \$1 ];\r\ +> \n :if ([ :len \$Input ] = 0) do={:return \"\"}\r\ +> \n :local Return \"\";\r\ +> \n :local Chars (\"\\n\\r !\\\"#\\\$%&'()*+,:;<=>\?@[\\\\]^`{|}~\");\r\ +> \n :local Subs { \"%0A\"; \"%0D\"; \"%20\"; \"%21\"; \"%22\"; \"%23\"; \"\ +> %24\"; \"%25\"; \"%26\"; \"%27\";\r\ +> \n \"%28\"; \"%29\"; \"%2A\"; \"%2B\"; \"%2C\"; \"%3A\"; \"%3B\"; \ +> \"%3C\"; \"%3D\"; \"%3E\"; \"%3F\";\r\ +> \n \"%40\"; \"%5B\"; \"%5C\"; \"%5D\"; \"%5E\"; \"%60\"; \"%7B\"; \ +> \"%7C\"; \"%7D\"; \"%7E\" };\r\ +> \n :for I from=0 to=([ :len \$Input ] - 1) do={\r\ +> \n :local Char [ :pick \$Input \$I ];\r\ +> \n :local Replace [ :find \$Chars \$Char ];\r\ +> \n :if ([ :typeof \$Replace ] = \"num\") do={:set Char (\$Subs->\$Repla\ +> ce)}\r\ +> \n :set Return (\$Return . \$Char);\r\ +> \n }\r\ +> \n :return \$Return;\r\ +> \n}\r\ +> \n\r\ +> \n:set IsDNSResolving do={\r\ +> \n :do {:resolve \"api.telegram.org\"} on-error={:return false}\r\ +> \n :return true;\r\ +> \n}\r\ +> \n\r\ +> \n:set IsFullyConnected do={\r\ +> \n :global IsDNSResolving;\r\ +> \n :global IsTimeSync;\r\ +> \n :if ([ \$IsDNSResolving ] = false) do={:return false};\r\ +> \n :if ([ \$IsTimeSync ] = false) do={:return false};\r\ +> \n :return true;\r\ +> \n}\r\ +> \n\r\ +> \n:set IsTimeSync do={\r\ +> \n :global IsTimeSyncCached;\r\ +> \n :global IsTimeSyncResetNtp;\r\ +> \n :if (\$IsTimeSyncCached = true) do={:return true}\r\ +> \n :if ([ /system/ntp/client/get enabled ] = true) do={\r\ +> \n :if ([ /system/ntp/client/get status ] = \"synchronized\") do={\r\ +> \n :set IsTimeSyncCached true;\r\ +> \n :return true;\r\ +> \n }\r\ +> \n :local Uptime [ /system/resource/get uptime ];\r\ +> \n :if ([ :typeof \$IsTimeSyncResetNtp ] = \"nothing\") do={\r\ +> \n :set IsTimeSyncResetNtp \$Uptime;\r\ +> \n }\r\ +> \n :if (\$Uptime - \$IsTimeSyncResetNtp < 3m) do={:return false}\r\ +> \n :log warning \"\$0 The ntp client is configured, but did not sync.\"\ +> ;\r\ +> \n :set IsTimeSyncResetNtp \$Uptime;\r\ +> \n /system/ntp/client/set enabled=no;\r\ +> \n :delay 20ms;\r\ +> \n /system/ntp/client/set enabled=yes;\r\ +> \n :return false;\r\ +> \n }\r\ +> \n :if ([ /system/license/get ]->\"level\" = \"free\" || \\\r\ +> \n [ /system/resource/get ]->\"board-name\" = \"x86\") do={\r\ +> \n :log debug \"\$0 No ntp client configured, relying on RTC for CHR fr\ +> ee license and x86.\";\r\ +> \n :return true;\r\ +> \n }\r\ +> \n :if ([ /ip/cloud/get update-time ] = true) do={\r\ +> \n :if ([ :typeof [ /ip/cloud/get public-address ] ] = \"ip\") do={\r\ +> \n :set IsTimeSyncCached true;\r\ +> \n :return true;\r\ +> \n }\r\ +> \n :return false;\r\ +> \n }\r\ +> \n :log debug \"\$0 No time source configured! Returning gracefully...\";\ +> \r\ +> \n :return true;\r\ +> \n}\r\ +> \n\r\ +> \n:set FetchHugeFiles do={\r\ +> \n :local ScriptName [ :tostr \$1 ];\r\ +> \n :local Url [ :tostr \$2 ];\r\ +> \n :local CheckCert [ :tostr \$3 ];\r\ +> \n\r\ +> \n :global CleanName;\r\ +> \n :global FetchUserAgentStr;\r\ +> \n :global GetRandom20CharAlNum;\r\ +> \n :global IfThenElse;\r\ +> \n :global LogPrint;\r\ +> \n :global MkDir;\r\ +> \n :global RmDir;\r\ +> \n :global RmFile;\r\ +> \n :global WaitForFile;\r\ +> \n\r\ +> \n :set CheckCert [ \$IfThenElse (\$CheckCert = \"false\") \"no\" \"yes-w\ +> ithout-crl\" ];\r\ +> \n\r\ +> \n :local DirName (\"tmpfs/\" . [ \$CleanName \$ScriptName ]);\r\ +> \n :if ([ \$MkDir \$DirName ] = false) do={\r\ +> \n \$LogPrint error \$0 (\"Failed creating directory!\");\r\ +> \n :return false;\r\ +> \n }\r\ +> \n\r\ +> \n :local FileName (\$DirName . \"/\" . [ \$CleanName \$0 ] . \"-\" . [ \ +> \$GetRandom20CharAlNum ]);\r\ +> \n :onerror Err {\r\ +> \n /tool/fetch check-certificate=\$CheckCert \$Url dst-path=\$FileName \ +> \\\r\ +> \n http-header-field=({ [ \$FetchUserAgentStr \$ScriptName ] }) as-va\ +> lue;\r\ +> \n } do={\r\ +> \n :if ([ \$WaitForFile \$FileName 500ms ] = true) do={\r\ +> \n \$RmFile \$FileName;\r\ +> \n }\r\ +> \n \$LogPrint debug \$0 (\"Failed downloading from \" . \$Url . \" - \"\ +> \_. \$Err);\r\ +> \n \$RmDir \$DirName;\r\ +> \n :return false;\r\ +> \n }\r\ +> \n\r\ +> \n :if ([ \$WaitForFile \$FileName 5s ] = false) do={\r\ +> \n \$LogPrint debug \$0 (\"The file downloaded from \" . \$Url . \" did\ +> \_not show up.\");\r\ +> \n :return false;\r\ +> \n }\r\ +> \n\r\ +> \n :local FileSize [ /file/get \$FileName size ];\r\ +> \n :local Return \"\";\r\ +> \n :local VarSize 0;\r\ +> \n :while (\$VarSize != \$FileSize) do={\r\ +> \n :set Return (\$Return . ([ /file/read offset=\$VarSize chunk-size=32\ +> 768 file=\$FileName as-value ]->\"data\"));\r\ +> \n :set FileSize [ /file/get \$FileName size ];\r\ +> \n :set VarSize [ :len \$Return ];\r\ +> \n :if (\$VarSize > \$FileSize) do={\r\ +> \n :delay 100ms;\r\ +> \n }\r\ +> \n }\r\ +> \n \$RmDir \$DirName;\r\ +> \n :return \$Return;\r\ +> \n}\r\ +> \n\r\ +> \n:set FetchUserAgentStr do={\r\ +> \n :local Caller [ :tostr \$1 ];\r\ +> \n :global GlobalScriptsUrl;\r\ +> \n :global CommitBrief;\r\ +> \n :global IfThenElse;\r\ +> \n :local Resource [ /system/resource/get ];\r\ +> \n :return (\"User-Agent: Mikrotik/\" . \$Resource->\"version\" . \" \" .\ +> \_\$Resource->\"architecture-name\" . \\\r\ +> \n \" \" . \$Caller . \"/Fetch (\" . \$GlobalScriptsUrl . \"; \" . [ \$\ +> CommitBrief ] . \")\");\r\ +> \n}\r\ +> \n\r\ +> \n:set ScriptInstallUpdate do={ :onerror Err {\r\ +> \n :local Scripts [ :toarray \$1 ];\r\ +> \n :local NewComment [ :tostr \$2 ];\r\ +> \n :global InitSetup;\r\ +> \n\r\ +> \n :global CommitId;\r\ +> \n :global ScriptUpdatesCRLF;\r\ +> \n :global GlobalConfVersion;\r\ +> \n :global Identity;\r\ +> \n :global CertificateAvailable;\r\ +> \n :global CheckSumsVerify;\r\ +> \n :global GlobalScriptsUrl;\r\ +> \n :global SumsDirAndFileName;\r\ +> \n :global GlobalScriptsUrlSuffix;\r\ +> \n :global EitherOr;\r\ +> \n :global FetchUserAgentStr;\r\ +> \n :global Grep;\r\ +> \n :global IfThenElse;\r\ +> \n :global LogPrint;\r\ +> \n :global ParseKeyValueStore;\r\ +> \n :global RequiredRouterOS;\r\ +> \n :global SendNotification2;\r\ +> \n :global SymbolForNotification;\r\ +> \n :global ValidateSyntax;\r\ +> \n :global CommentsInScripts;\r\ +> \n\r\ +> \n :if ([ \$CertificateAvailable \"Root YE\" \"fetch\" ] = false) do={\r\ +> \n \$LogPrint warning \$0 (\"Downloading certificate failed, trying wit\ +> hout.\");\r\ +> \n }\r\ +> \n\r\ +> \n :foreach Script in=\$Scripts do={\r\ +> \n :if ([ :len [ /system/script/find where name=\$Script ] ] = 0) do={\ +> \r\ +> \n \$LogPrint info \$0 (\"Adding new script: \" . \$Script);\r\ +> \n /system/script/add name=\$Script owner=\$Script source=\"#!rsc by \ +> Vados\\n\" comment=\$NewComment;\r\ +> \n }\r\ +> \n }\r\ +> \n\r\ +> \n :local CommitIdBefore \$CommitId;\r\ +> \n :local GlobalConfVersionBefore \$GlobalConfVersion;\r\ +> \n :local ReloadGlobal false;\r\ +> \n :local DeviceMode [ /system/device-mode/get ];\r\ +> \n\r\ +> \n :if (\$CheckSumsVerify = true) do={\r\ +> \n :local CheckSums ({});\r\ +> \n :do {\r\ +> \n :local Url (\$GlobalScriptsUrl . \$SumsDirAndFileName . \$GlobalScr\ +> iptsUrlSuffix);\r\ +> \n \$LogPrint debug \$0 (\"Fetching checksums from url: \" . \$Url);\ +> \r\ +> \n :set CheckSums [ :deserialize from=json ([ /tool/fetch check-certi\ +> ficate=yes-without-crl \\\r\ +> \n http-header-field=({ [ \$FetchUserAgentStr \$0 ] }) \$Url output\ +> =user as-value ]->\"data\") ];\r\ +> \n } on-error={ \$LogPrint warning \$0 (\"Err = \" . \$Err); }\r\ +> \n }\r\ +> \n\r\ +> \n :foreach Script in=[ /system/script/find where source~\"^#!rsc by Vado\ +> s\" ] do={\r\ +> \n :local ScriptVal [ /system/script/get \$Script ];\r\ +> \n :local ScriptInfo [ \$ParseKeyValueStore (\$ScriptVal->\"comment\") \ +> ];\r\ +> \n :local SourceNew;\r\ +> \n\r\ +> \n :foreach Scheduler in=[ /system/scheduler/find where on-event~(\"\\\ +> \\b\" . \$ScriptVal->\"name\" . \"\\\\b\") ] do={\r\ +> \n :local SchedulerVal [ /system/scheduler/get \$Scheduler ];\r\ +> \n :if (\$ScriptVal->\"policy\" != \$SchedulerVal->\"policy\") do={\r\ +> \n \$LogPrint warning \$0 (\"Policies differ for script '\" . \$Scr\ +> iptVal->\"name\" . \"' and its scheduler '\" . \$SchedulerVal->\"name\" . \ +> \"'!\");\r\ +> \n }\r\ +> \n }\r\ +> \n :do {\r\ +> \n :if (\$ScriptInfo->\"ignore\" = true) do={\r\ +> \n \$LogPrint debug \$0 (\"Ignoring script '\" . \$ScriptVal->\"nam\ +> e\" . \"', as requested.\");\r\ +> \n :error true;\r\ +> \n }\r\ +> \n :if (\$CheckSumsVerify = true) do={\r\ +> \n :local CheckSum (\$CheckSums->(\$ScriptVal->\"name\"));\r\ +> \n :if ([ :len (\$ScriptInfo->\"base-url\") ] = 0 && [ :len (\$Scri\ +> ptInfo->\"url-suffix\") ] = 0 && \\\r\ +> \n [ :convert transform=md5 to=hex [ :tolf (\$ScriptVal->\"sou\ +> rce\") ] ] = \$CheckSum) do={\r\ +> \n \$LogPrint debug \$0 (\"Checksum for script '\" . \$ScriptVal-\ +> >\"name\" . \"' matches, ignoring.\");\r\ +> \n :error true;\r\ +> \n }\r\ +> \n }\r\ +> \n :if ([ :len (\$ScriptInfo->\"certificate\") ] > 0) do={\r\ +> \n :if ([ \$CertificateAvailable (\$ScriptInfo->\"certificate\") \"\ +> fetch\" ] = false) do={\r\ +> \n \$LogPrint warning \$0 (\"Downloading certificate failed, tryi\ +> ng without.\");\r\ +> \n }\r\ +> \n }\r\ +> \n :onerror Err {\r\ +> \n :local BaseUrl [ \$EitherOr (\$ScriptInfo->\"base-url\") \$Globa\ +> lScriptsUrl ];\r\ +> \n :local UrlSuffix [ \$EitherOr (\$ScriptInfo->\"url-suffix\") \$G\ +> lobalScriptsUrlSuffix ];\r\ +> \n :local Url (\$BaseUrl . \$ScriptVal->\"name\" . \".rsc\" . \$Url\ +> Suffix);\r\ +> \n \$LogPrint warning \$0 (\"Fetching script '\" . (\$ScriptVal->\"\ +> name\") . \"' from url: \" . \$Url);\r\ +> \n :local Result [ /tool/fetch check-certificate=yes-without-crl \\\ +> \r\ +> \n http-header-field=({ [ \$FetchUserAgentStr \$0 ] }) \$Url outp\ +> ut=user as-value ];\r\ +> \n :if (\$Result->\"status\" = \"finished\") do={\r\ +> \n :set SourceNew [ :tolf (\$Result->\"data\") ];\r\ +> \n } \r\ +> \n } do={\r\ +> \n \$LogPrint warning \$0 (\"Failed fetching script '\" . \$ScriptV\ +> al->\"name\" . \"': \" . \$Err);\r\ +> \n :if (\$Err != \"Fetch failed with status 404\") do={\r\ +> \n :error false;\r\ +> \n }\r\ +> \n :if (\$ScriptVal->\"source\" = \"#!rsc by Vados\") do={\r\ +> \n \$LogPrint warning \$0 (\"Removing dummy. Typo on installation\ +> \?\");\r\ +> \n /system/script/remove \$Script;\r\ +> \n :error false;\r\ +> \n }\r\ +> \n :if (\$CheckSumsVerify = true) do={\r\ +> \n :if ([ :len (\$ScriptInfo->\"base-url\") ] = 0 && [ :len (\$Sc\ +> riptInfo->\"url-suffix\") ] = 0 && \\\r\ +> \n [ :len \$CheckSum ] = 0) do={\r\ +> \n \$LogPrint warning \$0 (\"Added the script manually\? Skip u\ +> pdates with 'ignore=true' in comment.\");\r\ +> \n }\r\ +> \n }\r\ +> \n :error false;\r\ +> \n }\r\ +> \n\r\ +> \n :if ([ :len \$SourceNew ] = 0) do={\r\ +> \n \$LogPrint debug \$0 (\"No update for script '\" . (\$ScriptVal-\ +> >\"name\") . \"'.\");\r\ +> \n :error false;\r\ +> \n }\r\ +> \n\r\ +> \n :local SourceCRLF [ :tocrlf \$SourceNew ];\r\ +> \n :if (\$InitSetup != true && ((\$ScriptVal->\"name\") != \"AM-Globa\ +> lConfig\" || (\$ScriptVal->\"name\") != \"AM-GlobalFunc\")) do={\r\ +> \n :if (\$SourceNew = (\$ScriptVal->\"source\") || \$SourceCRLF = (\ +> \$ScriptVal->\"source\")) do={\r\ +> \n \$LogPrint debug \$0 (\"Script '\" . (\$ScriptVal->\"name\") \ +> . \"' source did not change. End of lines set to CRLF.\");\r\ +> \n if (\$ScriptUpdatesCRLF = false) do={\r\ +> \n :put [ :tolf \$SourceNew ];\r\ +> \n \$LogPrint debug \$0 (\"Script '\" . (\$ScriptVal->\"name\"\ +> ) . \"' source update end of lines to LF.\");\r\ +> \n }\r\ +> \n :error false;\r\ +> \n }\r\ +> \n }\r\ +> \n\r\ +> \n :if ([ :pick \$SourceNew 0 14 ] != \"#!rsc by Vados\") do={\r\ +> \n \$LogPrint warning \$0 (\"Looks like new script '\" . \$ScriptVa\ +> l->\"name\" . \"' is not valid (missing shebang = '\$shebang') Ignoring!\"\ +> );\r\ +> \n :error false;\r\ +> \n }\r\ +> \n\r\ +> \n :if (\$CommentsInScripts = true) do={\r\ +> \n :local CommentLine [ \$Grep \$SourceNew (\"\\23 Script comment:\ +> \_\") ];\r\ +> \n :if ([ :len \$CommentLine ] = 0) do={\r\ +> \n \$LogPrint debug \$0 (\"The search in new script '\" . (\$Scr\ +> iptVal->\"name\") . \"' for comment in script body, is not found result Ig\ +> noring!\");\r\ +> \n :error false;\r\ +> \n } else={\r\ +> \n :if ([ :len (\$ScriptVal->\"comment\")] = 0 || [ :len (\$Scri\ +> ptVal->\"comment\")] != [ :pick \$CommentLine ([ :find \$CommentLine \":\"\ +> ] + 2) [ :len \$CommentLine] ]) do={\r\ +> \n \$LogPrint debug \$0 (\"Exsiting comment for script '\" . (\ +> \$ScriptVal->\"name\") . \"' is '\" . (\$ScriptVal->\"comment\") . \"'.\")\ +> ;\r\ +> \n :set (\$ScriptVal->\"comment\") [ :pick \$CommentLine ([ :f\ +> ind \$CommentLine \":\"] + 2) [ :len \$CommentLine] ];\r\ +> \n \$LogPrint debug \$0 (\"New comment (\" . (\$ScriptVal->\"c\ +> omment\") . \") for script '\" . (\$ScriptVal->\"name\") . \"' has been ad\ +> ded!\");\r\ +> \n } else={\r\ +> \n \$LogPrint debug \$0 (\"Comment for script '\" . (\$ScriptV\ +> al->\"name\") . \"' did not change.\");\r\ +> \n :error false;\r\ +> \n }\r\ +> \n } \r\ +> \n }\r\ +> \n\r\ +> \n :local RequiredROS ([ \$ParseKeyValueStore [ \$Grep \$SourceNew (\ +> \"\\23 requires RouterOS, \") ] ]->version);\r\ +> \n :if ([ \$RequiredRouterOS \$0 [ \$EitherOr \$RequiredROS \"0.0\" ]\ +> \_false ] = false) do={\r\ +> \n \$LogPrint warning \$0 (\"The script '\" . (\$ScriptVal->\"name\ +> \") . \"' requires RouterOS \" . \\\r\ +> \n \$RequiredROS . \", which is not met by your installation. I\ +> gnoring!\");\r\ +> \n :error false;\r\ +> \n }\r\ +> \n :local RequiredDM [ \$ParseKeyValueStore [ \$Grep \$SourceNew (\"\ +> \\23 requires device-mode, \") ] ];\r\ +> \n :local MissingDM ({});\r\ +> \n :foreach Feature,Value in=\$RequiredDM do={\r\ +> \n :if ([ :typeof (\$DeviceMode->\$Feature) ] = \"bool\" && (\$Devi\ +> ceMode->\$Feature) = false) do={\r\ +> \n :set MissingDM (\$MissingDM, \$Feature);\r\ +> \n }\r\ +> \n }\r\ +> \n :if ([ :len \$MissingDM ] > 0) do={\r\ +> \n \$LogPrint warning \$0 (\"The script '\" . (\$ScriptVal->\"name\ +> \") . \"' requires disabled \" . \\\r\ +> \n \"device-mode features (\" . [ :tostr \$MissingDM ] . \"). I\ +> gnoring!\");\r\ +> \n :error false;\r\ +> \n }\r\ +> \n\r\ +> \n :if ([ \$ValidateSyntax \$SourceNew ] = false) do={\r\ +> \n \$LogPrint warning \$0 (\"Syntax validation for script '\" . (\$\ +> ScriptVal->\"name\") . \"' failed! Ignoring!\");\r\ +> \n :error false;\r\ +> \n }\r\ +> \n \r\ +> \n :log info (\"Updating script: \" . (\$ScriptVal->\"name\") . \" Sc\ +> ript comment: \" . (\$ScriptVal->\"comment\"));\r\ +> \n\r\ +> \n /system/script/set owner=(\$ScriptVal->\"name\") comment=(\$Script\ +> Val->\"comment\") \\\r\ +> \n source=[ \$IfThenElse (\$ScriptUpdatesCRLF = true) \$SourceCRL\ +> F \$SourceNew ] \$Script;\r\ +> \n :if (\$ScriptVal->\"name\" = \"AM-GlobalConfig\" || \\\r\ +> \n \$ScriptVal->\"name\" = \"AM-GlobalFunc\" || \\\r\ +> \n \$ScriptVal->\"name\" ~ (\"^(AM-GlobalFunc\\\\.d|mod)/.\")) d\ +> o={\r\ +> \n :set ReloadGlobal true;\r\ +> \n }\r\ +> \n } on-error={ }\r\ +> \n }\r\ +> \n :if (\$ReloadGlobal = true) do={\r\ +> \n \$LogPrint info \$0 (\"Reloading global configuration and functions.\ +> \");\r\ +> \n :onerror Err {\r\ +> \n :global InitSetup (a);\r\ +> \n /system/script {run AM-GlobalConfig; run AM-GlobalFunc;};\r\ +> \n } do={\$LogPrint error \$0 (\"Reloading global configuration and fun\ +> ctions failed! \" . \$Err)}\r\ +> \n }\r\ +> \n :if (\$GlobalConfVersionBefore > \$GlobalConfVersion) do={\r\ +> \n \$LogPrint warning \$0 (\"The configuration version decreased from \ +> \" . \\\r\ +> \n \$GlobalConfVersionBefore . \" to \" . \$GlobalConfVersion . \\\r\ +> \n \". Installed an older version\?\");\r\ +> \n }\r\ +> \n :if (\$GlobalConfVersionBefore < \$GlobalConfVersion) do={\r\ +> \n :global GlobalConfChanges;\r\ +> \n :global GlobalConfMigration;\r\ +> \n :local ChangeLogCode;\r\ +> \n :if ([ :len \$ChangeLogCode ] > 0) do={\r\ +> \n :if ([ \$ValidateSyntax \$ChangeLogCode ] = true) do={\r\ +> \n :onerror Err {\r\ +> \n [ :parse \$ChangeLogCode ];\r\ +> \n } do={\$LogPrint warning \$0 (\"The changelog failed to run: \" \ +> . \$Err)}\r\ +> \n } else={\$LogPrint warning \$0 (\"The changelog failed syntax vali\ +> dation!\")}\r\ +> \n }\r\ +> \n :if ([ :len \$GlobalConfMigration ] > 0) do={\r\ +> \n :for I from=(\$GlobalConfVersionBefore + 1) to=\$GlobalConfVersion\ +> \_do={\r\ +> \n :local Migration (\$GlobalConfMigration->[ :tostr \$I ]);\r\ +> \n :do {\r\ +> \n :if ([ :typeof \$Migration ] != \"str\") do={\r\ +> \n \$LogPrint debug \$0 (\"Migration code for change \" . \$I .\ +> \_\" is not available.\");\r\ +> \n :error false;\r\ +> \n }\r\ +> \n :if ([ \$ValidateSyntax \$Migration ] = false) do={\r\ +> \n \$LogPrint warning \$0 (\"Migration code for change \" . \$I\ +> \_. \" failed syntax validation!\");\r\ +> \n :error false}\r\ +> \n \$LogPrint info \$0 (\"Applying migration for change \" . \$I \ +> . \": \" . \$Migration);\r\ +> \n :onerror Err {\r\ +> \n [ :parse \$Migration ];\r\ +> \n } do={\$LogPrint warning \$0 (\"Migration code for change \" .\ +> \_\$I . \" failed to run: \" . \$Err)}\r\ +> \n } on-error={ }\r\ +> \n }\r\ +> \n }\r\ +> \n :local NotificationMessage (\"The configuration version on \" . \$Id\ +> entity . \" increased \" . \\\r\ +> \n \"to \" . \$GlobalConfVersion . \", current configuration may nee\ +> d modification. \" . \\\r\ +> \n \"Please review and update global-config-overlay, then re-run glo\ +> bal-config.\");\r\ +> \n \$LogPrint info \$0 (\$NotificationMessage);\r\ +> \n :if ([ :len \$GlobalConfChanges ] > 0) do={\r\ +> \n :set NotificationMessage (\$NotificationMessage . \"\\n\\nChanges:\ +> \");\r\ +> \n :for I from=(\$GlobalConfVersionBefore + 1) to=\$GlobalConfVersion\ +> \_do={\r\ +> \n :local Change (\$GlobalConfChanges->[ :tostr \$I ]);\r\ +> \n :set NotificationMessage (\$NotificationMessage . \"\\n \" . \\\ +> \r\ +> \n [ \$SymbolForNotification \"pushpin\" \"*\" ] . \$Change);\r\ +> \n \$LogPrint info \$0 (\"Change \" . \$I . \": \" . \$Change);\r\ +> \n }\r\ +> \n } else={\r\ +> \n :set NotificationMessage (\$NotificationMessage . \"\\n\\nNews and\ +> \_changes are not available.\");\r\ +> \n\r\ +> \n }\r\ +> \n\r\ +> \n :if ([ :len \$GlobalConfChanges ] > 0) do={ :set GlobalConfChanges; \ +> } else={ :global GlobalConfChanges (a); }\r\ +> \n :if ([ :len \$GlobalConfMigration ] > 0) do={ :set GlobalConfMigrati\ +> on; } else={ :global GlobalConfMigration (a); }\r\ +> \n }\r\ +> \n} do={\r\ +> \n :global ExitOnError; \$ExitOnError \$0 \$Err;\r\ +> \n} }\r\ +> \n\r\ +> \n# load modules\r\ +> \n:foreach Script in=[ /system/script/find where name ~ \"^(global-functio\ +> ns\\\\.d|mod)/.\" ] do={\r\ +> \n :local ScriptVal [ /system/script/get \$Script ];\r\ +> \n :if ([ \$ValidateSyntax (\$ScriptVal->\"source\") ] = true) do={\r\ +> \n :onerror Err {\r\ +> \n /system/script/run \$Script;\r\ +> \n } do={\r\ +> \n \$LogPrint error \$0 (\"Module '\" . \$ScriptVal->\"name\" . \"' f\ +> ailed to run: \" . \$Err);\r\ +> \n }\r\ +> \n } else={\r\ +> \n \$LogPrint error \$0 (\"Module '\" . \$ScriptVal->\"name\" . \"' fai\ +> led syntax validation, skipping.\");\r\ +> \n }\r\ +> \n}\r\ +> \n\r\ +> \n# Add and fix global scheduler\r\ +> \n:put \"Add or/and fix Global scheduler...\";\r\ +> \n:local OnEvent \"/system/script { run AM-GlobalConfig; run AM-GlobalFunc\ +> ; }\";\r\ +> \n:local Comment \"Every Day Set Global Environment Variables\";\r\ +> \n:if ([ :len [ /system/scheduler/find where name=\"AM-SetGlobalEnv\" ] ] \ +> = 0) do={\r\ +> \n /system/scheduler/add name=\"AM-SetGlobalEnv\" comment=\$Comment on-ev\ +> ent=\$OnEvent start-time=startup;\r\ +> \n}\r\ +> \n:if ([ /system/scheduler/get \"AM-SetGlobalEnv\" comment ] != \$Comment)\ +> \_do={\r\ +> \n /system/scheduler/set \"AM-SetGlobalEnv\" comment=\$Comment;\r\ +> \n}\r\ +> \n:if ([ /system/scheduler/get \"AM-SetGlobalEnv\" on-event ] != \$OnEvent\ +> ) do={\r\ +> \n /system/scheduler/set \"AM-SetGlobalEnv\" on-event=\$OnEvent;\r\ +> \n}\r\ +> \n# Add Update Script scheduler\r\ +> \n:put \"Add or/and fix Update Script scheduler\";\r\ +> \n:set OnEvent \":global ScriptInstallUpdate; \\\$ScriptInstallUpdate;\";\ +> \r\ +> \n:set Comment \"Every Day Check For Update Scripts\";\r\ +> \n:if ([ :len [ /system/scheduler/find where name=\"AM-ScriptInstallUpdate\ +> \" ] ] = 0) do={\r\ +> \n/system/scheduler/add name=\"AM-ScriptInstallUpdate\" comment=\$Comment \ +> start-time=startup interval=1d on-event=\$OnEvent;\r\ +> \n}\r\ +> \n\r\ +> \n:onerror Err {\r\ +> \n :global GlobalConfReady;\r\ +> \n :retry { :if (\$GlobalConfReady != true) do={ :error (\"Global configs\ +> \_not ready.\"); }; } delay=100ms max=5;\r\ +> \n\r\ +> \n:log warning (\"This script \$ScriptName Loaded \" . \\\r\ +> \n [ \$IfThenElse (\$CommitId != \"unknown\") ([ \$CommitBrief ] . \" \ +> \") ] . \\\r\ +> \n \"on \" . \$devBoardName . \"\\nRouterOS: \" . \$devCurVersion . \"\ +> \\nArchitecture: \" . \$devCurArch . \"\\nIdentity: \" . \$Identity);\r\ +> \n # signal we are ready\r\ +> \n:set GlobalFuncReady true;\r\ +> \n:set ExitOK true;\r\ +> \n\r\ +> \n:log info (\$0 . \"Global configs ready!\");\r\ +> \n} do={\r\ +> \n :global ExitOnError; \$ExitOnError \$0 \$Err;\r\ +> \n}\r\ +> \n" +> add comment=\ +> "Lookup IP addresses for RKN list and add them to firewall address-list" \ +> dont-require-permissions=no name=AM-RKN-dnsLookup owner=AM-RKN-dnsLookup \ +295,305c2278,2416 +< source="# ============================================================\ +< \n# AWG Proxy -- MikroTik RouterOS (protocol: v2)\ +< \n# 2026-07-21 10:33:39\ +< \n# ============================================================\ +< \n\ +< \n# 0. Check prerequisites\ +< \n:if ([:len [/system/package/find where name=\"container\" disabled=no]] \ +< = 0) do={\ +< \n :put \"Container package is not installed or disabled. Install it and \ +< reboot.\"\ +< \n :error \"Usage: /system/device-mode/update container=yes\"\ +--- +> source="#!rsc by Vados\r\ +> \n# RouterOS script: AM-RKN-dnsLookup\r\ +> \n# Script comment: Lookup IP addresses for RKN list and add them to firew\ +> all address-list\r\ +> \n# Copyright (c) 2007-2026 Vados \r\ +> \n#\r\ +> \n#\r\ +> \n# requires RouterOS, version=7.19\r\ +> \n# requires device-mode, fetch\r\ +> \n#\r\ +> \n# Script description: This script is intended to be run periodically, e.\ +> g. once a day, to update the IP addresses in the firewall address-list bas\ +> ed on the RKN list.\r\ +> \n# It resolves the domain names in the RKN list and a\ +> dds the corresponding IP addresses to the specified firewall address-list.\ +> \r\ +> \n# The script also handles CNAME records by following\ +> \_them until it finds A records.\r\ +> \n# Usage:\r\ +> \n# /system/script { run AM-RKN-dnsLookup; }\r\ +> \n:local ScriptName [ :jobname ];\r\ +> \n\r\ +> \n:global dnsLookupReady false;\r\ +> \n:if ([:typeof \$dnsLookupReady] != \"boolean\") do={ :set dnsLookupReady\ +> \_true; }\r\ +> \nwhile (!\$dnsLookupReady) do={ :nothing; }\r\ +> \n:set dnsLookupReady false;\r\ +> \n\r\ +> \n:local arrRKN {\r\ +> \n \"telegra.ph\"\r\ +> \n \"grani.ru\"\r\ +> \n \"xhamster.com\"\r\ +> \n \"lostfilm.tv\"\r\ +> \n \"rutracker.org\"\r\ +> \n \"lurkmore.to\"\r\ +> \n \"dou.ua\"\r\ +> \n \"youporn.com\"\r\ +> \n \"pornolab.net\"\r\ +> \n \"crimerussia.com\"\r\ +> \n \"telegram.org\"\r\ +> \n \"api.telegram.org\"\r\ +> \n \"facebook.com\"\r\ +> \n \"instagram.com\"\r\ +> \n \"x.com\"\r\ +> \n \"twitter.com\"\r\ +> \n \"youtube.com\"\r\ +> \n \"googleapis.com\"\r\ +> \n \"youtu.be\"\r\ +> \n \"googlevideo.com\"\r\ +> \n \"gstatic.com\"\r\ +> \n \"googleusercontent.com\"\r\ +> \n \"nhacmp3youtube.com\"\r\ +> \n \"telegram.me\"\r\ +> \n \"t.me\";}\r\ +> \n\r\ +> \n:local ListRKN \"RKN-dnsLookup\";\r\ +> \n:local ListComment (\"ListRKN managed by \" . \$ScriptName);\r\ +> \n:foreach aListItem in=[/ip/firewall/address-list find list=\$ListRKN] do\ +> ={\r\ +> \n /ip firewall address-list remove \$aListItem;\r\ +> \n}\r\ +> \n:foreach aItem in=\$arrRKN do={\r\ +> \n# :do {\r\ +> \n :retry delay=500ms max=5 on-error={:log error \"dns resolve fail\ +> ure [ \$aItem - resolve ip ]\"} command={:resolve \$aItem}\r\ +> \n# } on-error={\r\ +> \n# :log error \"dns resolve failure [ \$arItem - resolve ip ]\";\r\ +> \n# }\r\ +> \n :foreach dnsRecord in=[/ip dns cache all find where (name=\$aItem)] \ +> do={\r\ +> \n :if ([/ip dns cache all get \$dnsRecord type]=\"A\") do={\r\ +> \n :local newAddress [/ip dns cache all get \$dnsRecord data];\ +> \r\ +> \n :do {\r\ +> \n /ip firewall address-list add list=\$ListRKN address=\$newA\ +> ddress comment=\$aItem;\r\ +> \n :log warning \"Successfully adding ip to list A record: \ +> \$dnsRecord, address: \$newAddress domain: \$aItem\";\r\ +> \n } on-error={\r\ +> \n :log error \"error when adding ip to list A record: \$dn\ +> sRecord, address: \$newAddress domain: \$aItem\";\r\ +> \n }\r\ +> \n }\r\ +> \n :if ([/ip dns cache all get \$dnsRecord type]=\"CNAME\") do={\r\ +> \n :local cname;\r\ +> \n :local nextCname;\r\ +> \n :local cnameAddress;\r\ +> \n :set cname [/ip dns cache all find where (name=\$aItem && ty\ +> pe=\"CNAME\")];\r\ +> \n :set nextCname [/ip dns cache all find where (name=[/ip dns \ +> cache all get \$cname data] && type=\"CNAME\")];\r\ +> \n :while (\$nextCname != \"\") do={\r\ +> \n :set cname \$nextCname;\r\ +> \n :set nextCname [/ip dns cache all find where (name=[/ip \ +> dns cache all get \$cname data] && type=\"CNAME\")];\r\ +> \n }\r\ +> \n :foreach aRecord in=[/ip dns cache all find where (name=[/ip\ +> \_dns cache all get \$cname data] && type=\"A\")] do={\r\ +> \n :do {\r\ +> \n :set cnameAddress [/ip dns cache all get \$aRecord d\ +> ata];\r\ +> \n /ip firewall address-list add list=\$ListRKN address\ +> =\$cnameAddress comment=\$aItem;\r\ +> \n :log warning \"Succesfully adding ip to list CNAME r\ +> ecord: \$cname, A record: \$aRecord, address: \$newAddress, from domain: \ +> \$aItem.\";\r\ +> \n# /ip firewall raw add action=add-dst-to-address-list\ +> \_address-list=\$ListRKN address-list-timeout=none-dynamic chain=preroutin\ +> g comment=\$aItem content=\$aItem;\r\ +> \n } on-error={\r\ +> \n :log error \"error when adding ip to list CNAME reco\ +> rd: \$cname, A record: \$aRecord, address: \$newAddress, from domain: \$aI\ +> tem.\";\r\ +> \n }\r\ +> \n }\r\ +> \n }\r\ +> \n }\r\ +> \n}\r\ +> \n\r\ +> \n:if ([ :len [ /system/scheduler/find where name=\$ScriptName ] ] = 0) do\ +> ={\r\ +> \n :log error (\$ScriptName . \"System Scheduler for script: \" . \$Scri\ +> ptName . \" is NOT SET! Fix It Now!\");\r\ +> \n /system/scheduler/add name=\$ScriptName on-event=\"/system/script { \ +> run \$ScriptName; }\" comment=\"Update RKN DNS Looup\" interval=00:30:00 p\ +> olicy=\"ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon\"\ +> \_start-time=startup;\r\ +> \n }\r\ +> \n:set dnsLookupReady true;\r\ +> \ndelay 2s; \r\ +> \n:global dnsLookupReady (a);\r\ +> \n" +> add dont-require-permissions=no name="renameLists " owner=vados policy=\ +> ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source=":\ +> local oldName \"Test\";\ +> \n:local newName \"Test-IP\";\ +> \n/ip firewall address-list\ +> \n:foreach i in=[find list=\$oldName] do={\ +> \nset \$i list=\$newName;\ +306a2418,2421 +> \n" +> add dont-require-permissions=no name=IPv6-Settings owner=vados policy=\ +> ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ +> #############Script Settings##################\ +308,335c2423,2446 +< \n# Check storage device\ +< \n{\ +< \n :local targetDisk \"usb1\"\ +< \n :local diskFree 0\ +< \n :do { :set diskFree [/disk/get [find where mount-point=\$targetDisk] f\ +< ree] } on-error={}\ +< \n :if (\$diskFree = 0) do={\ +< \n :local baseDisk \$targetDisk\ +< \n :local dashPos [:find \$targetDisk \"-part\"]\ +< \n :if ([:typeof \$dashPos] != \"nil\") do={ :set baseDisk [:pick \$tar\ +< getDisk 0 \$dashPos] }\ +< \n :if ([:len [/disk/find where slot=\$baseDisk]] > 0) do={\ +< \n :put (\"Device \$baseDisk found but \$targetDisk is not available.\ +< \")\ +< \n :put \"Format \$baseDisk as ext4\? ALL DATA WILL BE ERASED!\"\ +< \n :put \"Press 'y' to confirm, any other key to cancel:\"\ +< \n :local key [/terminal/inkey timeout=30]\ +< \n :if (\$key = 121 || \$key = 89) do={\ +< \n :put \"Formatting \$baseDisk as ext4...\"\ +< \n /disk/format-drive \$baseDisk file-system=ext4 label=\$baseDisk\ +< \n :delay 3s\ +< \n :do { :set diskFree [/disk/get [find where mount-point=\$targetD\ +< isk] free] } on-error={}\ +< \n :if (\$diskFree = 0) do={\ +< \n :put (\"ERROR: \$targetDisk not found after formatting.\")\ +< \n :put \"Check mount point: /disk/print\"\ +< \n :error (\"Mount point \$targetDisk not found after formatting\ +< \")\ +--- +> \n:local \"IF-TUN\" \"6to4-tun\"\ +> \n:local \"IF-LOC\" \"Bridge-LAN\"\ +> \n:local \"POOL-6TO4\" \"poolV6-local\"\ +> \n:local \"force-update\" false\ +> \n############ use then static ip #######################\ +> \n:local \"lease-address\" [/ip address get [find interface=\$\"IF-LOC\"] \ +> address]\ +> \n#:local \"interface\" \"ext\"\ +> \n:local bound 0\ +> \n\ +> \n###############################################\ +> \n\ +> \n:local 6to4prefix do={\ +> \n :global dec2hex\ +> \n :local ipv4 \$1\ +> \n :local ipv6 \"2002:\"\ +> \n :for i from=0 to=2 step=1 do={ \ +> \n :if ( \$i = 2) do={\ +> \n :set ipv6 (\$ipv6.\":\")\ +> \n }\ +> \n :local fp [:find \$ipv4 \".\"]\ +> \n :if ( \$fp > 0 ) do={\ +> \n :set ipv6 (\$ipv6.[\$dec2hex [:pick \$ipv4 0 \$fp]])\ +> \n :set ipv4 [:pick \$ipv4 (\$fp + 1 ) [:len \$ipv4]]\ +337,345d2447 +< \n :put (\"Formatted OK. Free: \" . (\$diskFree / 1048576) . \" MB\ +< \")\ +< \n } else={\ +< \n :error \"Formatting cancelled\"\ +< \n }\ +< \n } else={\ +< \n :put (\"ERROR: Storage device \$targetDisk not found.\")\ +< \n :put \"Check available disks: /disk/print\"\ +< \n :error (\"Storage not found: \" . \$targetDisk)\ +347,350c2449 +< \n } else={\ +< \n :put (\"Storage OK: \$targetDisk (\" . (\$diskFree / 1048576) . \" M\ +< B free)\")\ +< \n }\ +--- +> \n :return (\$ipv6.[\$dec2hex \$ipv4])\ +352,390c2451,2468 +< \n\ +< \n# 1. Uninstall script\ +< \n/system/script/add name=awg2vds-uninstall comment=awg2vds source={\ +< \n :put \"Uninstallimg AmneziaWG...\"\ +< \n :log info \"Uninstallimg AmneziaWG...\"\ +< \n :local prevDNS \"\"\ +< \n :do { :set prevDNS [/container/envs/get [find where list=\"awg2vds-env\ +< \" key=\"AWG_PREV_DNS\"] value] } on-error={}\ +< \n :local prevTmpdir \"\"\ +< \n :do { :set prevTmpdir [/container/envs/get [find where list=\"awg2vds-\ +< env\" key=\"AWG_PREV_TMPDIR\"] value] } on-error={}\ +< \n /ip/route/remove [find where comment=awg2vds-tunnel]\ +< \n /ip/route/remove [find where comment=awg2vds-dns]\ +< \n /container/stop [find where interface=veth-awg2vds]\ +< \n :delay 7s\ +< \n /container/remove [find where interface=veth-awg2vds]\ +< \n /container/envs/remove [find where list=\"awg2vds-env\"]\ +< \n :if (\$prevDNS != \"\") do={\ +< \n :do { /ip/dns/set servers=\"\$prevDNS\" } on-error={}\ +< \n :put (\"DNS restored to: \$prevDNS\")\ +< \n }\ +< \n /container/config set tmpdir=\$prevTmpdir\ +< \n :put (\"Container tmpdir restored to: \$prevTmpdir\")\ +< \n /ip/firewall/nat/remove [find where out-interface=\"wg-awg2vds\"]\ +< \n /ip/firewall/nat/remove [find where src-address=\"172.20.200.68/30\"]\ +< \n /ip/address/remove [find where address=\"172.20.200.69/30\"]\ +< \n /interface/veth/remove [find where name=\"veth-awg2vds\"]\ +< \n /interface/wireguard/peers/remove [find where interface=\"wg-awg2vds\"\ +< ]\ +< \n /ip/address/remove [find where interface=\"wg-awg2vds\"]\ +< \n /interface/wireguard/remove [find where name=\"wg-awg2vds\"]\ +< \n :do { /file/remove [find where name~\"awg2vds.+tar\"] } on-error={}\ +< \n :do { /file/remove [find where name=\"usb1/awg2vds\"] } on-error={}\ +< \n :do { /file/remove [find where name=\"usb1/ru_ranges_timeout.rsc\"] } \ +< on-error={}\ +< \n :do { /file/remove [find where name~\"usb1/pull\"] } on-error={}\ +< \n :put \"Uninstall AmneziaWG Proxy complete!\"\ +< \n :log info \"Uninstall AmneziaWG Proxy complete!\"\ +< \n /system/script/remove [find where name=awg2vds-uninstall]\ +--- +> \n:local \"str_replace\" do={\ +> \n :local \"str-pos\" [:find \$1 \$2]\ +> \n :local \"str-len\" [:len \$2]\ +> \n :local str \"\"\ +> \n :local rest \$1\ +> \n :while (\$\"str-pos\" >= 0) do={\ +> \n :local t [:pick \$rest 0 \$\"str-pos\"]\ +> \n :if ( \$4 > 0 ) do={\ +> \n :for i from=1 to=(\$4 - [:len \$t]) step=1 do={\ +> \n :set str (\$str.\$5)\ +> \n }\ +> \n }\ +> \n :set str (\$str.\$t.\$3)\ +> \n :set rest [:pick \$rest (\$\"str-pos\"+\$\"str-len\") [:len \$re\ +> st]]\ +> \n :set \"str-pos\" [:find \$rest \$2]\ +> \n }\ +> \n :return (\$str.\$rest)\ +393,438c2471,2472 +< \n# 2. Network infrastructure\ +< \n/interface/veth/add name=veth-awg2vds address=172.20.200.70/30 gateway=1\ +< 72.20.200.69\ +< \n/ip/address/add address=172.20.200.69/30 interface=veth-awg2vds\ +< \n/ip/firewall/nat/add chain=srcnat action=masquerade src-address=172.20.2\ +< 00.68/30\ +< \n\ +< \n# 3. WireGuard interface (MikroTik derives the public key automatically)\ +< \n/interface/wireguard/add name=wg-awg2vds private-key=\"4LNSJJNEDeT2LFXkF\ +< x0XyrNp2Mp7YXlS8SawhqNfKGQ=\" listen-port=26084 disabled=yes\ +< \n/interface/wireguard/peers/add interface=wg-awg2vds public-key=\"qHFd72X\ +< DJJ5UrUZCZ0vRFQmzxP7eUYcOuaGL9ZbHtyg=\" preshared-key=\"ckhzjCcr15ve+IeDRY\ +< veYITR7a/CMZCcOZ2Z0cABKD8=\" endpoint-address=172.20.200.70 endpoint-port=\ +< 51820 allowed-address=10.10.10.1/24,10.30.30.0/24,0.0.0.0/0 persistent-kee\ +< palive=10\ +< \n/ip/address/add address=10.10.10.2/24 interface=wg-awg2vds\ +< \n\ +< \n# 4. Container environment variables\ +< \n/container/envs/add list=awg2vds-env key=AWG_LISTEN value=\":51820\"\ +< \n/container/envs/add list=awg2vds-env key=AWG_REMOTE value=\"109.107.177.\ +< 79:443\"\ +< \n/container/envs/add list=awg2vds-env key=AWG_JC value=\"6\"\ +< \n/container/envs/add list=awg2vds-env key=AWG_JMIN value=\"171\"\ +< \n/container/envs/add list=awg2vds-env key=AWG_JMAX value=\"481\"\ +< \n/container/envs/add list=awg2vds-env key=AWG_S1 value=\"50\"\ +< \n/container/envs/add list=awg2vds-env key=AWG_S2 value=\"139\"\ +< \n/container/envs/add list=awg2vds-env key=AWG_H1 value=\"1189447486-11894\ +< 48396\"\ +< \n/container/envs/add list=awg2vds-env key=AWG_H2 value=\"538303610-538304\ +< 276\"\ +< \n/container/envs/add list=awg2vds-env key=AWG_H3 value=\"101001960-101002\ +< 598\"\ +< \n/container/envs/add list=awg2vds-env key=AWG_H4 value=\"1783887443-17838\ +< 87851\"\ +< \n/container/envs/add list=awg2vds-env key=AWG_SERVER_PUB value=\"qHFd72XD\ +< JJ5UrUZCZ0vRFQmzxP7eUYcOuaGL9ZbHtyg=\"\ +< \n/container/envs/add list=awg2vds-env key=AWG_CLIENT_PUB value=[/interfac\ +< e/wireguard/get [find name=wg-awg2vds] public-key]\ +< \n/container/envs/add list=awg2vds-env key=AWG_S3 value=\"17\"\ +< \n/container/envs/add list=awg2vds-env key=AWG_S4 value=\"6\"\ +< \n/container/envs/add list=awg2vds-env key=AWG_I1 value=\"\"\ +< \n/container/envs/add list=awg2vds-env key=AWG_I2 value=\"\"\ +< \n/container/envs/add list=awg2vds-env key=AWG_I3 value=\"\"\ +< \n/container/envs/add list=awg2vds-env key=AWG_I4 value=\"\"\ +< \n/container/envs/add list=awg2vds-env key=AWG_I5 value=\"\"\ +--- +> \n:if (\$bound=1) do={\ +> \n :local t [:find \$\"lease-address\" \"/\"]\ +440,487c2474,2556 +< \n# 5. DNS\ +< \n{ :local rawDNS [/ip/dns/get servers]; :local prevDNS \"\"; :foreach s i\ +< n=[:toarray \$rawDNS] do={ :if ([:len \$prevDNS] > 0) do={ :set prevDNS \"\ +< \$prevDNS,\$s\" } else={ :set prevDNS \$s } }; /container/envs/add list=aw\ +< g2vds-env key=AWG_PREV_DNS value=\"\$prevDNS\" }\ +< \n# NOTE: replaces existing DNS configuration\ +< \n/ip/dns/set servers=10.10.10.1\ +< \n/ip/route/add dst-address=10.10.10.1/32 gateway=wg-awg2vds distance=1 co\ +< mment=awg2vds-dns\ +< \n\ +< \n# 6. Download, create and start container\ +< \n:local prevTmpdir [/container/config/get tmpdir]\ +< \n/container/envs/add list=awg2vds-env key=AWG_PREV_TMPDIR value=\$prevTmp\ +< dir\ +< \n/container/config set tmpdir=usb1/pull memory-high=200M\ +< \n{\ +< \n :local arch [/system/resource/get architecture-name]\ +< \n :local ver [/system/resource/get version]\ +< \n :local dotPos [:find \$ver \".\"]\ +< \n :local rest [:pick \$ver (\$dotPos + 1) [:len \$ver]]\ +< \n :local endPos [:find \$rest \".\"]\ +< \n :if ([:typeof \$endPos] = \"nil\") do={ :set endPos [:find \$rest \" \ +< \"] }\ +< \n :local minor [:tonum [:pick \$rest 0 \$endPos]]\ +< \n :local suffix \"\"\ +< \n :if (\$minor <= 20) do={ :set suffix \"-7.20-Docker\" }\ +< \n :local file \"\"\ +< \n :if (\$arch = \"arm64\") do={ :set file (\"awg-proxy-arm64\" . \$suffi\ +< x . \".tar.gz\") }\ +< \n :if (\$arch = \"arm\") do={ :set file (\"awg-proxy-arm\" . \$suffix . \ +< \".tar.gz\") }\ +< \n :if (\$arch ~ \"x86\") do={ :set file (\"awg-proxy-amd64\" . \$suffix \ +< . \".tar.gz\") }\ +< \n :if (\$file = \"\") do={ :error \"Unsupported architecture: \$arch\" }\ +< \n :local url \"https://github.com/timbrs/amneziawg-mikrotik-c/releases/l\ +< atest/download/\$file\"\ +< \n :local filePath (\"usb1/pull/\" . \$file)\ +< \n :do { /file/make-directory usb1/pull } on-error={}\ +< \n :if ([:len [/file/find where name=\$filePath]] = 0) do={\ +< \n :local freeStorage 0\ +< \n :do { :set freeStorage [/disk/get [find where mount-point=\"usb1\"] \ +< free] } on-error={}\ +< \n :if (\$freeStorage < 262144) do={\ +< \n :put (\"WARNING: Low disk space (\" . (\$freeStorage / 1024) . \"K\ +< B free). Need at least 256KB.\")\ +< \n :put \"See: https://github.com/timbrs/amneziawg-mikrotik-c#insuffi\ +< cient-disk-space\"\ +< \n :error \"Insufficient disk space\"\ +--- +> \n :if ( \$t >= 0 ) do={\ +> \n :set \"lease-address\" [:pick \$\"lease-address\" 0 \$t]\ +> \n }\ +> \n\ +> \n :if ( [/interface 6to4 print count-only where name=\$\"IF-TUN\"] = 0\ +> ) do={\ +> \n /interface 6to4 add !keepalive local-address=\$\"lease-address\"\ +> \_mtu=1280 name=\$\"IF-TUN\" remote-address=10.30.30.0\ +> \n :set \"force-update\" true\ +> \n }\ +> \n\ +> \n :local \"IPv4-TUN\" [/interface 6to4 get [find name=\$\"IF-TUN\"] lo\ +> cal-address];\ +> \n\ +> \n :if ( \$\"lease-address\" != \$\"IPv4-TUN\" || \$\"force-update\" = \ +> true) do={\ +> \n /interface 6to4 set [find name=\$\"IF-TUN\"] local-address=\$\"l\ +> ease-address\"\ +> \n /ipv6 address remove [find interface=\$\"IF-TUN\"]\ +> \n /ipv6 address remove [find interface=\$\"IF-LOC\"]\ +> \n /ipv6 route remove [find gateway ~ \$\"IF-TUN\" and dst-address=\ +> \"::/0\"]\ +> \n :local \"pool-prefix\" [\$6to4prefix \$\"lease-address\"]\ +> \n :if ( [/ipv6 pool print count-only where name=\$\"POOL-6TO4\"] =\ +> \_0) do={ \ +> \n /ipv6 pool add name=\$\"POOL-6TO4\" prefix=(\$\"pool-prefix\ +> \".\":1::/64\") prefix-length=64\ +> \n } else={\ +> \n /ipv6 pool set [/ipv6 pool find where name=\$\"POOL-6TO4\"] \ +> prefix=(\$\"pool-prefix\".\":1::/64\")\ +> \n }\ +> \n /ipv6 address add address=(\$\"pool-prefix\".\"::\".[\$MAC2EUI64\ +> \_[/interface get [find name=\$\"interface\"] mac-address]].\"/3\") interf\ +> ace=\$\"IF-TUN\" advertise=no\ +> \n /ipv6 address add eui-64=yes from-pool=\$\"POOL-6TO4\" interface\ +> =\$\"IF-LOC\" advertise=yes\ +> \n /ipv6 route add dst-address=::/0 gateway=(\"::10.30.30.81%\".\$\ +> \"IF-TUN\")\ +> \n :local t [/ipv6 address get [find interface=\$\"IF-LOC\"] addres\ +> s]\ +> \n :set t [:pick \$t 0 [:find \$t \"/\"]]\ +> \n :if ( [/ipv6 dhcp-server option print count-only where name=DNS]\ +> \_= 0) do={\ +> \n /ipv6 dhcp-server option add code=23 name=DNS value=(\"0x\".\ +> [\$\"str_replace\" \$t \":\" \"\" 4 \"0\"])\ +> \n } else={\ +> \n /ipv6 dhcp-server option set [/ipv6 dhcp-server option find \ +> where name=DNS] value=(\"0x\".[\$\"str_replace\" \$t \":\" \"\" 4 \"0\"])\ +> \n }\ +> \n :if ( [/ipv6 dhcp-server print count-only where interface=\$\"IF\ +> -LOC\"] = 0) do={\ +> \n /ipv6 dhcp-server add address-pool=\$\"POOL-6TO4\" dhcp-opti\ +> on=DNS interface=\$\"IF-LOC\" lease-time=1d name=\$\"IF-LOC\"\ +> \n }\ +> \n :if ( [ipv6 nd print count-only where interface=\$\"IF-LOC\"] = \ +> 0) do={\ +> \n /ipv6 nd add advertise-dns=no interface=\$\"IF-LOC\" other-c\ +> onfiguration=yes\ +> \n }\ +> \n }\ +> \n}" +> add dont-require-permissions=no name=IPv6-GlobalFunc owner=vados policy=\ +> ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source=":\ +> global MAC2EUI64 do={\ +> \n :local EUI64 \"\"\ +> \n :local MAC \$1\ +> \n :local HEX2DEC \"0123456789ABCDEF\"\ +> \n :for i from=0 to=5 step=1 do={\ +> \n :if ( \$i = 0 ) do={\ +> \n :set EUI64 [:pick \$MAC 0]\ +> \n :set EUI64 (\$EUI64.[:tostr [:pick \$\"HEX2DEC\" ([:find \$\ +> \"HEX2DEC\" [:pick \$MAC 1]] ^ 2)]])\ +> \n }\ +> \n :if ( \$i = 1 || \$i = 3) do={\ +> \n :set EUI64 (\$EUI64.\":\")\ +> \n }\ +> \n :if ( \$i = 2 ) do={\ +> \n :set EUI64 (\$EUI64.\"FF:FE\")\ +> \n }\ +> \n :if ( [:find \$MAC \":\"] = 2 ) do={\ +> \n :set MAC [:pick \$MAC 3 [:len \$MAC]]\ +> \n :set EUI64 (\$EUI64.[:pick \$MAC 0 2])\ +> \n }\ +489,537c2558 +< \n :put (\"Fetching: \$url -> \" . \$filePath)\ +< \n /tool/fetch url=\$url dst-path=\$filePath http-max-redirect-count=10\ +< \n } else={\ +< \n :put (\"File already exists: \" . \$filePath)\ +< \n }\ +< \n /container/add file=\$filePath interface=veth-awg2vds envlist=awg2vds-\ +< env hostname=awg2vds root-dir=usb1/awg2vds logging=no start-on-boot=yes co\ +< mment=awg2vds\ +< \n :if (\$minor > 20) do={ [:parse \"/container/set [find where interface\ +< =veth-awg2vds] shm-size=4M\"] }\ +< \n /file/remove \$filePath\ +< \n :local freeMem [/system/resource/get free-memory]\ +< \n :if (\$freeMem < 16777216) do={\ +< \n :put (\"WARNING: Low memory (\" . (\$freeMem / 1048576) . \"MB free)\ +< . 16MB+ recommended.\")\ +< \n }\ +< \n /container/start [find where interface=veth-awg2vds]\ +< \n :do { /file/remove [find where name=\"console-dump.txt\"] } on-error={\ +< }\ +< \n :put \"Waiting for container to start...\"\ +< \n :delay 5s\ +< \n /interface/wireguard/enable wg-awg2vds\ +< \n :put \"WireGuard interface enabled\"\ +< \n :put \"Installation complete!\"\ +< \n :put \"Ping test: 10.10.10.1 via AmneziaWG tunnel. repeat 10 times\"\ +< \n /ping 10.10.10.1 count=10 interval=1\ +< \n :put \"\"\ +< \n :put \"======= NEXT STEPS =======\"\ +< \n :put \"\"\ +< \n :put \"Route specific traffic through the AmneziaWG tunnel:\"\ +< \n :put \"\"\ +< \n :put \" Route a single host:\"\ +< \n :put \" /ip/route/add dst-address=8.8.8.8/32 gateway=wg-awg2vds com\ +< ment=awg2vds-tunnel\"\ +< \n :put \"\"\ +< \n :put \" Route a subnet:\"\ +< \n :put \" /ip/route/add dst-address=100.0.0.0/8 gateway=wg-awg2vds co\ +< mment=awg2vds-tunnel\"\ +< \n :put \"\"\ +< \n :put \" Remove a route:\"\ +< \n :put \" /ip/route/remove [find where comment=awg2vds-tunnel dst-add\ +< ress=8.8.8.8/32]\"\ +< \n :put \"\"\ +< \n :put \" Show all tunnel routes:\"\ +< \n :put \" /ip/route/print where comment=awg2vds-tunnel\"\ +< \n :put \"\"\ +< \n :put \" Uninstall:\"\ +< \n :put \" /system/script/run awg2vds-uninstall\"\ +< \n :put \"=========================\"\ +--- +> \n :return (\$EUI64)\ +540,543c2561,2634 +< \n# 7. Verification\ +< \n# /container/print\ +< \n# /interface/wireguard/print\ +< \n# /interface/wireguard/peers/print\ +--- +> \n:global dec2hex do={\ +> \n :local hex \"\"\ +> \n :local dec [:tonum \$1]\ +> \n :for i from=0 to=4 step=4 do={\ +> \n :set hex ([:pick \"0123456789ABCDEF\" ((\$dec>>\$i)&0xf) (((\$de\ +> c>>\$i)&0xf)+1)].\$hex)\ +> \n }\ +> \n :return ([:tostr \$hex])\ +> \n}" +> add comment=Generator dont-require-permissions=no name=proxySet owner=vados \ +> policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \ +> source="# 2. WireGuard interface\r\ +> \n/interface/wireguard/add name=wg-VDSina private-key=\"4CHyNhbOs923/EyNDg\ +> uMXJXdghL2I3UyzXPwrANVgHs=\" listen-port=21641\r\ +> \n/interface/wireguard/peers/add interface=wg-VDSina public-key=\"o5IgCl1/\ +> G6xbl6j7sPaP4ZNYREeYOmqZjKbm+v0b9jU=\" preshared-key=\"RNvF7T1cg5tyXcYQnD9\ +> N5BEp6e20vVJQTv0GMjyvHU0=\" endpoint-address=10.30.30.33 endpoint-port=518\ +> 20 allowed-address=0.0.0.0/0 persistent-keepalive=11\r\ +> \n/ip/address/add address=10.9.0.3/32 interface=wg-VDSina\r\ +> \n\r\ +> \n# 3. DNS\r\ +> \n{ :local rawDNS [/ip/dns/get servers]; :local prevDNS \"\"; :foreach s i\ +> n=[:toarray \$rawDNS] do={ :if ([:len \$prevDNS] > 0) do={ :set prevDNS \"\ +> \$prevDNS,\$s\" } else={ :set prevDNS \$s } }; /system/script/add name=VDS\ +> ina-prev-dns comment=\"\$prevDNS\" source=\"\" }\r\ +> \n/ip/dns/set servers=8.8.4.4\r\ +> \n/ip/route/add dst-address=8.8.4.4/32 gateway=wg-VDSina distance=1 commen\ +> t=VDSina-dns\r\ +> \n\r\ +> \n# 4. Enable WireGuard\r\ +> \n/interface/wireguard/enable wg-VDSina\r\ +> \n" +> add dont-require-permissions=no name=AM-Telegram-Send owner=vados policy=\ +> ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="#\ +> !rsc by Vados\ +> \n# RouterOS script: AM-Telegram-Send\ +> \n# Script comment: Mini script for send messages to admin Telegram chat\ +> \n# Copyright (c) 2007-2026 Vados \ +> \n#\ +> \n#\ +> \n# requires RouterOS, version=7.19\ +> \n# requires device-mode, fetch\ +> \n#\ +> \n# Script description: \ +> \n#\ +> \n#\ +> \n# Usage:\ +> \n# /system/script { run AM-Telegram-Send \"Message here )))\"; }\ +> \n\ +> \n/system/script\ +> \nadd name=telegram-send dont-require-permissions=no source={\ +> \n :global TelegramTokenId;\ +> \n :global TelegramChatId;\ +> \n :local message [:tostr \$1];\ +> \n :local identity [/system/identity/get name];\ +> \n :local sendMsg (\"[\".\$identity.\"] \".\$message)\ +> \n /tool/fetch url=(\"https://api.telegram.org/bot\".\$TelegramTokenId.\\\ +> \n \"/sendMessage\\\?chat_id=\".\$TelegramChatId.\\\ +> \n \"&text=\".\$sendMsg.\\\ +> \n \"&parse_mode=HTML\") \\\ +> \n mode=https keep-result=no\ +> \n}" +> add dont-require-permissions=no name=telegram-send owner=vados policy=\ +> ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="\ +> \n :global TelegramTokenId;\ +> \n :global TelegramChatId;\ +> \n :local message [:tostr \$1];\ +> \n :local identity [/system/identity/get name];\ +> \n :local sendMsg (\"[\".\$identity.\"] \".\$message)\ +> \n /tool/fetch url=(\"https://api.telegram.org/bot\".\$TelegramTokenId.\\\ +> \n \"/sendMessage\\\?chat_id=\".\$TelegramChatId.\\\ +> \n \"&text=\".\$sendMsg.\\\ +> \n \"&parse_mode=HTML\") \\\ +> \n mode=https keep-result=no\ +546,549c2637,2638 +< add name=backup policy="telnet,ssh,ftp,read,write,policy,test,sniff,sensitive,\ +< !local,!reboot,!winbox,!password,!web,!api,!romon,!rest-api" +< add name=manager policy="local,ssh,ftp,read,write,policy,api,rest-api,!telnet,\ +< !reboot,!test,!winbox,!password,!web,!sniff,!sensitive,!romon" +--- +> add name=backup policy="ssh,read,write,policy,test,web,sniff,sensitive,api,res\ +> t-api,!local,!telnet,!ftp,!reboot,!winbox,!password,!romon" +551,555c2640 +< set builtin-trust-store=fetch +< /container config +< set memory-high=200.0MiB +< /disk settings +< set auto-media-interface=Bridge-Lan +--- +> set builtin-trust-store=all crl-download=yes crl-store=system crl-use=yes +557c2642 +< set domain=WORKGROUP enabled=no interfaces=lo +--- +> set enabled=no interfaces=lo +559,564c2644,2650 +< add bridge=Bridge-Lan interface=ether2 +< add bridge=Bridge-Lan interface=ether3 +< add bridge=Bridge-Lan interface=ether4 +< add bridge=Bridge-Lan interface=ether5 +< add bridge=Bridge-Lan interface=wlan1 +< add bridge=Bridge-Lan interface=wlan2 +--- +> add bridge=Bridge-LAN interface=ether5 +> add bridge=Bridge-LAN interface=ether2 +> add bridge=Bridge-LAN interface=ether4 trusted=yes +> add bridge=Bridge-LAN interface=ether3 +> add bridge=Bridge-LAN interface=wlan2 +> add bridge=Bridge-LAN interface=wlan1 +> add bridge=Bridge-LAN disabled=yes interface=Unet-ether1 +566c2652,2654 +< set allow-fast-path=no use-ip-firewall=yes +--- +> set use-ip-firewall=yes +> /ip firewall connection tracking +> set udp-timeout=10s +568c2656 +< set discover-interface-list=LAN +--- +> set discover-interface-list=LAN lldp-med=no lldp-poe-power=no +570c2658,2659 +< set accept-redirects=yes allow-fast-path=no +--- +> set accept-redirects=yes ipv4-multipath-hash-policy=l4 max-neighbor-entries=\ +> 8192 +572,573c2661,2662 +< set accept-router-advertisements-on=none allow-fast-path=no disable-ipv6=yes \ +< disable-link-local-address=yes +--- +> set disable-ipv6=yes disable-link-local-address=yes forward=no \ +> max-neighbor-entries=8192 multipath-hash-policy=l4 +575,576c2664,2669 +< set detect-interface-list=static internet-interface-list=WAN \ +< lan-interface-list=LAN wan-interface-list=WAN +--- +> set detect-interface-list=WAN internet-interface-list=Internet \ +> lan-interface-list=LAN request-interval=1m wan-interface-list=WAN +> /interface l2tp-server server +> set authentication=mschap2 use-ipsec=yes +> /interface list +> add exclude=*2000016,LAN include=*2000017 name=WAN +578,579c2671,2683 +< add interface="ether1 - Unet" list=Internet +< add interface=Bridge-Lan list=LAN +--- +> add interface=lo list=LAN +> add interface=Unet-ether1 list=Internet +> add interface=WG list=WAN +> add interface=Bridge-LAN list=LAN +> /interface wireguard peers +> add allowed-address=0.0.0.0/0 client-allowed-address=::/0 endpoint-address=\ +> 109.107.177.79 endpoint-port=29185 interface=WG name=VDSina \ +> persistent-keepalive=10s public-key=\ +> "zuRsO+dL/j6awaBWZ/NgnHR+bCNUjRWbaHFpdzkNnw4=" +> add allowed-address=0.0.0.0/0 client-allowed-address=::/0 disabled=yes \ +> endpoint-address=10.30.30.33 endpoint-port=55055 interface=wg-nuc name=\ +> NUC persistent-keepalive=11s public-key=\ +> "+OvzAjLC45Td52hjkQPmpGvC3RGhZ+Q2CDMJ1U/D4Rw=" +581,585c2685,2688 +< # +< set bridge=Bridge-Lan caps-man-addresses=10.30.30.10 \ +< caps-man-certificate-common-names=CAPsMAN-ABE2F4E9EE17 certificate=\ +< CAP-18FD746E5814 discovery-interfaces=Bridge-Lan enabled=yes interfaces=\ +< wlan1,wlan2 lock-to-caps-man=yes +--- +> set bridge=Bridge-LAN caps-man-addresses=10.30.30.10 \ +> caps-man-certificate-common-names=CAPsMAN-51B25E507D07 certificate=\ +> CAP-488F5A8E1ABC discovery-interfaces=Bridge-LAN interfaces=wlan2,wlan1 \ +> lock-to-caps-man=yes +587c2690,2691 +< add address=10.30.30.81/24 interface=Bridge-Lan network=10.30.30.0 +--- +> add address=10.30.30.81/24 interface=Bridge-LAN network=10.30.30.0 +> add address=10.8.0.2/24 interface=WG network=10.8.0.0 +589c2693 +< set ddns-enabled=yes +--- +> set update-time=no +591,592c2695,2697 +< add check-gateway=bfd default-route-tables=main:1 dhcp-options=\ +< clientid,clientid_duid interface="ether1 - Unet" name=client1 \ +--- +> add add-default-route=special-classless comment=Unet-client \ +> default-route-distance=2 default-route-tables=main:2 dhcp-options=\ +> hostname,clientid_duid,clientid interface=Unet-ether1 name=UnetDHCP \ +602a2708,2709 +> add address=10.30.30.70 dhcp-option=domain-search-list,HostName \ +> dhcp-option-set=HP1505n mac-address=00:1E:0B:1A:88:8D server=masterDHCP +628a2736,2739 +> add address=10.30.30.95 client-id=1:88:ae:dd:60:39:54 dhcp-option=HostName \ +> dhcp-option-set=VADOS-NUC mac-address=88:AE:DD:60:39:54 server=masterDHCP +> add address=10.30.30.98 client-id=1:c8:5b:76:d8:cc:bf dhcp-option=HostName \ +> dhcp-option-set=VADOS-LEN mac-address=C8:5B:76:D8:CC:BF server=masterDHCP +632a2744,2751 +> add address=10.30.30.30 dhcp-option=HostName dhcp-option-set=miller \ +> mac-address=F0:75:5D:1E:5F:71 server=masterDHCP +> add address=10.30.30.100 client-id=iVados dhcp-option=HostName \ +> dhcp-option-set=iVados mac-address=DE:4D:72:F3:1A:9F server=masterDHCP +> add address=10.30.30.10 allow-dual-stack-queue=yes client-id=\ +> ff:0:0:0:df:0:3:0:1:f0:75:5d:1e:5f:85 dhcp-option=HostName \ +> dhcp-option-set=MikroNUC mac-address=F0:75:5D:1E:5F:85 server=masterDHCP \ +> use-src-mac=yes +634,636c2753,2755 +< add address=10.30.30.0/24 caps-manager=10.30.30.10 dhcp-option=\ +< domain-search-list dhcp-option-set=domain-search-set dns-server=\ +< 10.30.30.81 domain=WORKGROUP gateway=10.30.30.81 netmask=24 ntp-server=\ +--- +> add address=0.0.0.0/24 caps-manager=10.30.30.10 dhcp-option=\ +> domain-search-list dhcp-option-set=domain-search-set dns-server=0.0.0.0 \ +> domain=WORKGROUP gateway=0.0.0.0 netmask=24 ntp-server=\ +637a2757,2758 +> add address=10.30.30.0/24 dns-server=10.30.30.81 gateway=10.30.30.81 netmask=\ +> 24 +639c2760,2762 +< set allow-remote-requests=yes servers=89.110.101.17,10.30.30.33,8.8.4.4 +--- +> set allow-remote-requests=yes cache-max-ttl=1d doh-max-concurrent-queries=100 \ +> doh-max-server-connections=20 servers=10.30.30.33,109.107.177.79 \ +> verify-doh-cert=yes +641,646c2764,2796 +< add address=10.30.30.81 comment=defconf name=router.lan type=A +< add address=10.30.30.81 comment=defconf name=master type=A +< add address=10.30.30.33 comment=amster name=amster.vados.ru type=A +< add address=8.8.8.8 name=dns.google type=A +< add address=8.8.4.4 name=dns.google type=A +< add address=1.0.0.1 comment="CloudFlare-doh IPv4 2" name=\ +--- +> add address=109.107.177.79 comment="VDSina Server DNS" name=ns1.vados.ru \ +> type=A +> add address=109.107.177.79 name=vds.vados.ru type=A +> add comment="Local DNS server for vados.ru" disabled=yes ns=10.30.30.81 \ +> regexp=*.vados.ru type=NS +> add comment="*.vados.ru Regexp" disabled=yes forward-to=10.30.30.81 regexp=\ +> "\".*\\\\.vados\\\\.ru\"" type=FWD +> add comment="*.30.30.10.in-addr.arpa Regexp" disabled=yes forward-to=\ +> 10.30.30.81 regexp="\".*\\\\.30\\\\.30\\\\.10\\\\.in-addr\\\\.arpa" type=\ +> FWD +> add address=10.30.30.81 comment=NS.vados.ru.local disabled=yes name=\ +> ns.vados.ru.local type=A +> add comment="DNS ns.vados.ru.local" disabled=yes match-subdomain=yes name=\ +> vados.ru ns=ns.vados.ru.local type=NS +> add address=10.30.30.33 comment=reg.vados.ru name=reg.vados.ru type=A +> add address=8.8.8.8 comment="Google-dns IPv4 1" match-subdomain=yes name=\ +> dns.google type=A +> add address=8.8.4.4 comment="Google-dns IPv4 2" name=dns.google type=A +> add address=10.30.30.33 comment=AMSTER name=amster.vados.ru type=A +> add address=10.30.30.33 name=ros.vados.ru type=A +> add address=10.30.30.95 name=vados-nuc type=A +> add address=10.30.30.33 name=amster-nuc type=A +> add address=10.30.30.33 name=amster type=A +> add address=10.30.30.33 name=amster-reg type=A +> add address=10.30.30.33 disabled=yes name=mng.vados.ru type=A +> add address=10.30.30.33 name=mgr.vados.ru type=A +> add address=10.30.30.33 name=prt.vados.ru type=A +> add address=10.30.30.33 disabled=yes match-subdomain=yes name=\ +> mikrots.vados.ru type=A +> add address=10.30.30.30 comment=MILLER name=miller.vados.ru type=A +> add address=10.30.30.30 name=MILLER-LEN type=A +> add address=10.30.30.30 name=miller type=A +> add address=1.0.0.1 comment="CloudFlare-doh IPv4 2" disabled=yes name=\ +650,651d2799 +< add address=149.112.112.112 comment="Cuad9-dns IPv4 2" disabled=yes name=\ +< dns.quad9.net type=A +653a2802,2811 +> add address=149.112.112.112 comment="Cuad9-dns IPv4 2" disabled=yes name=\ +> dns.quad9.net type=A +> add address=195.133.25.16 comment="DNS Comss" disabled=yes name=dns.comss.one \ +> type=A +> add address=10.30.30.81 comment=LocalNet name=MikroVados type=A +> add address=10.30.30.10 name=MikroNUC type=A +> add address=10.30.30.86 disabled=yes name=MikroYellow type=A +> add address=10.30.30.85 disabled=yes name=MikroMic type=A +> add address=10.30.30.95 name=VADOS-NUC type=A +> add address=10.30.30.98 name=VADOS-LEN type=A +656,657c2814 +< add address=91.192.189.2 comment=Unet-DNS disabled=yes name=ns1.unet.ws type=\ +< A +--- +> add address=10.30.30.20 disabled=yes name=garage type=A +659,661d2815 +< add address=10.0.0.0/8 list=RFC1918 +< add address=172.16.0.0/12 list=RFC1918 +< add address=192.168.0.0/16 list=RFC1918 +667,677c2821,2907 +< add address=8.8.4.4 disabled=yes list=to_vpn +< add address=10.30.30.98 comment=vados-len list=Local2Vpn +< add address=89.110.101.17 list=VDS +< add address=109.107.177.79 list=TRUSTED +< add address=185.71.70.78 disabled=yes list=TRUSTED +< add address=176.53.203.171 disabled=yes list=TRUSTED +< add address=176.53.203.170 disabled=yes list=TRUSTED +< add address=176.53.202.194 disabled=yes list=TRUSTED +< add address=2ip.ru list=Test +< add address=89.110.101.17 comment=VDSIna list=TRUSTED +< add address=10.8.0.0/24 comment="WG VDSIna" list=TRUSTED +--- +> add address=8.8.4.0/24 list=YouTube +> add address=8.8.8.0/24 list=YouTube +> add address=8.34.208.0/20 list=YouTube +> add address=8.35.192.0/20 list=YouTube +> add address=23.236.48.0/20 list=YouTube +> add address=23.251.128.0/19 list=YouTube +> add address=34.0.0.0/15 list=YouTube +> add address=34.2.0.0/16 list=YouTube +> add address=34.3.0.0/23 list=YouTube +> add address=34.3.3.0/24 list=YouTube +> add address=34.3.4.0/24 list=YouTube +> add address=34.3.8.0/21 list=YouTube +> add address=34.3.16.0/20 list=YouTube +> add address=34.3.32.0/19 list=YouTube +> add address=34.3.64.0/18 list=YouTube +> add address=34.4.0.0/14 list=YouTube +> add address=34.8.0.0/13 list=YouTube +> add address=34.16.0.0/12 list=YouTube +> add address=34.32.0.0/11 list=YouTube +> add address=34.64.0.0/10 list=YouTube +> add address=34.128.0.0/10 list=YouTube +> add address=35.184.0.0/13 list=YouTube +> add address=35.192.0.0/14 list=YouTube +> add address=35.196.0.0/15 list=YouTube +> add address=35.198.0.0/16 list=YouTube +> add address=35.199.0.0/17 list=YouTube +> add address=35.199.128.0/18 list=YouTube +> add address=35.200.0.0/13 list=YouTube +> add address=35.208.0.0/12 list=YouTube +> add address=35.224.0.0/12 list=YouTube +> add address=35.240.0.0/13 list=YouTube +> add address=57.140.192.0/18 list=YouTube +> add address=64.15.112.0/20 list=YouTube +> add address=64.233.160.0/19 list=YouTube +> add address=66.22.228.0/23 list=YouTube +> add address=66.102.0.0/20 list=YouTube +> add address=66.249.64.0/19 list=YouTube +> add address=70.32.128.0/19 list=YouTube +> add address=72.14.192.0/18 list=YouTube +> add address=74.125.0.0/16 list=YouTube +> add address=104.154.0.0/15 list=YouTube +> add address=104.196.0.0/14 list=YouTube +> add address=104.237.160.0/19 list=YouTube +> add address=107.167.160.0/19 list=YouTube +> add address=107.178.192.0/18 list=YouTube +> add address=108.59.80.0/20 list=YouTube +> add address=108.170.192.0/18 list=YouTube +> add address=108.177.0.0/17 list=YouTube +> add address=130.211.0.0/16 list=YouTube +> add address=136.22.160.0/20 list=YouTube +> add address=136.22.176.0/21 list=YouTube +> add address=136.22.184.0/23 list=YouTube +> add address=136.22.186.0/24 list=YouTube +> add address=142.250.0.0/15 list=YouTube +> add address=146.148.0.0/17 list=YouTube +> add address=152.65.208.0/22 list=YouTube +> add address=152.65.214.0/23 list=YouTube +> add address=152.65.218.0/23 list=YouTube +> add address=152.65.222.0/23 list=YouTube +> add address=152.65.224.0/19 list=YouTube +> add address=162.120.128.0/17 list=YouTube +> add address=162.216.148.0/22 list=YouTube +> add address=162.222.176.0/21 list=YouTube +> add address=172.110.32.0/21 list=YouTube +> add address=172.217.0.0/16 list=YouTube +> add address=172.253.0.0/16 list=YouTube +> add address=173.194.0.0/16 list=YouTube +> add address=173.255.112.0/20 list=YouTube +> add address=192.158.28.0/22 list=YouTube +> add address=192.178.0.0/15 list=YouTube +> add address=193.186.4.0/24 list=YouTube +> add address=199.36.154.0/23 list=YouTube +> add address=199.36.156.0/24 list=YouTube +> add address=199.192.112.0/22 list=YouTube +> add address=199.223.232.0/21 list=YouTube +> add address=207.223.160.0/20 list=YouTube +> add address=208.65.152.0/22 list=YouTube +> add address=208.68.108.0/22 list=YouTube +> add address=208.81.188.0/22 list=YouTube +> add address=208.117.224.0/19 list=YouTube +> add address=209.85.128.0/17 list=YouTube +> add address=216.58.192.0/19 list=YouTube +> add address=216.73.80.0/20 list=YouTube +> add address=216.239.32.0/19 list=YouTube +> add address=2ip.ru list=Test-IP +> add address=wg.vados.ru comment=VDSIna list=TRUSTED +> add address=10.8.0.0/24 comment="WG VDSIna" disabled=yes list=TRUSTED +682,691c2912,2918 +< add address=vdsina.com comment=vdsina.com list=NoVdsina +< add address=vdsina.ru comment=vdsina.ru list=NoVdsina +< add address=youla.ru comment=youla.ru list=NoVdsina +< add address=kupiprodai.ru comment=kupiprodai.ru list=NoVdsina +< add address=myip.ru list=Test +< add address=geoip.co comment=geoip.co list=NoVdsina +< add address=x.com list=Twitter +< add address=facebook.com list=facebook +< add address=fbcd.net list=facebook +< add address=comp-lenta.ru comment=comp-lenta.ru list=NoVdsina +--- +> add address=vdsina.com list=NoVdsina +> add address=vdsina.ru list=NoVdsina +> add address=youla.ru list=NoVdsina +> add address=kupiprodai.ru list=NoVdsina +> add address=myip.ru list=Test-IP +> add address=geoip.co list=NoVdsina +> add address=comp-lenta.ru list=NoVdsina +882,884d3108 +< add address=82.202.162.184 comment=comp-lenta.ru list=NoWG +< add address=smtp.mail.me.com.akadns.net. comment=smtp.mail.me.com list=NoWG +< add address=17.57.155.37 comment=smtp.mail.me.com.akadns.net list=NoWG +1087c3311 +< add address=10.30.30.33 comment=NUC disabled=yes list=NoWG +--- +> add address=10.30.30.33 comment=amster list=NoWG +1090c3314 +< add address=wg.vados.ru comment=VDSina-vpn list=Trusted-VPN +--- +> add address=wg.vados.ru comment=VDSina-vpn list=VDSina +1098c3322 +< add address=vdsina.vados.ru comment="!!!VDSina Server!!!" list=NoVdsina +--- +> add address=89.110.101.17 comment="!!!VDSina Server!!!" list=NoVdsina +1111,1140c3335,3356 +< add address=cp.vdsina.com comment=VDSina-vpn list=Trusted-VPN +< add address=vdsina.ru comment=VDSina-vpn list=Trusted-VPN +< add address=ns.vados.ru comment=VDSina-vpn list=Trusted-VPN +< add address=vdsina.com comment=VDSina-vpn list=Trusted-VPN +< add address=cp.vdsina.ru comment=VDSina-vpn list=Trusted-VPN +< add address=ns1.vdsina.ru comment=VDSina-vpn list=Trusted-VPN +< add address=ghcr.io comment=GitHub list=Trusted-VPN +< add address=github.com comment=GitHub list=Trusted-VPN +< add address=149.154.164.13 comment=telegra.ph list=FuckRKN +< add address=194.85.61.76 comment=grani.ru list=FuckRKN +< add address=109.70.26.37 comment=grani.ru list=FuckRKN +< add address=104.16.4.81 comment=xhamster.com list=FuckRKN +< add address=104.16.3.81 comment=xhamster.com list=FuckRKN +< add address=188.114.96.1 comment=lostfilm.tv list=FuckRKN +< add address=188.114.97.1 comment=lostfilm.tv list=FuckRKN +< add address=172.67.182.196 comment=rutracker.org list=FuckRKN +< add address=104.21.32.39 comment=rutracker.org list=FuckRKN +< add address=104.247.81.99 comment=lurkmore.to list=FuckRKN +< add address=8.47.69.6 comment=dou.ua list=FuckRKN +< add address=8.6.112.6 comment=dou.ua list=FuckRKN +< add address=66.254.114.79 comment=youporn.com list=FuckRKN +< add address=185.110.92.40 comment=pornolab.net list=FuckRKN +< add address=185.110.92.41 comment=pornolab.net list=FuckRKN +< add address=104.21.71.238 comment=crimerussia.com list=FuckRKN +< add address=172.67.172.95 comment=crimerussia.com list=FuckRKN +< add address=149.154.167.99 comment=telegram.org list=FuckRKN +< add address=149.154.166.110 comment=api.telegram.org list=FuckRKN +< add address=myip.ru comment="!!! Check IP (MYIP.RU) !!!" disabled=yes list=\ +< NoVdsina +< add address=ipinfo.io comment="!!! Check IP (IPINFO.IO) !!!" list=NoVdsina +--- +> add address=cp.vdsina.com comment=VDSina-vpn list=VDSina +> add address=vdsina.ru comment=VDSina-vpn list=VDSina +> add address=ns.vados.ru comment=VDSina-vpn list=VDSina +> add address=vdsina.com comment=VDSina-vpn list=VDSina +> add address=cp.vdsina.ru comment=VDSina-vpn list=VDSina +> add address=ns1.vdsina.ru comment=VDSina-vpn list=VDSina +> add address=10.30.30.0/24 comment="Local Network" list=Local-Net +> add address=10.8.0.0/24 comment="WireGuard Network" list=Local-Net +> add address=146.120.64.208/29 comment="External Net" list=Unet +> add address=esia.gosuslugi.ru comment=esia.gosuslugi.ru list=NoVdsina +> add address=lk.gosuslugi.ru comment=lk.gosuslugi.ru list=NoVdsina +> add address=trudvsem.ru comment=trudvsem.ru list=NoVdsina +> add address=10.30.30.30 comment=miller disabled=yes list=NoWG +> add address=10.30.30.33 comment="Direct connet to DNS servers" list=\ +> Direct-DNS +> add address=109.107.177.79 list=VPN-Server +> add address=10.0.0.0/8 list=RFC1918 +> add address=172.16.0.0/12 list=RFC1918 +> add address=192.168.0.0/16 list=RFC1918 +> add address=8.8.4.4 disabled=yes list=to_vpn +> add address=myip.ru disabled=yes list=to_vpn +> add address=10.30.30.98 disabled=yes list=to_vpn +1142,1172c3358,3370 +< add action=add-src-to-address-list address-list="Honeypot Hacker" \ +< address-list-timeout=12h chain=input comment="block honeypot DNS UDP" \ +< connection-state=new dst-port=53 in-interface="ether1 - Unet" protocol=\ +< udp src-address-list=!VDS +< add action=add-src-to-address-list address-list="Honeypot Hacker" \ +< address-list-timeout=4w2d chain=input comment="block honeypot DNS TCP" \ +< connection-state=new dst-port=53 in-interface="ether1 - Unet" protocol=\ +< tcp src-address-list=!VDS +< add action=add-src-to-address-list address-list="Honeypot Hacker" \ +< address-list-timeout=4w2d chain=input comment="block honeypot NTP" \ +< connection-state=new dst-port=123 in-interface="ether1 - Unet" protocol=\ +< udp +< add action=add-src-to-address-list address-list="Honeypot Hacker" \ +< address-list-timeout=4w2d chain=input comment="block honeypot asterisk" \ +< connection-state=new dst-port=5060 in-interface="ether1 - Unet" protocol=\ +< udp +< add action=add-src-to-address-list address-list="Honeypot Hacker" \ +< address-list-timeout=4w2d chain=input comment=\ +< "block honeypot ssh rdp winbox" connection-state=new dst-port=22,8291 \ +< in-interface-list=WAN protocol=tcp src-address-list=!TRUSTED +< add action=accept chain=input comment=\ +< "defconf: accept established,related,untracked" connection-state=\ +< established,related,untracked +< add action=drop chain=input comment="defconf: drop invalid" connection-state=\ +< invalid +< add action=accept chain=input comment="defconf: accept ICMP" protocol=icmp +< add action=accept chain=input comment=\ +< "defconf: accept to local loopback (for CAPsMAN)" disabled=yes \ +< dst-address=127.0.0.1 in-interface=lo src-address=127.0.0.1 +< add action=drop chain=input comment="defconf: drop all not coming from LAN" \ +< in-interface-list=!LAN +--- +> add action=fasttrack-connection chain=forward comment=\ +> "FastTrack for non-VPN connections" connection-mark=!VPN_No_FastTrack \ +> connection-state=established,related,new disabled=yes +> add action=accept chain=output comment="accept WireGuard" disabled=yes \ +> dst-address-list=VPN-Server out-interface=Unet-ether1 protocol=udp \ +> src-port=13231 +> add action=accept chain=output dst-address-list=VPN-Server dst-port=29185 \ +> out-interface=Unet-ether1 protocol=udp +> add action=fasttrack-connection chain=forward comment="defconf: fasttrack" \ +> connection-state=established,related,new disabled=yes routing-mark=\ +> !To-VPN +> add action=accept chain=output disabled=yes protocol=tcp src-port=443 +> add action=accept chain=output disabled=yes src-address=127.0.0.1 +1179c3377 +< established,related,untracked +--- +> established,related,untracked disabled=yes +1181c3379,3380 +< connection-state=invalid +--- +> connection-state=invalid in-interface=Unet-ether1 src-address=\ +> !10.30.30.0/24 +1184c3383,3387 +< in-interface-list=WAN +--- +> connection-state=new in-interface=Unet-ether1 src-address-list=!VDSina +> add action=accept chain=input protocol=icmp +> add action=accept chain=input connection-state=established +> add action=accept chain=input connection-state=related +> add action=drop chain=input in-interface-list=!LAN +1186,1192c3389,3424 +< add action=accept chain=prerouting dst-address-list=RFC1918 \ +< in-interface-list=!WAN +< add action=mark-connection chain=prerouting comment="NO VPN" disabled=yes \ +< dst-address-list=NoVdsina in-interface-list=!WAN new-connection-mark=\ +< To-ISP +< add action=mark-routing chain=prerouting comment=All2vpn connection-mark=\ +< !To-ISP disabled=yes dst-address=!89.110.101.17 dst-address-list=\ +--- +> add action=accept chain=prerouting comment=RFC1918 dst-address-list=RFC1918 \ +> in-interface-list=!LAN +> add action=mark-connection chain=prerouting comment=\ +> "Mark connection \"no-mark\" to NoWG" new-connection-mark=no-mark \ +> src-address-list=NoWG +> add action=mark-connection chain=prerouting comment=\ +> "Mark connection \"no-mark\" to NoVdsina" dst-address-list=NoVdsina \ +> new-connection-mark=no-mark src-address=10.30.30.0/24 +> add action=mark-connection chain=prerouting comment=\ +> "Transit for address-list \"to_vpn\"" connection-mark=!no-mark disabled=\ +> yes dst-address-list=to_vpn new-connection-mark=to-vpn-conn routing-mark=\ +> To-VPN +> add action=mark-routing chain=prerouting comment=\ +> "Find routing over table r_to_vpn" connection-mark=to-vpn-conn disabled=\ +> yes in-interface-list=!LAN new-routing-mark=*401 +> add action=mark-connection chain=prerouting comment=\ +> "Mark connection \"no-mark\" to VDSina" dst-address-list=VPN-Server \ +> new-connection-mark=no-mark passthrough=no src-address=10.30.30.0/24 +> add action=mark-connection chain=prerouting comment=\ +> "Mark Routing main for MikroNuc" disabled=yes dst-address-list=AWG-Proxy \ +> new-connection-mark=no-mark src-address=10.30.30.0/24 +> add action=mark-routing chain=prerouting comment=\ +> "!!!ERROR Mark Routing main for Unet!!!" disabled=yes dst-address-list=\ +> Unet new-routing-mark=main passthrough=no +> add action=mark-routing chain=prerouting comment="Test-IP sites" disabled=yes \ +> dst-address=!10.30.30.0/24 dst-address-list=Test-IP new-routing-mark=\ +> To-VPN src-address=10.30.30.0/24 +> add action=mark-routing chain=prerouting comment=FuckRKN disabled=yes \ +> dst-address=!10.30.30.0/24 dst-address-list=RKN-dnsLookup \ +> new-routing-mark=To-VPN passthrough=no src-address=10.30.30.0/24 +> add action=change-mss chain=forward comment="MSS on WG (1380)" \ +> connection-mark=!no-mark dst-address=!10.30.30.0/24 new-mss=1380 \ +> out-interface=WG protocol=tcp routing-mark=To-VPN src-address=\ +> 10.30.30.0/24 tcp-flags=syn tcp-mss=1381-65535 +> add action=mark-routing chain=prerouting comment="WG for all" \ +> connection-mark=!no-mark dst-address=!10.30.30.0/24 dst-address-list=\ +1195,1200d3426 +< add action=change-mss chain=forward comment="MSS on WG" connection-mark=\ +< !To-ISP disabled=yes in-interface-list=!WAN new-mss=1380 protocol=tcp \ +< tcp-flags=syn tcp-mss=1381-65535 +< add action=mark-routing chain=prerouting connection-mark=to-vpn-conn \ +< disabled=yes new-routing-mark=To-VPN routing-mark=To-VPN src-address=\ +< 10.30.30.0/24 +1202,1207c3428,3431 +< "Mark VPN connections to exclude from FastTrack" disabled=yes \ +< in-interface=*B log-prefix=Mark-VPN-FT new-connection-mark=\ +< VPN_No_FastTrack +< add action=accept chain=prerouting comment="SSH To ME" disabled=yes \ +< dst-address=10.30.30.81 dst-port=2222 in-interface-list=!WAN protocol=tcp \ +< src-address=10.30.30.0/24 +--- +> "Mark VPN connections to exclude from FastTrack" connection-mark=!no-mark \ +> disabled=yes dst-address-list=!NoVdsina new-connection-mark=\ +> VPN_No_FastTrack routing-mark=To-VPN src-address=10.30.30.0/24 \ +> src-address-list=!NoWG +1209,1210c3433,3438 +< dst-address=10.8.0.0/24 log-prefix=VPN-Net new-routing-mark=To-VPN \ +< src-address=10.30.30.0/24 +--- +> dst-address=10.8.0.0/24 new-routing-mark=To-VPN src-address=10.30.30.0/24 +> add action=mark-connection chain=output comment="For this router" \ +> connection-mark=no-mark dst-address-list=to_vpn new-connection-mark=\ +> to-vpn-conn-local +> add action=mark-routing chain=output comment="For this router" \ +> connection-mark=to-vpn-conn-local new-routing-mark=*401 +1211a3440,3460 +> add action=redirect chain=dstnat comment="udp Redirect DNS in NAT" disabled=\ +> yes dst-port=53 protocol=udp src-address=10.30.30.0/24 src-address-list=\ +> !NoWG to-addresses=10.30.30.33 to-ports=53 +> add action=redirect chain=dstnat comment="tcp Redirect DNS in NAT" disabled=\ +> yes dst-port=53 protocol=tcp src-address=10.30.30.0/24 src-address-list=\ +> !NoWG to-addresses=10.30.30.33 to-ports=53 +> add action=masquerade chain=srcnat comment=\ +> "Nat Addresses for routing mark r_to_vpn" disabled=yes routing-mark=*401 +> add action=dst-nat chain=dstnat comment=\ +> "53/tcp dst-nat to amster.loc. From VDSina Server" dst-port=53 \ +> in-interface=Unet-ether1 protocol=tcp src-address-list=VPN-Server \ +> to-addresses=10.30.30.33 to-ports=53 +> add action=dst-nat chain=dstnat comment=\ +> "53/udp dst-nat to amster.loc. From VDSina Server" dst-port=53 protocol=\ +> udp src-address-list=VPN-Server to-addresses=10.30.30.33 to-ports=53 +> add action=dst-nat chain=dstnat disabled=yes dst-port=44333 in-interface=\ +> Unet-ether1 protocol=udp src-address=!10.30.30.0/24 to-addresses=\ +> 10.30.30.33 to-ports=44333 +> add action=masquerade chain=srcnat comment=WG disabled=yes dst-address=\ +> !10.30.30.0/24 dst-address-list=!NoVdsina out-interface=WG routing-mark=\ +> To-VPN src-address=10.30.30.0/24 src-address-list=!NoWG +1213,1224c3462,3492 +< !10.30.30.0/24 ipsec-policy=out,none out-interface="ether1 - Unet" \ +< routing-mark=!To-VPN src-address=10.30.30.0/24 +< add action=masquerade chain=srcnat comment="NAT for VPN" disabled=yes \ +< out-interface=lo routing-mark=To-VPN +< add action=dst-nat chain=dstnat comment="dst-nat for acme" dst-port=80 \ +< in-interface="ether1 - Unet" protocol=tcp to-addresses=10.30.30.33 \ +< to-ports=80 +< add action=dst-nat chain=dstnat comment="dst-nat for amster HTTPS" dst-port=\ +< 443 in-interface="ether1 - Unet" protocol=tcp to-addresses=10.30.30.33 \ +< to-ports=443 +< add action=dst-nat chain=dstnat comment="dst-nat for amster ssh" disabled=yes \ +< dst-port=22 protocol=tcp src-address-list=VDS to-addresses=10.30.30.33 \ +--- +> !10.30.30.0/24 out-interface=Unet-ether1 routing-mark=!To-VPN \ +> src-address=10.30.30.0/24 +> add action=dst-nat chain=dstnat disabled=yes dst-port=44044 in-interface=\ +> Unet-ether1 protocol=udp src-address=109.107.177.79 to-addresses=\ +> 10.30.30.33 to-ports=44044 +> add action=dst-nat chain=dstnat comment=amster.vados.ruhttps dst-port=443 \ +> fragment=no in-interface=Unet-ether1 protocol=tcp routing-mark=main \ +> to-addresses=10.30.30.33 to-ports=443 +> add action=dst-nat chain=dstnat comment="amster.vados.ru For Certbot HTTP" \ +> dst-port=80 in-interface=Unet-ether1 protocol=tcp to-addresses=\ +> 10.30.30.33 to-ports=80 +> add action=dst-nat chain=dstnat comment="amster.vados.ru 3x-ui" disabled=yes \ +> dst-port=2904 in-interface=Unet-ether1 protocol=tcp to-addresses=\ +> 10.30.30.33 to-ports=2904 +> add action=dst-nat chain=dstnat comment=reg.vados.ru disabled=yes dst-port=\ +> 5000 in-interface=Unet-ether1 protocol=tcp to-addresses=10.30.30.33 \ +> to-ports=5000 +> add action=dst-nat chain=dstnat comment="Docker swarm" disabled=yes dst-port=\ +> 2377 in-interface=Unet-ether1 protocol=tcp to-addresses=10.30.30.33 \ +> to-ports=2377 +> add action=dst-nat chain=dstnat comment=npm dst-port=81 in-interface=\ +> Unet-ether1 protocol=tcp routing-mark=To-VPN to-addresses=10.30.30.33 \ +> to-ports=81 +> add action=dst-nat chain=dstnat comment=SSH dst-port=22 in-interface=\ +> Unet-ether1 protocol=tcp src-address-list=TRUSTED to-addresses=\ +> 10.30.30.33 to-ports=22 +> add action=dst-nat chain=dstnat comment="portainer agent" disabled=yes \ +> dst-port=2377 in-interface=Unet-ether1 protocol=tcp to-addresses=\ +> 10.30.30.33 to-ports=2377 +> add action=dst-nat chain=dstnat disabled=yes dst-port=22 in-interface=\ +> Unet-ether1 protocol=tcp routing-mark=!To-VPN to-addresses=10.30.30.33 \ +1226,1231c3494,3562 +< add action=dst-nat chain=dstnat comment="dst-nat for amster DNS (TCP)" \ +< dst-port=53 in-interface="ether1 - Unet" protocol=tcp src-address-list=\ +< VDS to-addresses=10.30.30.33 to-ports=53 +< add action=dst-nat chain=dstnat comment="dst-nat for amster DNS (UDP)" \ +< dst-port=53 in-interface="ether1 - Unet" protocol=udp src-address-list=\ +< VDS to-addresses=10.30.30.33 to-ports=53 +--- +> add action=dst-nat chain=dstnat comment="Yandex.DNS Family" disabled=yes \ +> dst-port=53 in-interface=Bridge-LAN protocol=udp src-address-list=KIDS \ +> time=6h-15m,sun,mon,tue,wed,thu,fri,sat to-addresses=77.88.8.3 +> add action=dst-nat chain=dstnat disabled=yes dst-port=53 in-interface=\ +> Bridge-LAN protocol=tcp src-address-list=KIDS time=\ +> 6h-15m,sun,mon,tue,wed,thu,fri,sat to-addresses=77.88.8.3 +> /ip firewall raw +> add action=drop chain=prerouting comment="Drop Honeypot Hackers" \ +> in-interface=Unet-ether1 src-address-list="Honeypot Hacker" +> add action=accept chain=prerouting comment="Trusted DNS" disabled=yes \ +> in-interface-list=*2000012 src-address-list=Trusted-DNS +> add action=add-dst-to-address-list address-list=NoVdsina \ +> address-list-timeout=none-dynamic chain=prerouting comment=\ +> extras.getpagespeed.com content=extras.getpagespeed.com disabled=yes +> add action=add-dst-to-address-list address-list=NoVdsina \ +> address-list-timeout=none-dynamic chain=prerouting comment=linux.duke.edu \ +> content=linux.duke.edu disabled=yes +> add action=add-dst-to-address-list address-list=FuckRKN address-list-timeout=\ +> none-dynamic chain=prerouting comment="YouTube raw" content=youtube.com \ +> disabled=yes +> add action=add-dst-to-address-list address-list=FuckRKN address-list-timeout=\ +> none-dynamic chain=prerouting comment="YouTube raw" content=\ +> googleapis.com disabled=yes +> add action=add-dst-to-address-list address-list=FuckRKN address-list-timeout=\ +> none-dynamic chain=prerouting comment="YouTube raw" content=ggpht.com \ +> disabled=yes +> add action=add-dst-to-address-list address-list=FuckRKN address-list-timeout=\ +> none-dynamic chain=prerouting comment="YouTube raw" content=youtu.be \ +> disabled=yes +> add action=add-dst-to-address-list address-list=FuckRKN address-list-timeout=\ +> none-dynamic chain=prerouting comment="YouTube raw" content=ytimg.com \ +> disabled=yes +> add action=add-dst-to-address-list address-list=FuckRKN address-list-timeout=\ +> none-dynamic chain=prerouting comment="YouTube raw" content=\ +> googlevideo.com disabled=yes +> add action=add-dst-to-address-list address-list=FuckRKN address-list-timeout=\ +> none-dynamic chain=prerouting comment="YouTube raw" content=gstatic.com \ +> disabled=yes +> add action=add-dst-to-address-list address-list=FuckRKN address-list-timeout=\ +> none-dynamic chain=prerouting comment="YouTube raw" content=\ +> googleusercontent.com disabled=yes +> add action=add-dst-to-address-list address-list=FuckRKN address-list-timeout=\ +> none-dynamic chain=prerouting comment="YouTube raw" content=\ +> nhacmp3youtube.com disabled=yes +> add action=add-dst-to-address-list address-list=NoVdsina \ +> address-list-timeout=none-dynamic chain=prerouting comment=rutube.ru \ +> content=rutube.ru disabled=yes +> add action=add-dst-to-address-list address-list=NoVdsina \ +> address-list-timeout=none-dynamic chain=prerouting comment="me.com raw" \ +> content=me.com disabled=yes +> add action=add-dst-to-address-list address-list=NoVdsina \ +> address-list-timeout=none-dynamic chain=prerouting comment=\ +> "icloud.com raw" content=icloud.com disabled=yes +> add action=add-dst-to-address-list address-list=NoVdsina \ +> address-list-timeout=none-dynamic chain=prerouting comment=\ +> "smtp.mail.me.com raw" content=smtp.mail.me.com disabled=yes +> add action=add-dst-to-address-list address-list=NoVdsina \ +> address-list-timeout=none-dynamic chain=prerouting comment=\ +> "smtp.mail.me.com.akadns.net raw" content=smtp.mail.me.com.akadns.net \ +> disabled=yes +> add action=add-dst-to-address-list address-list=NoVdsina \ +> address-list-timeout=none-dynamic chain=prerouting comment=\ +> "api.db-ip.com raw" content=api.db-ip.com disabled=yes +> add action=add-dst-to-address-list address-list=NoVdsina \ +> address-list-timeout=none-dynamic chain=prerouting comment=\ +> esia.gosuslugi.ru content=esia.gosuslugi.ru disabled=yes +> add action=add-dst-to-address-list address-list=NoVdsina \ +> address-list-timeout=none-dynamic chain=prerouting comment=gosuslugi.ru \ +> content=gosuslugi.ru disabled=yes +1239,1240c3570,3578 +< /ip hotspot user profile +< set [ find default=yes ] address-pool=dhcp +--- +> /ip ipsec settings +> set accounting=no +> /ip ipsec policy +> set 0 disabled=yes dst-address=0.0.0.0/0 src-address=0.0.0.0/0 +> /ip ipsec profile +> set [ find default=yes ] dpd-interval=2m dpd-maximum-failures=5 +> /ip proxy +> set cache-administrator="" max-cache-size=none port=80,443 src-address=\ +> 0.0.0.0 +1242,1247c3580,3581 +< add check-gateway=ping disabled=yes distance=1 dst-address=10.10.10.0/24 \ +< gateway=10.30.30.33 routing-table=main scope=30 target-scope=10 +< add comment=awg2all-dns disabled=yes distance=1 dst-address=10.9.0.1/32 \ +< gateway="" +< add comment=awg2all-dns disabled=yes distance=1 dst-address=8.8.4.4/32 \ +< gateway="" +--- +> add check-gateway="(unknown)" disabled=no distance=1 dst-address=0.0.0.0/0 \ +> gateway=WG routing-table=To-VPN scope=30 target-scope=10 +1251d3584 +< set www disabled=yes port=188 +1253,1255c3586,3591 +< set ssh port=2222 +< set api disabled=yes +< set api-ssl disabled=yes +--- +> set ssh address=10.30.30.0/24 port=2222 +> set www disabled=yes port=8080 +> set winbox address=10.30.30.0/24 +> set api address=10.30.30.0/24 +> set api-ssl address=10.30.30.0/24 disabled=yes +> set www-ssl certificate=*15 port=18443 +1261,1262c3597 +< set forwarding-enabled=both publickey-authentication-options=verify-required \ +< strong-crypto=yes +--- +> set forwarding-enabled=both publickey-authentication-options=verify-required +1266c3601,3622 +< add interface="ether1 - Unet" type=external +--- +> add interface=Bridge-LAN type=internal +> add forced-ip=146.120.64.211 interface=Unet-ether1 type=external +> add forced-ip=109.107.177.79 interface=*E type=external +> add interface=lo type=internal +> add interface=wlan2 type=internal +> add interface=wlan1 type=internal +> /ipv6 dhcp-client +> add add-default-route=yes disabled=yes interface=*F rapid-commit=no request=\ +> info use-interface-duid=yes validate-server-duid=no +> /ipv6 dhcp-server option sets +> add name=domain-search-set options=domain-search-list +> add name="=\"Client ID\"" options=HostName +> /ipv6 firewall address-list +> add address=::/128 comment="defconf: unspecified address" list=bad_ipv6 +> add address=::1/128 comment="defconf: lo" list=bad_ipv6 +> add address=fec0::/10 comment="defconf: site-local" list=bad_ipv6 +> add address=::ffff:0.0.0.0/96 comment="defconf: ipv4-mapped" list=bad_ipv6 +> add address=::/96 comment="defconf: ipv4 compat" list=bad_ipv6 +> add address=100::/64 comment="defconf: discard only " list=bad_ipv6 +> add address=2001:db8::/32 comment="defconf: documentation" list=bad_ipv6 +> add address=2001:10::/28 comment="defconf: ORCHID" list=bad_ipv6 +> add address=3ffe::/16 comment="defconf: 6bone" list=bad_ipv6 +1270c3626 +< established,related,untracked disabled=yes +--- +> established,related,untracked +1272,1274c3628,3630 +< invalid disabled=yes +< add action=accept chain=input comment="defconf: accept ICMPv6" disabled=yes \ +< protocol=icmpv6 +--- +> invalid +> add action=accept chain=input comment="defconf: accept ICMPv6" protocol=\ +> icmpv6 +1276c3632 +< disabled=yes dst-port=33434-33534 protocol=udp +--- +> dst-port=33434-33534 protocol=udp +1278,1285c3634,3641 +< "defconf: accept DHCPv6-Client prefix delegation." disabled=yes dst-port=\ +< 546 protocol=udp src-address=fe80::/10 +< add action=accept chain=input comment="defconf: accept IKE" disabled=yes \ +< dst-port=500,4500 protocol=udp +< add action=accept chain=input comment="defconf: accept ipsec AH" disabled=yes \ +< protocol=ipsec-ah +< add action=accept chain=input comment="defconf: accept ipsec ESP" disabled=\ +< yes protocol=ipsec-esp +--- +> "defconf: accept DHCPv6-Client prefix delegation." dst-port=546 protocol=\ +> udp src-address=fe80::/10 +> add action=accept chain=input comment="defconf: accept IKE" dst-port=500,4500 \ +> protocol=udp +> add action=accept chain=input comment="defconf: accept ipsec AH" protocol=\ +> ipsec-ah +> add action=accept chain=input comment="defconf: accept ipsec ESP" protocol=\ +> ipsec-esp +1287,1288c3643 +< "defconf: accept all that matches ipsec policy" disabled=yes \ +< ipsec-policy=in,ipsec +--- +> "defconf: accept all that matches ipsec policy" ipsec-policy=in,ipsec +1290,1293c3645,3646 +< "defconf: drop everything else not coming from LAN" disabled=yes \ +< in-interface-list=!LAN +< add action=fasttrack-connection chain=forward comment="defconf: fasttrack6" \ +< connection-state=established,related +--- +> "defconf: drop everything else not coming from LAN" in-interface-list=\ +> !LAN +1318a3672,3684 +> /ipv6 nd +> set [ find default=yes ] advertise-dns=yes disabled=yes interface=Bridge-LAN \ +> managed-address-configuration=yes other-configuration=yes pref64=::/64 +> /ipv6 nd prefix +> add autonomous=no disabled=yes interface=Bridge-LAN on-link=no prefix=none +> /ipv6 nd prefix default +> set dhcp6-pd-preferred=yes +> /ipv6 nd proxy +> add disabled=yes interface=lo +> /ipv6 nd settings +> set router-advertisement-route-distance=100 +> /routing settings +> set single-process=no +1320c3686,3688 +< set time-zone-autodetect=no time-zone-name=Europe/Moscow +--- +> set time-zone-name=Europe/Moscow +> /system clock manual +> set time-zone=+03:00 +1322a3691,3693 +> /system logging +> add action=email disabled=yes regex="* added|changed|removed *" topics=\ +> system,info +1327a3699,3702 +> add address=0.ru.pool.ntp.org +> add address=1.ru.pool.ntp.org +> add address=2.ru.pool.ntp.org +> add address=3.ru.pool.ntp.org +1328a3704,3705 +> /system package update +> set check-certificate=yes-without-crl ip-version=ipv4 +1338a3716,3721 +> add comment="Update RKN DNS Looup" disabled=yes interval=20m name=\ +> AM-RKN-dnsLookup on-event="/system/script { run AM-RKN-dnsLookup; }" \ +> policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \ +> start-time=startup +> /system watchdog +> set watchdog-timer=no +1341a3725,3728 +> /tool mac-server +> set allowed-interface-list=LAN +> /tool mac-server mac-winbox +> set allowed-interface-list=LAN +1343,1362c3730,3822 +< add comment="doh-fallback, doh-url=https://security.cloudflare-dns.com/dns-que\ +< ry, doh-cert=DigiCert Global Root CA, notify, name=CloudFlare-doh IPv4 1" \ +< disabled=yes host=1.1.1.1 type=simple +< add comment="doh, doh-url=https://security.cloudflare-dns.com/dns-query, doh-c\ +< ert=DigiCert Global Root CA, notify, name=CloudFlare-doh IPv4 2" \ +< disabled=yes host=1.0.0.1 type=simple +< add comment="doh-fallback, dns-fallback, doh-url=https://dns.google/dns-query,\ +< \_doh-cert=DigiCert Global Root G2, notify, name=Google-doh IPv4 1" \ +< disabled=yes host=8.8.8.8 type=simple +< add comment="doh-fallback, dns-fallback, doh-url=https://dns.google/dns-query,\ +< \_doh-cert=DigiCert Global Root G2, notify, name=Google-doh IPv4 2" \ +< disabled=yes host=8.8.4.4 type=simple +< add comment="doh-fallback, dns-fallback, doh-url=https://dns.quad9.net/dns-que\ +< ry, doh-cert=DigiCert Global Root G3, notify, name=Cuad9-doh IPv4 1" \ +< disabled=yes host=9.9.9.9 type=simple +< add comment="doh-fallback, dns-fallback, doh-url=https://dns.quad9.net/dns-que\ +< ry, doh-cert=DigiCert Global Root G3, notify, name=Cuad9-doh IPv4 2" \ +< disabled=yes host=149.112.112.112 type=simple +< add comment="dns, notify, name=ns1.unet.ws" disabled=yes host=91.192.189.2 \ +< type=simple +--- +> add certificate=DigiCert-Global-Root-CA check-certificate=no comment="doh, doh\ +> -url=https://security.cloudflare-dns.com/dns-query, notify, name=CloudFlar\ +> e-doh IPv4 1" disabled=yes down-script="" host=1.1.1.1 http-codes="" \ +> interval=10s name="CloudFlare-doh IPv4 1" port=443 test-script="" type=\ +> https-get up-script="" +> add check-certificate=no comment="doh-fallback, doh-url=https://security.cloud\ +> flare-dns.com/dns-query, doh-cert=DigiCert Global Root CA, notify, name=Cl\ +> oudFlare-doh IPv4" disabled=yes down-script="" host=1.0.0.1 http-codes="" \ +> name="CloudFlare-doh IPv4" port=443 test-script="" type=https-get \ +> up-script="" +> add comment="dns, notify, name=Google-DNS IPv4" disabled=yes dns-server=\ +> 8.8.8.8 down-script="" host=dns.google http-codes="" name=\ +> "Google-DNS IPv4" test-script="" type=dns up-script="" +> add certificate=GTS-Root-R4 check-certificate=yes comment="doh-fallback, doh-u\ +> rl=https://dns.google/dns-query, doh-cert=GTS Root R1, notify, name=Google\ +> -DOH IPv4" disabled=yes dns-server=8.8.4.4 down-script="" host=dns.google \ +> http-codes="" name="Google-DOH IPv4" port=443 record-type=NS src-address=\ +> "" test-script="" type=dns up-script="" +> add comment="dns-fallback, notify, name=Cuad9-DOH IPv4" disabled=yes \ +> dns-server=9.9.9.9 down-script="" host=dns9.quad9.net http-codes="" \ +> interval=10s name="Cuad9-DOH IPv4" src-address=146.120.64.211 \ +> test-script="" timeout=800ms type=dns up-script="" +> add certificate=DigiCert-Assured-ID-Root-CA comment="doh-fallback, doh-url=htt\ +> ps://dns.quad9.net/dns-query, name=Cuad9-DOH IPv4" disabled=yes \ +> down-script="" host=149.112.112.112 http-codes="" interval=10s name=\ +> "Cuad9-DOH IPv4" port=443 test-script="" type=https-get up-script="" +> add comment="dns-fallback, notify, name=ns1.unet.ws" disabled=yes \ +> down-script="" host=91.192.189.2 http-codes="" interval=10s name=\ +> ns1.unet.ws test-script="" type=simple up-script="" +> add check-certificate=yes comment=\ +> "doh, doh-url=https://vds.vados.ru/vds-query, name=vds.vados.ru" \ +> disabled=yes down-script="" host=109.107.177.79 http-codes="" name=\ +> vds.vados.ru port=443 test-script="" type=https-get up-script="" +> add comment="WireGuard NAT " disabled=yes down-script="/log info \"[WG-Monitor\ +> ] WireGuard is NOT running - reverting rules\"\ +> \n/ip firewall nat remove [find comment=\"Redirect to Router\"]\ +> \n/ip dns set servers=8.8.8.8\ +> \n/ip dns cache flush\ +> \n/ip route remove [find comment=\"wg-auto-route\"]\ +> \n" host=10.8.0.1 http-codes="" interval=15s name=WG test-script="" \ +> timeout=5s type=simple up-script="/log info \"[WG-Monitor] WireGuard is RU\ +> NNING - applying rules\";\ +> \n:local routeFile \"ips.txt\";\ +> \n:local routeDefAddr \"0.0.0.0/0\";\ +> \n:local routeGateway \"10.8.0.1\";\ +> \n:local routeIF \"WG\";\ +> \n:local routeTable \"To-VPN\";\ +> \n:local routeComment \"wg-auto-route\";\ +> \n/ip dns cache flush;\ +> \n:if ([:len [/ip firewall nat find comment=\"Redirect to Router\"]] > 0) \ +> do={\ +> \n /ip firewall nat remove [find comment=\"Redirect to Router\"];\ +> \n}\ +> \n/ip firewall nat add action=redirect chain=dstnat src-address-list=\"Red\ +> irectDNS\" dst-port=53 protocol=udp comment=\"Redirect to Router\";\ +> \n/ip dns set servers=\$routeGateway;\ +> \n:local content [/file get \$routeFile contents];\ +> \n:if ([:len \$content] > 0) do={\ +> \n :local line \"\";\ +> \n :for i from=0 to=([:len \$content] - 1) do={\ +> \n :local char [:pick \$content \$i];\ +> \n :if (\$char != \"\\r\" && \$char != \"\\n\") do={\ +> \n :set line (\$line . \$char);\ +> \n } else={\ +> \n :if ([:len \$line] > 5) do={\ +> \n :do { /ip route add disabled=no dst-address=\$routeDefAd\ +> dr gateway=\$routeIF distance=1 scope=30 target-scope=10 routing-table=\$r\ +> outeTable comment=\$routeComment check-gateway=none } on-error={}\ +> \n }\ +> \n :set line \"\";\ +> \n }\ +> \n }\ +> \n :if ([:len \$line] > 5) do={\ +> \n# :do { /ip route add dst-address=\$line gateway=\$routeGateway \ +> distance=1 comment=\$routeComment } on-error={}\ +> \n :do { /ip route add disabled=no dst-address=\$routeDefAddr ga\ +> teway=\$routeIF distance=1 scope=30 target-scope=10 routing-table=\$routeT\ +> able comment=\$routeComment check-gateway=none } on-error={}\ +> \n }\ +> \n}\ +> \n:local dotPos [:find \$routeGateway \".\"];\ +> \n:if (\$dotPos != \"\") do={\ +> \n :local firstOctet [:pick \$routeGateway 0 \$dotPos];\ +> \n :local derivedDstAddress (\$firstOctet . \".30.0.0/15\");\ +> \n :do { /ip route add dst-address=\$derivedDstAddress gateway=\$routeG\ +> ateway distance=1 comment=\$routeComment } on-error={}\ +> \n}\ +> \n\ +> \n" +> add comment=WG-Default disabled=yes down-script=\ +> "/ip route disable [find comment=\"WG-Default\"];" host=10.8.0.1 \ +> interval=15s name=WG packet-count=20 test-script="" thr-loss-count=5 \ +> type=icmp up-script="/ip route enable [find comment=\"WG-Default\"];" diff --git a/MikroMaster/tmp/Config.rsc b/MikroMaster/tmp/Config.rsc deleted file mode 100644 index e69de29..0000000 diff --git a/MikroMaster/tmp/Diff-Config.rsc b/MikroMaster/tmp/Diff-Config.rsc deleted file mode 100644 index 48974ef..0000000 --- a/MikroMaster/tmp/Diff-Config.rsc +++ /dev/null @@ -1,65 +0,0 @@ -28c28 -< add comment=WG listen-port=13231 mtu=1360 name=WG ---- -> add comment=WG disabled=yes listen-port=13231 mtu=1360 name=WG -2664c2664 -< set detect-interface-list=WAN internet-interface-list=Internet \ ---- -> set detect-interface-list=all internet-interface-list=Internet \ -2676,2678c2676,2678 -< add allowed-address=0.0.0.0/0 client-allowed-address=::/0 endpoint-address=\ -< 109.107.177.79 endpoint-port=29185 interface=WG name=VDSina \ -< persistent-keepalive=10s public-key=\ ---- -> add allowed-address=0.0.0.0/0 client-allowed-address=::/0 disabled=yes \ -> endpoint-address=109.107.177.79 endpoint-port=29185 interface=WG name=\ -> VDSina persistent-keepalive=10s public-key=\ -2691d2690 -< add address=10.8.0.2/24 interface=WG network=10.8.0.0 -3392,3393c3391,3392 -< "Mark connection \"no-mark\" to NoWG" new-connection-mark=no-mark \ -< src-address-list=NoWG ---- -> "Mark connection \"no-mark\" to NoWG" disabled=yes new-connection-mark=\ -> no-mark src-address-list=NoWG -3395,3396c3394,3395 -< "Mark connection \"no-mark\" to NoVdsina" dst-address-list=NoVdsina \ -< new-connection-mark=no-mark src-address=10.30.30.0/24 ---- -> "Mark connection \"no-mark\" to NoVdsina" disabled=yes dst-address-list=\ -> NoVdsina new-connection-mark=no-mark src-address=10.30.30.0/24 -3405,3406c3404,3406 -< "Mark connection \"no-mark\" to VDSina" dst-address-list=VPN-Server \ -< new-connection-mark=no-mark passthrough=no src-address=10.30.30.0/24 ---- -> "Mark connection \"no-mark\" to VDSina" disabled=yes dst-address-list=\ -> VPN-Server new-connection-mark=no-mark passthrough=no src-address=\ -> 10.30.30.0/24 -3420,3421c3420,3421 -< connection-mark=!no-mark dst-address=!10.30.30.0/24 new-mss=1380 \ -< out-interface=WG protocol=tcp routing-mark=To-VPN src-address=\ ---- -> connection-mark=!no-mark disabled=yes dst-address=!10.30.30.0/24 new-mss=\ -> 1380 out-interface=WG protocol=tcp routing-mark=To-VPN src-address=\ -3424,3426c3424,3426 -< connection-mark=!no-mark dst-address=!10.30.30.0/24 dst-address-list=\ -< !NoVdsina new-routing-mark=To-VPN src-address=10.30.30.0/24 \ -< src-address-list=!NoWG ---- -> connection-mark=!no-mark disabled=yes dst-address=!10.30.30.0/24 \ -> dst-address-list=!NoVdsina new-routing-mark=To-VPN src-address=\ -> 10.30.30.0/24 src-address-list=!NoWG -3435,3436c3435,3436 -< connection-mark=no-mark dst-address-list=to_vpn new-connection-mark=\ -< to-vpn-conn-local ---- -> connection-mark=no-mark disabled=yes dst-address-list=to_vpn \ -> new-connection-mark=to-vpn-conn-local -3438c3438 -< connection-mark=to-vpn-conn-local new-routing-mark=*401 ---- -> connection-mark=to-vpn-conn-local disabled=yes new-routing-mark=*401 -3579,3581d3578 -< /ip route -< add check-gateway="(unknown)" disabled=no distance=1 dst-address=0.0.0.0/0 \ -< gateway=WG routing-table=To-VPN scope=30 target-scope=10 -- 2.52.0