Skip to content

Proposal: Make WireGuard startup resilient to temporary DNS unavailability #2319

Description

@usa-

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:

  1. Disconnect the local network from the Internet (more precisely, block communication between the camera and the DNS server).
  2. Configure WireGuard to use a hostname as the server address.
  3. On the camera, execute:
chmod -x /etc/init.d/S98wireguard
  1. Reboot the camera.
  2. 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.
  1. 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).

  1. 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.

  2. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions