wireguard not working after reboot using peer fqdn, os 25.7..1

Started by iorx, August 01, 2025, 08:34:46 AM

Previous topic - Next topic
Hi all awesome people!

I've got this since 25.7. Now on 25.7.1.
/usr/local/opnsense/scripts/Wireguard/wg-service-control.php: The command '/usr/bin/wg syncconf 'wg1' '/usr/local/etc/wireguard/wg1.conf'' returned exit code '1', the output was 'Name does not resolve: `mywg.domainIhave.yy:55820' Configuration parsing error'

mywg.domainIhave.yy resolves as it should. But using it as peer in wg, wg fails with the above.
Replacing mywg.domainIhave.yy with the IP-address resolves the problem and wg starts as it should after reboot.

This used to work without any problem before the upgrade, that is 25.1.
Any changes made how wg is starting or waiting for stuff?

Brgs,

Hi on my self and others!

Still got this problem it looks like. I resorted to IP-adress, but it would be really nice if it is possible to get it working with a peer hostname instead.
Any way to resolve this?
Make WireGuard wait for DNS-service and maybe be a bit more stubborn on resolving the the name? Make it wait for a while before starting?

from the log:
/usr/local/opnsense/scripts/wireguard/wg-service-control.php: The command </usr/bin/wg syncconf 'wg1' '/usr/local/etc/wireguard/wg1.conf'> returned exit code 1 and the output was "Name does not resolve: `my-very-nice-dyn-hostname:55120' Configuration parsing error"


Brgs,

Today at 09:39:58 AM #2 Last Edit: Today at 10:48:55 AM by iorx Reason: Added a solution
Hi again!

Don't know if this is frowned upon or maybe worth much for others, but this solved it for me and may give other an idea how to get it going with WireGuard and hostname.

Some LLM vibe-coding...

This script ensures that all required services are running and that the hostname is resolvable before it triggers a WireGuard restart via pluginctl. It also includes a "pre-flight check" so it doesn't restart anything if the tunnel is already up.

It grabs what it can from the config.conf. A warning is that it assumes that a pingable IP through the tunnel is .1 from one of the .0/24 allowed networks in the peer configuration.

Add:
Put it here, and make an +x on it.

root@fwa:~ # cd /usr/local/etc/rc.syshook.d/start
root@fwa:/usr/local/etc/rc.syshook.d/start # ls
10-newwanip             25-syslog               90-carp                 90-openvpn              95-beep
20-freebsd              50-ntopng               90-cron                 90-sysctl               99-wireguard-dns-fix
root@fwa:/usr/local/etc/rc.syshook.d/start # chmod +x 99-wireguard-dns-fix

PEER_NAME: Change the to match your peer name.
REQUIRED_SERVICES: Adjust Services that should be running.

Script:
#!/bin/sh

# Header: Dynamic Wireguard Startup Sync for OPNsense 26.1
# Description: Extracts peer data from config.xml and ensures DNS stack is ready.
# Note: This script will "man-guess" that .1 is a reachable gateway address if a .0 network is found.
# Optimization: Checks if the tunnel is already up before performing any actions.
# Logging: Outputs to system log with tag "man-guess-wg" and priority "user.notice".

# --- Configuration ---
PEER_NAME="wg_peer"
REQUIRED_SERVICES="unbound dnsmasq AdGuardHome"
CONFIG_PATH="/conf/config.xml"
LOG_TAG="man-guess-wg"
MAX_RETRIES=20
SLEEP_INTERVAL=5

log_msg() {
    # Output to stdout and OPNsense System Log (General)
    echo "$1"
    logger -p user.notice -t "$LOG_TAG" "$1"
}

# 1. Extract the Endpoint (serveraddress)
CHECK_HOST=$(xmllint --xpath "string(//wireguard/client/clients/client[name='$PEER_NAME']/serveraddress)" $CONFIG_PATH 2>/dev/null)

# 2. Extract the first entry from Allowed IPs (tunneladdress)
RAW_IP=$(xmllint --xpath "string(//wireguard/client/clients/client[name='$PEER_NAME']/tunneladdress)" $CONFIG_PATH 2>/dev/null | cut -d',' -f1 | cut -d'/' -f1)

# Logic: Convert network address (ending in .0) to gateway (.1) for ping test.
# This part is a confident man-guess that .1 is the responding address.
TUNNEL_IP=$(echo "$RAW_IP" | sed 's/\.0$/.1/')

# Validation: Stop if configuration data is missing
if [ -z "$CHECK_HOST" ] || [ -z "$RAW_IP" ]; then
    log_msg "ERROR: Extraction failed for '$PEER_NAME'. Check if the name matches in config.xml."
    exit 1
fi

# --- INITIAL CHECK ---
# If the tunnel is already reachable, we exit immediately to avoid unnecessary restarts.
if ping -c 1 -t 2 "$TUNNEL_IP" > /dev/null 2>&1; then
    log_msg "STATUS: Tunnel to $TUNNEL_IP is already UP. No action taken."
    exit 0
fi

check_process() {
    pgrep -f "$1" > /dev/null
    return $?
}

log_msg "STATUS: Tunnel is DOWN. Initiating sync for peer: $PEER_NAME (Target: $CHECK_HOST)"

for i in $(seq 1 $MAX_RETRIES); do
    SERVICES_READY=true
   
    # Verify that all DNS-related services are running
    for SERVICE in $REQUIRED_SERVICES; do
        if ! check_process "$SERVICE"; then
            SERVICES_READY=false
            break
        fi
    done
   
    if [ "$SERVICES_READY" = true ]; then
        # Check if the dynamic hostname can be resolved yet
        if host "$CHECK_HOST" > /dev/null 2>&1; then
            log_msg "DNS OK: $CHECK_HOST resolved. Restarting Wireguard via pluginctl."

            # Official OPNsense 26.1 method for plugin service management
            /usr/local/sbin/pluginctl -s wireguard restart
           
            # Allow time for handshake and routing table updates
            sleep 15
           
            if ping -c 1 -t 3 "$TUNNEL_IP" > /dev/null 2>&1; then
                log_msg "SUCCESS: Connectivity to $TUNNEL_IP confirmed."
                exit 0
            fi
        fi
    fi
   
    # Log status every 5th attempt to keep the system log clean
    if [ $((i % 5)) -eq 0 ]; then
        log_msg "WAIT: Attempt $i/$MAX_RETRIES - Dependencies or DNS not ready."
    fi
   
    sleep $SLEEP_INTERVAL
done

log_msg "FATAL: Timeout reached. Connectivity could not be verified for $PEER_NAME."
exit 1