I have identified the cause of an intermittent WireGuard startup failure. As I suspected, the problem occurs when the server address is specified as a hostname rather than an IP address, and DNS is unavailable during reboot, either because the network is not ready yet or because the DNS server itself is unreachable.
The error occurs after approximately 2.5 minutes in /usr/sbin/wireguard, at this line:
wg setconf wg0 /tmp/wireguard.conf || { echo "Error: Failed to apply wireguard configuration." >&2; exit 1; }
How to reproduce
This can be reproduced in real time on a camera connected to a local network:
- Disconnect the local network from the Internet (more precisely, block communication between the camera and the DNS server).
- Configure WireGuard to use a hostname as the server address.
- On the camera, execute:
chmod -x /etc/init.d/S98wireguard
- Reboot the camera.
- Run
wireguard on the camera and observe the output:
root@gk7205v300-imx335:~# wireguard
Try again: `${Endpoint}'. Trying again in 1.00 seconds...
Try again: `${Endpoint}'. Trying again in 1.20 seconds...
Try again: `${Endpoint}'. Trying again in 1.44 seconds...
Try again: `${Endpoint}'. Trying again in 1.73 seconds...
Try again: `${Endpoint}'. Trying again in 2.07 seconds...
Try again: `${Endpoint}'. Trying again in 2.49 seconds...
Try again: `${Endpoint}'. Trying again in 2.99 seconds...
Try again: `${Endpoint}'. Trying again in 3.58 seconds...
Try again: `${Endpoint}'. Trying again in 4.30 seconds...
Try again: `${Endpoint}'. Trying again in 5.16 seconds...
Try again: `${Endpoint}'. Trying again in 6.19 seconds...
Try again: `${Endpoint}'. Trying again in 7.43 seconds...
Try again: `${Endpoint}'. Trying again in 8.92 seconds...
Try again: `${Endpoint}'. Trying again in 10.70 seconds...
Try again: `${Endpoint}'. Trying again in 12.84 seconds...
Try again: `${Endpoint}'
Configuration parsing error
Error: Failed to apply wireguard configuration.
- Reconnect the camera to the Internet and restore the normal startup:
chmod +x /etc/init.d/S98wireguard
Possible solutions
The following are alternatives to the workaround proposed in #2242 (which suggested periodically monitoring the WireGuard connection and restarting it when it is detected as inactive).
-
Change WireGuard so that reading the configuration does not fail when the endpoint hostname cannot currently be resolved. The configuration should be accepted, and WireGuard should retry connecting later, similarly to what happens when an already established connection to the server is lost.
-
Start /usr/sbin/wireguard asynchronously from /etc/init.d/S98wireguard, and in /usr/sbin/wireguard, after all U-Boot variables have been read, wait for the DNS server to become available if the WireGuard server address is specified as a hostname:
ENDPOINT=$(fw_printenv -n wg_endpoint)
case "$ENDPOINT" in
[0-9]*)
;;
*)
HOST="${ENDPOINT%:*}"
while true; do
if nslookup "$HOST" >/dev/null 2>&1; then
break
fi
sleep 10
done
;;
esac
This approach avoids blocking the rest of the system startup while still allowing WireGuard to start automatically as soon as DNS becomes available.
P. S. I also believe that errors from initialization scripts should be logged to syslog, rather than being printed only to the console.
I have identified the cause of an intermittent WireGuard startup failure. As I suspected, the problem occurs when the server address is specified as a hostname rather than an IP address, and DNS is unavailable during reboot, either because the network is not ready yet or because the DNS server itself is unreachable.
The error occurs after approximately 2.5 minutes in
/usr/sbin/wireguard, at this line:How to reproduce
This can be reproduced in real time on a camera connected to a local network:
wireguardon the camera and observe the output:Possible solutions
The following are alternatives to the workaround proposed in #2242 (which suggested periodically monitoring the WireGuard connection and restarting it when it is detected as inactive).
Change WireGuard so that reading the configuration does not fail when the endpoint hostname cannot currently be resolved. The configuration should be accepted, and WireGuard should retry connecting later, similarly to what happens when an already established connection to the server is lost.
Start
/usr/sbin/wireguardasynchronously from/etc/init.d/S98wireguard, and in/usr/sbin/wireguard, after all U-Boot variables have been read, wait for the DNS server to become available if the WireGuard server address is specified as a hostname:This approach avoids blocking the rest of the system startup while still allowing WireGuard to start automatically as soon as DNS becomes available.
P. S. I also believe that errors from initialization scripts should be logged to syslog, rather than being printed only to the console.