When the external client connects on Windows it creates a config file in directory: C:\Program Files (x86)\PrivadoVPN\Config\PrivadoVPN_Wireguard.conf and you have to copy some information into the script underneath every time you want to takeover the WG connection. The shown privatekey is altered and is also generated ever new connection by the client.
It is a reused script and has more features than needed. It can be more direct because it is know which interface is to be targeted and now if the ports are the same as before it won't apply the new config.
Code: Select all
# Free to use. No reselling or commercial usage without an explicit written agreement by me!
# Created by Blacklister version: 20220120-0.93
# WireGuard implementation by Mikrotik does not adapt listening port to the one used by the VPN provider.
# This because it can't iniate the connection you need first to login, this is first done by an external client (Linux/Windows/MacOS).
# That external client creates the connection and configfile used, this script take that connection over so that this device can use it.
# You first have to find that configfile and drop it it in files on the router.
#
# Extra functionality:
# Read a WireGuard config file and changes the Wireguard entries and the addresses for that VPN connection
# Directly underneath you have to enter the name of the file, the name you want to use for the VPN. Those lines are marked with: # <---
#
# version 0.91 : updated script to use SET instead of ADD and using [find xxx=$nameVPN] to edit the correct lines. Also remove a lot of obsolete code.
# version 0.92 : added checks for config file and if the lines are present that are being changed.
# version 0.93 : added a check if there is an WG connection active that can be taken over matching the configfile
# version 0.931: correct swapping name and interface which caused an error
{
# the name of the config files copied to files in Winbox on this router
:local configname "PrivadoVPN_Wireguard.conf"; # <--- provide the name of the config files that you copied to /files on this router
:local nameVPN "PrivadoAMS"; # <--- name for this VPN connection
:local delimiter "\_"; # space
:local fileOK true; :local wgOK true; :local wgPeerOK true
:do { :local data [/file/get $configname contents] } on-error={ :set $fileOK false } ; # the name of the Wireguard config which to apply
if ( $fileOK ) do={
:local data [/file/get $configname contents]
:log info "Changing WireGuard settings for $nameVPN, from file $configname"
# avoiding that a config file has no "\n" (newline) at the end of the file, adding one just to be sure
:set $data "$data\n"
# reading the config file and extractig the found values
:while ([:len $data]!=0) do={ # eaten all the data in the file?
# not comparing the first character because it could be a capital letter
:if ($data~"rivate" || $data~"ddress" || $data~"DNS" || $data~"ublic" || $data~"ndpoint" || $data~"alive" || $data~"hared") do={
:do {set $name [:pick $data 0 [:find $data $delimiter]] } on-error={}; # on error avoids any panics
:set $data [:pick $data ([:find $data $delimiter]+1) [:len $data]]
:do {set $isSign [:pick $data 0 [:find $data $delimiter]] } on-error={}; # on error avoids any panics
:set $data [:pick $data ([:find $data $delimiter]+1) [:len $data]]
:do {set $value [:pick $data 0 [:find $data "\n"]] } on-error={}; # on error avoids any panics
# put the values into not yet permanent variables
if ( $name~"rivate" ) do={ :set $privateKey $value }; if ( $name~"ddress" ) do={ :set $localAddress $value }
if ( $name~"DNS" ) do={ :set $DNS $value }; if ( $name~"ublic" ) do={ :set $PeerPubKey $value }
if ( $name~"ndpoint" ) do={ :set $endpointAddress $value }; if ( $name~"alive" ) do={ :set $PersistentKA $value }
if ( $name~"hared" ) do={ :set $PreShared $value }
}; # END-IF - line contains any matching data "~"
:set data [:pick $data ([:find $data "\n"]+1) [:len $data]]; # remove the line that has just been examined from the data array
}; # while
:put "Importing $nameVPN with the following values:"; :put "Privatekey \t $privateKey"
:put "Local-address: \t $localAddress"; :set $network [:pick $localAddress 0 [:find $localAddress "/"]]
:put "Network: \t $network "; :put "DNS WireGuard: \t $DNS"
:set $pingDNS [:pick $DNS 0 [find $DNS ","]]; :put "Netwatch ping: \t $pingDNS"
:put "PeerPubkey: \t $PeerPubKey"; :put "PersistentKA: \t $PersistentKA"
:set $endpointPort [:pick $endpointAddress ( [:find $endpointAddress ":"]+1) [:len $endpointAddress]]
:set $endpointAddress [:pick $endpointAddress 0 [:find $endpointAddress ":"]]
:put "EndpointAddres: $endpointAddress"; :put "EndpointPort: \t $endpointPort"; :put "PresharedKey: \t $PreShared"
:do { /interface/wireguard get [find name=$nameVPN] } on-error={ :set $wgOK false }
:do { /interface/wireguard/peer get [find interface=$nameVPN] } on-error={ :set $wgPeerOK false }
:if ( $wgOK && $wgPeerOK ) do={
# Changing lines
# Set the WireGuard lines
:do { /interface/wireguard set comment="$nameVPN Taken over by script " mtu=1420 private-key=$privateKey disable=yes [find name=$nameVPN] } on-error={}
:delay 300ms; # give some time to set the line
:do { /interface/wireguard/peer set allowed-address=0.0.0.0/0 comment="taken over GW connection" endpoint-address=$endpointAddress endpoint-port=$endpointPort persistent-keepalive=300 public-key=$PeerPubKey preshared-key=$PreShared [find interface=$nameVPN] } on-error={}
# Set the IP to the addresses
:do { /ip address set address=$localAddress network=$network disable=no [find interface=$nameVPN] } on-error={}
# variables can be reused because the extracted config ones are already applied and obsolete.
# Actual changing the port connecting to the Peer and activating it
:set $WGport [/interface/wireguard/ get [find name=$nameVPN] listen-port]
:if ( :get [/ip/firewall/connection find dst-address~$endpointAddress ] ) do={
:foreach connectionID in=[/ip/firewall/connection/ find dst-address~$endpointAddress] do={
:set $srcAddress [/ip/firewall/connection get $connectionID src-address]
:set $newListenPort [:pick $srcAddress ([:find $srcAddress ":"]+1) [:len $srcAddress] ]
:if ( $newListenPort = $WGport ) do={ :log warning "WireGuard listen port already correct." }
:if ( $newListenPort != $WGport ) do={
/interface/wireguard set [find name=$nameVPN] disable=yes; # disable before changing so a new connection is created on the new port
:delay 300ms; # wait 300 miliseconds
/interface/wireguard set [find name=$nameVPN] listen-port=$newListenPort disable=no; # enable at the same time
:if ($logging = yes) do={ :log info "WireGuard: changed listening port $WGport --> $newListenPort of $nameVPN" }
} else={ /interface/wireguard set disable=no [find name=$nameVPN] }; # EndIf newListenPort and enable cient when nothing has to be changed
}; # foreach connenctionID
} else={ :log error "No matching WireGuard connection found to take-over " }; # EndIf get-find-endpointaddress
} else={ :log error "WireGuard or it's peer settings line not found or corrupt." }; # EndIf wgOK wgPeerOK
} else={ :log error "WG config file $configfilename not found." }; # EndIf fileOK
if ( $fileOK || $wgOK || $wgPeerOK ) do={} else={ :put "Settings not changed and check the log for the cause!" }
}
ps. This is only the script to take over a connection and you have to create first the WireGuard and Peer settings. And of course the needed addresses, routing or any other firewall settings.
Update: completed also the dynamic take over of a WG connection and after running block access by the external client on your computer after the Router made the connection. This way the external client can't logout and so disconnect the connection you are using. A short keep-alive in WG ensures you stay connected till a reboot/disconnect.
Update: disabled remove of lines and change add into set. When removing the current settings in the router become invalid.
Update-2: reworked the code and made it SET instead of ADD and removed a lot obsolete code not needed anymore. Only config is read and so the script only has to change one connection instead being able to change many.
Update-3: added checks for config file and if the lines are present that are being changed.
Update-4: added a check if there is an WG connection active that can be taken over matching the config file
Update-5: correct swapping name and interface which caused an error