Sure.can you please share your "small netwatch script" ?
/tool netwatch add down-script="/interface wireguard peers disable 0
:delay 5
/interface wireguard peers enable 0"
host=10.255.255.1
Is that on the SERVER router or on the PEER router (client device)?Sure.can you please share your "small netwatch script" ?
Very basic but does what it needs to do.
10.255.255.1 is the IP of the "server". When that's not visible, WG is down or not active yet.
And I know I shouldn't use peer numbers but there is only 1 peer on that device. Can't go wrong there.
Code: Select all/tool netwatch add down-script="/interface wireguard peers disable 0 :delay 5 /interface wireguard peers enable 0" host=10.255.255.1
I see the same, when my local IP. which is passed-trough from LTE (LHGG) changes. Resolution is to delete the existing conntrack entry to the remote/Server side and then toggle the local peer.When I updated the remote hAp ac3 from 7.1.3 to 7.1.5, the wireguard tunnel never came up (waited -30 min to see if it would eventually come up, but it did not).
Thinking this over ... this changing of 'client-IP' should be dealt with automatically by the WG-protocol, as last resort should toggling of peer status do the same thing ?Ah, the other side ... good call !
Might indeed be that.
Agree with the reboot thing. But a Change of local WAN IP in my case does not toggle the conntrack entries for the wg interface going out to the (fixed) remote Server IP.Thinking this over ... this changing of 'client-IP' should be dealt with automatically by the WG-protocol, as last resort should toggling of peer status do the same thing ?
A reboot should not be needed.
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
#
# Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
set -e
shopt -s nocasematch
shopt -s extglob
export LC_ALL=C
CONFIG_FILE="$1"
[[ $CONFIG_FILE =~ ^[a-zA-Z0-9_=+.-]{1,15}$ ]] && CONFIG_FILE="/etc/wireguard/$CONFIG_FILE.conf"
[[ $CONFIG_FILE =~ /?([a-zA-Z0-9_=+.-]{1,15})\.conf$ ]]
INTERFACE="${BASH_REMATCH[1]}"
process_peer() {
[[ $PEER_SECTION -ne 1 || -z $PUBLIC_KEY || -z $ENDPOINT ]] && return 0
[[ $(wg show "$INTERFACE" latest-handshakes) =~ ${PUBLIC_KEY//+/\\+}\ ([0-9]+) ]] || return 0
(( ($EPOCHSECONDS - ${BASH_REMATCH[1]}) > 135 )) || return 0
wg set "$INTERFACE" peer "$PUBLIC_KEY" endpoint "$ENDPOINT"
reset_peer_section
}
reset_peer_section() {
PEER_SECTION=0
PUBLIC_KEY=""
ENDPOINT=""
}
reset_peer_section
while read -r line || [[ -n $line ]]; do
stripped="${line%%\#*}"
key="${stripped%%=*}"; key="${key##*([[:space:]])}"; key="${key%%*([[:space:]])}"
value="${stripped#*=}"; value="${value##*([[:space:]])}"; value="${value%%*([[:space:]])}"
[[ $key == "["* ]] && { process_peer; reset_peer_section; }
[[ $key == "[Peer]" ]] && PEER_SECTION=1
if [[ $PEER_SECTION -eq 1 ]]; then
case "$key" in
PublicKey) PUBLIC_KEY="$value"; continue ;;
Endpoint) ENDPOINT="$value"; continue ;;
esac
fi
done < "$CONFIG_FILE"
process_peer
:local wgcheckip Local_IP
:local endpointip xxxyyy.sn.mynetname.net
#:log info "wg check-ip $wgcheckip "
:if ([/ping $wgcheckip interval=1 count=5] =0) do={
:log info "WG down $wgcheckip"
/interface/wireguard/peers/disable [find endpoint-address=$endpointip];
:delay 60
/interface/wireguard/peers/enable [find endpoint-address=$endpointip];
:log info "WG up again $wgcheckip"
}
:delay 25
/interface wireguard peer disable 0
:delay 5
/interface wireguard peer enable 0
:log info "WGPeer toggled"
You typed to soon look above for the answer!!! It is simply a script that runs on the client, similar to the procustodibus AGENT, and no different from the two scripts I pointed to above that are on the user article..........The WireGuard Tools script addresses the following scenario
When the WireGuard interface of the ("Peer" client) starts up, it will resolve the DNS record for myvpn.myddns.com, and select one of the IP addresses to use as its endpoint for the ("Peer" server). Let’s say it selects 1.2.3.4
In many CGNAT networks -- let’s say the WireGuard ("Peer" server) at 1.2.3.4 becomes unavailable, and your DNS servers remove it from their myvpn.myddns.com responses. Your ("Peer" client) will continue to try to access the WireGuard ("Peer" server) at 1.2.3.4 even though the DNS record for vmyvpn.myddns.com now only contains 13.10.199.6
Hope that explains it
:foreach i in=[/interface/wireguard/peers/find where disabled=no endpoint-address~"[a-z]\$"] do={
:if ([/interface/wireguard/peers/get $i last-handshake] > [:totime "5m"]) do={
/interface/wireguard/peers/set $i endpoint-address=[/interface/wireguard/peers/get $i endpoint-address]
}
}
:foreach i in=[/interface/wireguard/peers/find where disabled=no endpoint-address~"[a-z]\$"] do={
:local LastHandshake [/interface/wireguard/peers/get $i last-handshake]
:if (([:tostr $LastHandshake] = "") or ($LastHandshake > [:totime "5m"])) do={
/interface/wireguard/peers/set $i endpoint-address=[/interface/wireguard/peers/get $i endpoint-address]
}
}
Wireguard is works fine when used endpoint as IP but it doesn't accepting host name to use DDNS.
/interface/wireguard/peers
add allowed-address=10.1.101.0/24 endpoint-address=192.168.80.1 endpoint-port=13231 interface=wireguard1 \
public-key="v/oIzPyFm1FPHrqhytZgsKjU7mUToQHLrW+Tb5e601M="
:local ddnshost "host.mywire.org"
:local peerip [/interface wireguard peers get [find comment="home"] endpoint-address ];
:local hostip [:resolve $ddnshost];
#:log info "peer endpoint ip address is $peerip";
#:log info "resolved ip address is $hostip"
:if ($peerip != $hostip) do={
/interface wireguard peers set [find comment="home"] endpoint-address=$hostip;
:log warning "Wireguard Peer endpoint IP Updated to: $hostip old IP was $peerip";
} else={
#:log info "WG: no need to update";
}
Here is a „small“ guide: https://blog.spaps.de/mikrotik-routeros ... t-refresh/Is this a script you run on a schedule?
Yes i run it after 1 minute intervalIs this a script you run on a schedule?
/system script
add dont-require-permissions=no name=wg owner=zone policy=\
ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source=":lo\
cal ddnshost \"host.mywire.org\"\r\
\n:local peerip [/interface wireguard peers get [find comment=\"Office\"] en\
dpoint-address ];\r\
\n:local hostip [:resolve \$ddnshost];\r\
\n#:log info \"peer endpoint address is \$peerip\";\r\
\n#:log info \"resolved address is \$hostip\"\r\
\n:if (\$peerip != \$hostip) do={\r\
\n/interface wireguard peers set [find comment=\"Office\"] endpoint-address=\
\$hostip;\r\
\n:log warning \"Wireguard Peer endpoint IP Updated to: \$hostip old IP was \
\$peerip\";\r\
\n} else={\r\
\n#:log info \"WG: no need to update\";\r\
\n}"
/system scheduler
add interval=1m name=wireguard on-event="/system/script/run wg" policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon start-date=nov/12/2022 start-time=14:39:59
# Wireguard check script
#Declare variables
:local wgport
:local wgpeer
# Disable any peers that have last handshake > 3mins
/interface/wireguard/peers/set disabled=yes [find last-handshake > [:totime "3m"]]
# Disable any peers that have tx or rx 0 (sometimes happens after router restart)
/interface/wireguard/peers/set disabled=yes [find rx=0 or tx=0]
:delay 2
# For any disabled peer get the port and clear any connections in the firewall
:foreach i in=[/interface/wireguard/peers find disabled=yes] do={
:set wgport ([/interface/wireguard/peers get $i endpoint-port])
:foreach j in=[/ip firewall connection find dst-address~":$wgport\$" protocol=udp] do={
/ip firewall connection remove $j
: log info "** Wiregiuard Check Script ** firewall connections on port $wgport cleared"
}
# and re-enable any disabled peers
/interface/wireguard/peers set $i disabled=no
# and let the log file know what has happened
:set wgpeer [/interface/wireguard/peers get $i interface]
:log info "** Wireguard Check Script ** wireguard peer $wgpeer restarted"
}
s/:$wgport/:$wgport\$" protocol="udp/
Good spot. Thanks. I have edited my original post to save clogging up the thread with a new post.It IS brutal
Btw,? So if port is 9090, no connections with port 90907 would be killed.Code: Select alls/:$wgport/:$wgport\$" protocol="udp/
If you have mikrotik at both ends you can run at both, It would help clear up any stale connection at either end. It wont touch any connection that is in good health.
Just to confirm these scripts are meant for the client router side ( meaning client at the initial handshake ).
Yes
Will also ask the same question @aoakeley, is this script run on a schedule???
The script sets wgpeer and wgport within the if statements. Look for the lines starting with ":set" within the if statements.
Also how does your router use the local variables......?
Mine is not really that different, except that it is a but more brutal in that it disables and re-enables the peer and clears the firewall connections.
Tough time picking between Sob/Daves version and aoakeley's version LOL.
So it is not affecting other disabled peers in anyway?So it works like this
1.it detects a peer that is not working
2.it disables the peer
3. delays for 2 seconds (you can probably remove this)
4.then cycles through the "if" with
- if peer is disabled find which peer it is and set the $wgpeer variable
- use $wgpeer to find the port of that peer and set $wgport
- use $wgport to clear the connection in the firewall
5. Then enable the peers again
- repeat for all disabled peers
@aoakeleyHere is another one for you. It is a bit more brutal, but it is versatile as it does not rely on finding any comments, and you can put it on a router with a number of peers and it will just pick out the ones that need killing and restarting without affecting the ones that are OK.
It checks
- if handshake >3min (no peer should ever have handshake more than 00:02:10)
- It also checks if there are any peers with 0 tx or 0 rx (which sometimes happens after reboot, and if the peer has never started it will never get handshake >3min)
- it disables any peer that meets the above two critera
- THEN in addition looks up the ports in use by each peer, and clears any connections in the firewall (useful if traffic is trying to go out the wrong interface)
- and finally logs a bit to the log file, only if it has found something to do (so you don't end up with log spam)
- Then re-enables the peer
Code: Select all# Wireguard check script #Declare variables :local wgport :local wgpeer # Disable any peers that have last handshake > 3mins /interface/wireguard/peers/set disabled=yes [find last-handshake > [:totime "3m"]] # Disable any peers that have tx or rx 0 (sometimes happens after router restart) /interface/wireguard/peers/set disabled=yes [find rx=0 or tx=0] :delay 2 # For any disabled peer get the port and clear any connections in the firewall :foreach i in=[/interface/wireguard/peers find disabled=yes] do={ :set wgport ([/interface/wireguard/peers get $i endpoint-port]) :foreach j in=[/ip firewall connection find dst-address~":$wgport\$" protocol=udp] do={ /ip firewall connection remove $j : log info "** Wiregiuard Check Script ** firewall connections on port $wgport cleared" } # and re-enable any disabled peers /interface/wireguard/peers set $i disabled=no # and let the log file know what has happened :set wgpeer [/interface/wireguard/peers get $i interface] :log info "** Wireguard Check Script ** wireguard peer $wgpeer restarted" }
Condition matches already disabled interfaces too./interface/wireguard/peers/set disabled=yes [find rx=0 or tx=0]
enables all interfaces/interface/wireguard/peers set $i disabled=no
Dear I am not asking you to use 1 minuteI note the terms >5min or >3min, seems like running the script every 10 minutes makes sense.....................
I prefer not to run scripts frequently if avoidable...........aka 1minute for example
Conclusion: finding comment & editing only required fields is way better than yours.
Here is my script
Yup
Conclusion: finding comment & editing only required fields is way better than yours.
Here is my script
Whatever dude.... it is not a competition. Relax.
Some stuff works better for some than others.
:foreach i in=[/interface/wireguard/peers/find where disabled=no endpoint-address~"[a-z]\$"] do={
:local LastHandshake [/interface/wireguard/peers/get $i last-handshake]
:if (([:tostr $LastHandshake] = "") or ($LastHandshake > [:totime "5m"])) do={
/interface/wireguard/peers/set $i endpoint-address=[/interface/wireguard/peers/get $i endpoint-address]
}
}
I like this one more: viewtopic.php?p=921026#p921026
Because you have FQDN in WG Peer, not only in a script, and you only update it when there's no connectivity. WG can automatically detect new peer IP if there are packets from new IP with the same signature, so you don't need to update the endpoint in that case.
:global Tx
/interface/wireguard/peers
:foreach i in=[find where disabled=no endpoint-address~"[a-z]\$"] do={
:local LocalTx [get $i tx]
:local LastHandshake [get $i last-handshake]
:if (([:tostr $LastHandshake] = "") or (($LastHandshake > [:totime "5m"]) and ($Tx->[:tostr $i] != $LocalTx))) do={
:local EndpointAddress [get $i endpoint-address]
:log info ("WG $EndpointAddress down, LastHandshake $LastHandshake, LastTx " . $Tx->[:tostr $i] . ", CurrentTx $LocalTx")
set $i endpoint-address=$EndpointAddress
}
:set ($Tx->[:tostr $i]) $LocalTx
}
In worst case scenario, your script is run on 4:59 after last handshake (and does nothing), then on 6:59 and updates the endpoint IP addressI use the scheduler to run the script every 2 minutes - so 5 minutes minimum, 7 minutes maximum of downtime before a reset is attempted.
WireGuard keeps in memory the current secure session, the previous secure
session, and the next secure session for the case of an unconfirmed session. Every time a new secure session
is created, the existing one rotates into the “previous” slot, and the new one occupies the “current” slot, for
the initiator, and for the responder, the “next” slot is used interstitially until the handshake is confirmed.
This passive keepalive is only sent when a peer has nothing to send, and is only sent in circumstances when
another peer is sending authenticated transport data messages to it. This means that when neither side is
exchanging transport data messages, the network link will be silent.
Because every transport data message sent warrants a reply of some kind—either an organic one generated
by the nature of the encapsulated packets or this keepalive message—we can determine if the secure session
is broken or disconnected
AMEN TO THAT BROTHER, I already put in a request and nothing, so the more people that do...............the better chance it will happen.Start on post 8, 28, 29 and further down.
Various solutions have been presented to circumvent this problem (until they finally solve it in ROS itself, where it should be solved)