Andrew Mercer
on this page

Overview

A residential connection's public IP can change without warning. Anything that references it directly, such as WireGuard client configs, breaks when it does. Dynamic DNS fixes this: the firewall reports its current public IP to a DNS provider, and clients connect to a stable hostname instead of an IP.

This guide covers:

  1. Installing the os-ddclient plugin on OPNsense, including when it doesn't show up in the plugin list
  2. Creating a No-IP hostname and DDNS Key
  3. Configuring OPNsense to keep the hostname updated
  4. Switching WireGuard clients from an IP endpoint to the hostname

Throughout, myhome.ddns.net stands in for your No-IP hostname and 51820 for your WireGuard listen port.


1. Install os-ddclient

Via the GUI

  1. System → Firmware → Status → Check for updates. The Plugins tab is often empty until the firmware catalogue has been refreshed at least once. Apply any pending updates first, because plugins are built against the current release.
  2. System → Firmware → Plugins, find os-ddclient, and click + to install.

Via the shell (if the plugin list is empty)

From the console (option 8) or SSH:

pkg update -f
pkg install os-ddclient

If pkg update fails, the firewall can't reach the package mirror. Check:

  • System → Settings → General: DNS servers are configured.
  • Interfaces → Diagnostics → DNS Lookup: pkg.opnsense.org resolves.
  • System → Firmware → Settings: the mirror and release type (Community or Business) are correct.

A successful install ends with output like:

[8/8] Installing os-ddclient-1.28...
Migrated OPNsense\DynDNS\DynDNS from 0.0.0 to 1.5.1
Reloading template OPNsense/ddclient: OK

Ignore the post-install ddclient message. The FreeBSD package notice tells you to edit /usr/local/etc/ddclient.conf and set ddclient_enable="YES" in /etc/rc.conf. Don't. On OPNsense, the plugin generates the config from the GUI and manages the service itself. Manual edits are overwritten or conflict with the plugin.

Hard-refresh the browser (Ctrl+F5) so the Services → Dynamic DNS menu appears.


2. Set Up the Hostname on No-IP

No-IP requires a DDNS Key for dynamic updates. A DDNS Key is a separate username and password pair scoped to your hostnames. Your account login is not used.

Create or edit the hostname

  1. Log in at noip.com and go to DNS Records.
  2. For a new hostname, click Create Hostname: - Enter the host (e.g. myhome) and pick a domain (e.g. ddns.net). - Leave the record type as A. - The IPv4 field is pre-filled with your current public IP.
  3. Tick Enable Dynamic DNS, then click Create / Save With DDNS Key. For an existing hostname, click it, tick Enable Dynamic DNS, and save.

Generate the DDNS Key

  1. Pick any client or OS option (OPNsense isn't listed, which doesn't matter) and click Next.
  2. Enter a description such as opnsense, then click Generate DDNS Key.
  3. Copy the username and password immediately. The password is shown only once and can't be recovered, only reset.

Keys can be managed later under Keys/Groups.

Free tier: free accounts get one DDNS hostname, which must be confirmed monthly via an emailed link or it expires.


3. Configure Dynamic DNS in OPNsense

General settings

Services → Dynamic DNS → Settings → General

  • Tick Enable.
  • Backend: if noip doesn't appear in the service list below, switch this to ddclient. The native backend supports fewer providers.
  • Save.

Add the account

Accounts tab → +

Field Value
Enabled ✔
Service noip
Username DDNS Key username (not your No-IP email)
Password DDNS Key password
Hostname(s) myhome.ddns.net
Check ip method Interface if WAN has a public IP; noip-ipv4 if behind a modem/router
Interface to monitor WAN
Description No-IP

Save, then click Apply.

If updates fail with your real hostname, No-IP's documentation says to use all.ddnskey.com as the hostname with DDNS Key credentials. This updates every hostname attached to the key.

Choosing the check IP method

  • Interface: reads the IP directly off WAN. It's fast and fully local, but only correct when WAN holds a public IP.
  • Web check (noip-ipv4, etc.): asks an external service what your public IP is. Use this when OPNsense sits behind another NAT device (ISP modem in router mode), because WAN then holds a private RFC1918 address.

4. Verify DDNS

In the GUI, the account row should show Current IP and an Updated timestamp within a minute or two.

From the shell:

# Service running?
service ddclient status

# Generated config
cat /usr/local/etc/ddclient.conf

# Hostname resolves to your public IP?
drill myhome.ddns.net

On No-IP, the hostname's IP under DNS Records should match your public IP.

If something's wrong, check Services → Dynamic DNS → Log File. Most failures are authentication errors from a mistyped DDNS Key.


5. Point WireGuard at the Hostname

Switching to a hostname does not require new keys. Only the Endpoint line in each client config changes.

Existing clients

Change:

[Peer]
Endpoint = 203.0.113.45:51820

to:

[Peer]
Endpoint = myhome.ddns.net:51820

Leave everything else as it is: keys, AllowedIPs, Address, and DNS.

Linux (wg-quick)

sudo sed -i 's/^Endpoint = .*/Endpoint = myhome.ddns.net:51820/' /etc/wireguard/wg0.conf
sudo systemctl restart wg-quick@wg0

Linux (NetworkManager)

The simplest reliable approach is to re-import the edited config:

nmcli connection delete wg0
nmcli connection import type wireguard file /path/to/wg0.conf

Android / iOS

Open the tunnel, tap Edit, change Endpoint in the peer section, and save.

Windows / macOS

Select the tunnel, click Edit, change the Endpoint line, and save.

New clients: OPNsense Peer generator

  1. VPN → WireGuard → Peer generator
  2. Select the server Instance.
  3. Set Endpoint to myhome.ddns.net:51820. Every config generated from here includes it.
  4. Fill in the name, tunnel address, DNS, and allowed IPs.
  5. Copy the config or scan the QR code, then click Store and generate next.
  6. Click Apply on the WireGuard page.

Verify the tunnel

dig +short myhome.ddns.net   # matches your current public IP
sudo wg show                 # "latest handshake" should be recent

On OPNsense, VPN → WireGuard → Status shows handshakes from the server side.


6. Caveat: WireGuard Resolves DNS Once

WireGuard resolves the endpoint hostname when the tunnel comes up and then keeps using that IP. If your public IP changes while a client is connected, the tunnel stalls until it's restarted.

  • Mobile clients usually recover on their own, since they reconnect when switching networks.
  • Always-on Linux clients can periodically re-resolve using reresolve-dns.sh from wireguard-tools' contrib directory:

sh /usr/share/doc/wireguard-tools/examples/reresolve-dns/reresolve-dns.sh wg0

Run it every couple of minutes from a systemd timer:

```ini # /etc/systemd/system/[email protected] [Unit] Description=Re-resolve WireGuard endpoints for %i

[Service] Type=oneshot ExecStart=/usr/share/doc/wireguard-tools/examples/reresolve-dns/reresolve-dns.sh %i ```

```ini # /etc/systemd/system/[email protected] [Unit] Description=Periodically re-resolve WireGuard endpoints for %i

[Timer] OnBootSec=1min OnUnitActiveSec=2min

[Install] WantedBy=timers.target ```

sh sudo systemctl daemon-reload sudo systemctl enable --now [email protected]

The script's path varies by distro, and some packages don't ship it. If it's missing, copy it from the wireguard-tools repository.


Summary

Step Where
Install plugin pkg install os-ddclient or Firmware → Plugins
Hostname + DDNS Key noip.com → DNS Records
DDNS account Services → Dynamic DNS → Accounts
Existing WG clients Change Endpoint to hostname:port
New WG clients VPN → WireGuard → Peer generator
Long-lived Linux peers reresolve-dns.sh on a systemd timer