Hello all,
Is there a better log to be looking at, on the WG client or server side, to troubleshoot problem connections? The Log File in OPNsense tells me close to nothing when trying to understand why a client connection is not working.
Thanks,
Steve
+1
It appears that wireguard connection logging is not existent by design. see https://forum.opnsense.org/index.php?topic=43997.0 (https://forum.opnsense.org/index.php?topic=43997.0)
But I would think that some type of basic connection/handshake logging would be possible from within OPNsense because the GUI is able to show the connection status and the last handshake age.
Quote from: joezeppy on June 21, 2025, 01:26:41 PMIt appears that wireguard connection logging is not existent by design. see https://forum.opnsense.org/index.php?topic=43997.0 (https://forum.opnsense.org/index.php?topic=43997.0)
But I would think that some type of basic connection/handshake logging would be possible from within OPNsense because the GUI is able to show the connection status and the last handshake age.
Isn't that simply processing the Output of (assuming wg1 is your Wireguard Interface):
wg show wg1 dumpOr possibly just grepping the Human Readable Output
But I guess easiest is for X = 1 ... 8 (depending on which Field you want to analyze)
wg show wg1 dump | tail -n1 | awk '{print $X}'
We really need this since logging is important for monitoring who connects to the VPN and from what IP.
I see that someone has made a similar script based solution for Mikrotik routers. Can anyone implement something similar for for OPNsense? The built in kernel level logging is what it is but it does not stop us from having logs since the peer info is accessible and can be parsed.
https://forum.mikrotik.com/t/logging-wireguard-peer-connects-and-disconnects/263033
Just for information for all those who see this post.
If you create new WireGuard peers, you will need to restart the WireGuard service.
Only then is the new peer applied.
I've spent a whole day searching why my newly created peers aren't working.
Uncheck the box "Enable WireGuard" and tick it, that's it.
I hope this saves someone time.
Because of the acute lack of solutions I decided to roll my own and share it.
An easy way of doing this with minimal modifications is to use userscripts.
The scipt has been tested on OPNsense 26.1.1-amd64
Steps to implement:
Log into the firewall shell with SSH and create the script file:
vi /usr/local/opnsense/service/conf/actions.d/actions_wireguardlogger.conf
Add the content (if not familiar with VI press i and then paste content and press esc and :wq and enter)
[restart]
command: /bin/sh -c 'S=/var/db/wg-peer-cron.state; T=$(mktemp /tmp/wg-peer-cron.XXXXXX) || exit 1; M=$(mktemp /tmp/wg-peer-map.XXXXXX) || exit 1; N=$(date +%s); mkdir -p /var/db; python3 -c '\''import xml.etree.ElementTree as ET; root=ET.parse("/conf/config.xml").getroot(); [print(((c.findtext("pubkey") or "").strip())+"|"+((c.findtext("name") or "").strip())) for c in root.findall("./OPNsense/wireguard/client/clients/client")]'\'' > "$M"; /usr/bin/wg show all dump | awk -F "\t" -v now="$N" '\''NF==9{hs=$6+0; age=(hs>0?now-hs:999999999); st=(hs>0&&age<=300?"connected":"disconnected"); print $1 "|" $2 "|" st "|" hs "|" $4 "|" $5 "|" age}'\'' > "$T" && [ -s "$T" ] || { rm -f "$T" "$M"; exit 0; }; [ -f "$S" ] || : > "$S"; while IFS="|" read -r IF PK ST HS EP AL AGE; do O=$(awk -F "|" -v i="$IF" -v p="$PK" '\''$1==i && $2==p {print; exit}'\'' "$S"); OS=$(printf "%s" "$O" | awk -F "|" '\''{print $3}'\''); [ -n "$OS" ] || OS=unknown; PN=$(awk -F "|" -v p="$PK" '\''$1==p {print $2; exit}'\'' "$M"); [ -n "$PN" ] || PN=unknown; [ -n "$EP" ] && [ "$EP" != "(none)" ] || EP=unknown; [ "$ST" = connected ] && [ "$OS" != connected ] && logger -t wireguard -p auth.notice "wireguard peer connected: instance=$IF, peer_name=$PN, peer_pubkey=$PK, endpoint=$EP, allowed_ips=$AL, handshake_age=${AGE}s"; [ "$ST" = disconnected ] && [ "$OS" != disconnected ] && logger -t wireguard -p auth.notice "wireguard peer disconnected: instance=$IF, peer_name=$PN, peer_pubkey=$PK, endpoint=$EP, allowed_ips=$AL, handshake_age=${AGE}s"; done < "$T"; cut -d"|" -f1-6 "$T" > "$S"; rm -f "$T" "$M"'
parameters:
type: script
message: checking wireguard connections
description: Wireguard connection monitor and logger
Pay attention to the command parameter, the whole long command needs to be one line.
Restart the configd service to see the new script:
service configd restart
Log into web management and go to system -> settings -> cron
Create a new job and set it to run every minute
(https://i.imgur.com/nv0q0FR.png)
If you did everything correctly the Wireguard log will start logging events every minute. These are accessible directly in the wireguard VPN log menu.
2026-03-13T14:04:00 Notice wireguard wireguard peer connected: instance=wg0, peer_name=phone, peer_pubkey=bOa1clBIOgmJEw2To7+StkqPaA2UxKsjw=, endpoint=192.168.11.65:51888, allowed_ips=192.168.12.2/32, handshake_age=56s
2026-03-13T14:03:00 Notice wireguard wireguard peer disconnected: instance=wg0, peer_name=laptop, peer_pubkey=9V3VB9ALJtB0lgvhpCetVVEbZW6YH6Rnk=, endpoint=192.168.11.228:54553, allowed_ips=192.168.12.3/32, handshake_age=513s
2026-03-13T13:58:12 Notice wireguard wireguard peer disconnected: instance=wg0, peer_name=phone, peer_pubkey=bOa1clBIOgmJEw2To7+StkqPaA2UxKsjw=, endpoint=192.168.11.65:51888, allowed_ips=192.168.12.2/32, handshake_age=381s
2026-03-13T13:54:36 Notice wireguard wireguard peer connected: instance=wg0, peer_name=laptop, peer_pubkey=9V3VB9ALJtB0lgvhpCetVVEbZW6YH6Rnk=, endpoint=192.168.11.228:54553, allowed_ips=192.168.12.3/32, handshake_age=9s
2026-03-13T13:51:57 Notice wireguard wireguard peer connected: instance=wg0, peer_name=phone, peer_pubkey=bOa1clBIOgmJEw2To7+StkqPaA2UxKsjw=, endpoint=192.168.11.65:51888, allowed_ips=192.168.12.2/32, handshake_age=6s
Peers are marked disconnected when they have not handshaked in 300 seconds / 5 min.
For the life of me I do not understand why this simple logging is not part of the Wireguard implementation on every firewall, since it is essential to know who is accessing your firewall and from where.
Peer names need to be unique for the logging to successfully work.
Quote from: mtchetch on March 13, 2026, 01:20:05 PMBecause of the acute lack of solutions I decided to roll my own and share it.
An easy way of doing this with minimal modifications is to use userscripts.
The scipt has been tested on OPNsense 26.1.1-amd64
Steps to implement:
Log into the firewall shell with SSH and create the script file:
vi /usr/local/opnsense/service/conf/actions.d/actions_wireguardlogger.conf
Add the content (if not familiar with VI press i and then paste content and press esc and :wq and enter)
[restart]
command: /bin/sh -c 'S=/var/db/wg-peer-cron.state; T=$(mktemp /tmp/wg-peer-cron.XXXXXX) || exit 1; M=$(mktemp /tmp/wg-peer-map.XXXXXX) || exit 1; N=$(date +%s); mkdir -p /var/db; python3 -c '\''import xml.etree.ElementTree as ET; root=ET.parse("/conf/config.xml").getroot(); [print(((c.findtext("pubkey") or "").strip())+"|"+((c.findtext("name") or "").strip())) for c in root.findall("./OPNsense/wireguard/client/clients/client")]'\'' > "$M"; /usr/bin/wg show all dump | awk -F "\t" -v now="$N" '\''NF==9{hs=$6+0; age=(hs>0?now-hs:999999999); st=(hs>0&&age<=300?"connected":"disconnected"); print $1 "|" $2 "|" st "|" hs "|" $4 "|" $5 "|" age}'\'' > "$T" && [ -s "$T" ] || { rm -f "$T" "$M"; exit 0; }; [ -f "$S" ] || : > "$S"; while IFS="|" read -r IF PK ST HS EP AL AGE; do O=$(awk -F "|" -v i="$IF" -v p="$PK" '\''$1==i && $2==p {print; exit}'\'' "$S"); OS=$(printf "%s" "$O" | awk -F "|" '\''{print $3}'\''); [ -n "$OS" ] || OS=unknown; PN=$(awk -F "|" -v p="$PK" '\''$1==p {print $2; exit}'\'' "$M"); [ -n "$PN" ] || PN=unknown; [ -n "$EP" ] && [ "$EP" != "(none)" ] || EP=unknown; [ "$ST" = connected ] && [ "$OS" != connected ] && logger -t wireguard -p auth.notice "wireguard peer connected: instance=$IF, peer_name=$PN, peer_pubkey=$PK, endpoint=$EP, allowed_ips=$AL, handshake_age=${AGE}s"; [ "$ST" = disconnected ] && [ "$OS" != disconnected ] && logger -t wireguard -p auth.notice "wireguard peer disconnected: instance=$IF, peer_name=$PN, peer_pubkey=$PK, endpoint=$EP, allowed_ips=$AL, handshake_age=${AGE}s"; done < "$T"; cut -d"|" -f1-6 "$T" > "$S"; rm -f "$T" "$M"'
parameters:
type: script
message: checking wireguard connections
description: Wireguard connection monitor and logger
Pay attention to the command parameter, the whole long command needs to be one line.
Restart the configd service to see the new script:
service configd restart
Log into web management and go to system -> settings -> cron
Create a new job and set it to run every minute
(https://i.imgur.com/nv0q0FR.png)
If you did everything correctly the Wireguard log will start logging events every minute. These are accessible directly in the wireguard VPN log menu.
2026-03-13T14:04:00 Notice wireguard wireguard peer connected: instance=wg0, peer_name=phone, peer_pubkey=bOa1clBIOgmJEw2To7+StkqPaA2UxKsjw=, endpoint=192.168.11.65:51888, allowed_ips=192.168.12.2/32, handshake_age=56s
2026-03-13T14:03:00 Notice wireguard wireguard peer disconnected: instance=wg0, peer_name=laptop, peer_pubkey=9V3VB9ALJtB0lgvhpCetVVEbZW6YH6Rnk=, endpoint=192.168.11.228:54553, allowed_ips=192.168.12.3/32, handshake_age=513s
2026-03-13T13:58:12 Notice wireguard wireguard peer disconnected: instance=wg0, peer_name=phone, peer_pubkey=bOa1clBIOgmJEw2To7+StkqPaA2UxKsjw=, endpoint=192.168.11.65:51888, allowed_ips=192.168.12.2/32, handshake_age=381s
2026-03-13T13:54:36 Notice wireguard wireguard peer connected: instance=wg0, peer_name=laptop, peer_pubkey=9V3VB9ALJtB0lgvhpCetVVEbZW6YH6Rnk=, endpoint=192.168.11.228:54553, allowed_ips=192.168.12.3/32, handshake_age=9s
2026-03-13T13:51:57 Notice wireguard wireguard peer connected: instance=wg0, peer_name=phone, peer_pubkey=bOa1clBIOgmJEw2To7+StkqPaA2UxKsjw=, endpoint=192.168.11.65:51888, allowed_ips=192.168.12.2/32, handshake_age=6s
Peers are marked disconnected when they have not handshaked in 300 seconds / 5 min.
For the life of me I do not understand why this simple logging is not part of the Wireguard implementation on every firewall, since it is essential to know who is accessing your firewall and from where.
That scripts runs perfectly fine, thank you so much!
At least a bit of information in the logs.
Quote from: mtchetch on March 13, 2026, 01:20:05 PMIf you did everything correctly the Wireguard log will start logging events every minute. These are accessible directly in the wireguard VPN log menu.
Code Select Expand
2026-03-13T14:04:00 Notice wireguard wireguard peer connected: instance=wg0, peer_name=phone, peer_pubkey=bOa1clBIOgmJEw2To7+StkqPaA2UxKsjw=, endpoint=192.168.11.65:51888, allowed_ips=192.168.12.2/32, handshake_age=56s
2026-03-13T14:03:00 Notice wireguard wireguard peer disconnected: instance=wg0, peer_name=laptop, peer_pubkey=9V3VB9ALJtB0lgvhpCetVVEbZW6YH6Rnk=, endpoint=192.168.11.228:54553, allowed_ips=192.168.12.3/32, handshake_age=513s
2026-03-13T13:58:12 Notice wireguard wireguard peer disconnected: instance=wg0, peer_name=phone, peer_pubkey=bOa1clBIOgmJEw2To7+StkqPaA2UxKsjw=, endpoint=192.168.11.65:51888, allowed_ips=192.168.12.2/32, handshake_age=381s
2026-03-13T13:54:36 Notice wireguard wireguard peer connected: instance=wg0, peer_name=laptop, peer_pubkey=9V3VB9ALJtB0lgvhpCetVVEbZW6YH6Rnk=, endpoint=192.168.11.228:54553, allowed_ips=192.168.12.3/32, handshake_age=9s
2026-03-13T13:51:57 Notice wireguard wireguard peer connected: instance=wg0, peer_name=phone, peer_pubkey=bOa1clBIOgmJEw2To7+StkqPaA2UxKsjw=, endpoint=192.168.11.65:51888, allowed_ips=192.168.12.2/32, handshake_age=6s
Peers are marked disconnected when they have not handshaked in 300 seconds / 5 min.
For the life of me I do not understand why this simple logging is not part of the Wireguard implementation on every firewall, since it is essential to know who is accessing your firewall and from where.
Not bad, maybe consider to open a PR on github?
Even though this is via the cron menu it could be redone to have it by default.
Regards,
S.
Wireguard is not connected or disconnected, since the protocol is connectionless.
All logging are just assumptions.
Use OpenVPN for proper logging.
As reference I made the wireguard dashboard widget and had so many confused users about the states it displays that I know what Im talking about here.
There is no missing feature here, just use the correct tools for the correct job.
Quote from: Monviech (Cedrik) on April 30, 2026, 12:57:30 PMThere is no missing feature here, just use the correct tools for the correct job.
I agree, but considering the fact that a lot of people claim that Wireguard is better when it comes to battery consumption on phones and tablets you could call this an exception to that rule :)