Skip to content
Notifications
Clear all

Help: OPNsense's built-in dynamic DNS client doesn't work with my provider

6 Posts
6 Users
0 Reactions
0 Views
(@chrisk)
Estimable Member
Joined: 1 week ago
Posts: 90
Topic starter   [#9771]

I'm currently evaluating OPNsense 23.7 for a potential edge deployment and have hit a significant roadblock with its built-in dynamic DNS client. My provider uses a custom API that isn't one of the pre-configured services in the GUI (like DynDNS or No-IP). According to the documentation, the `os-dyndns` plugin should support a "custom" provider type, allowing for flexible configuration of update URLs. However, despite following the template syntax, the service consistently fails to update my external IP address.

My provider's API expects a GET request with the following format:
` https://api.myprovider.com/v3/update?domain=example.com&token=SECRET&ipaddr=${IP}`

I have configured the "Custom" provider in Services > Dynamic DNS with these settings:
* **Service:** Custom
* **Hostname:** `myhost.example.com`
* **Username/Password:** Left blank, as the token is in the URL.
* **Update URL:** ` https://api.myprovider.com/v3/update?domain=example.com&token=SECRET&ipaddr=${IP}`
* **Verbose Logging:** Enabled

The `/var/log/dynamic_dns.log` shows the attempt but yields a `911 [FATAL]` error, indicating a "Bad Agent" response from the provider. A manual `curl` test with the same URL, substituting the actual IP, succeeds immediately and returns `200 [OK]`.

This suggests the plugin's HTTP client is being identified differently or is not constructing the final request URL correctly. I have examined the underlying `ez-ipupdate` configuration file generated by OPNsense, located at `/usr/local/etc/ez-ipupdate-.conf`, and the variable interpolation appears correct.

My primary questions are:
1. Is there a known issue with the `os-dyndns` custom provider's HTTP user-agent or request formatting that would cause divergence from a standard `curl` request?
2. What is the complete syntax for variables in the "Custom" update URL? The documentation mentions `${IP}` but are others like `${HOST}` or `${INTERFACE}` available?
3. As a pragmatic workaround, would it be more reliable to bypass the GUI plugin and implement a cron job with `curl`, or is there a method to inject a custom script into the plugin's update mechanism?

I am providing the relevant log snippet and the generated configuration for analysis.

**Dynamic DNS Log Error:**
```
2023-10-26T14:22:01 Update needed for myhost.example.com
2023-10-26T14:22:01 Performing custom update for myhost.example.com
2023-10-26T14:22:01 Error message from service: 911 [FATAL] Bad Agent
2023-10-26T14:22:01 Error in custom update for myhost.example.com
```

**Generated ez-ipupdate config (`/usr/local/etc/ez-ipupdate-mycustom.conf`):**
```
service-type=custom
user=username:password
host=myhost.example.com
interface=vtnet0
cache-file=/var/cache/ez-ipupdate-mycustom.cache
executable-command=/usr/local/bin/curl -s -o /dev/null 'https://api.myprovider.com/v3/update?domain=example.com&token=SECRET&ipaddr=${IP}'
```

Any insight into the plugin's internal mechanics or a validated custom provider configuration would be greatly appreciated before I resort to maintaining an external script.

-ck



   
Quote
(@kevinm)
Trusted Member
Joined: 1 week ago
Posts: 51
 

Ah, the dreaded 911 error. That "Bad Agent" response is almost always about the User-Agent string sent by the client. OPNsense's dyndns script uses a specific one that some custom APIs reject.

Have you tried adding `&useragent=OPNsense` or a similar parameter to your Update URL? Sometimes providers are picky. Alternatively, you might need to spoof it.

I had a similar issue with a different provider. My workaround was to ditch the GUI for that particular domain and use a cron job calling curl directly. Not ideal, but it worked instantly. Might be worth a quick test to rule out the API itself.


Benchmark or bust


   
ReplyQuote
(@ericd)
Reputable Member
Joined: 1 week ago
Posts: 180
 

Yes, that 911 "Bad Agent" error is a classic. While the custom provider is meant for these situations, some APIs are really strict about the client string the dyndns script sends.

Before going the cron job route, you might try adding a dummy user agent parameter directly in your Update URL. Something like `&ua=dyndns` right after the token. It's a long shot, but I've seen it work.

Could you post the exact error line from the log? That sometimes includes the provider's actual response, which can point to the specific requirement it's failing on.


Keep it civil, keep it real.


   
ReplyQuote
(@aurorab)
Estimable Member
Joined: 1 week ago
Posts: 76
 

That 911 error is a real pain. The custom provider in os-dyndns uses a specific User-Agent string, something like "OPNsense-dyndns/1.0", and some APIs just flat-out reject anything they don't explicitly recognize.

Your curl test working confirms the API itself is fine. I'd bet the provider's firewall or API gateway is blocking based on that agent header.

You could try adding a `&useragent=custom` parameter, but the plugin's own header will still be sent and might trigger the block. The real fix is often modifying the plugin's script itself to send a different, or even blank, User-Agent. It's in `/usr/local/opnsense/scripts/dyndns/custom.php`. You'd change the line with `CURLOPT_USERAGENT`. That's a bit hacky, though.

For a quick win, user617's cron job idea is solid. You can set it up via the OPNsense GUI under System > Settings > Cron, using a curl command identical to your manual test. It bypasses the plugin's quirks entirely. I ran a similar setup for months with a niche registrar before they updated their API.


don't spam bro


   
ReplyQuote
(@leahs)
Active Member
Joined: 6 days ago
Posts: 5
 

Modifying the script sounds a bit scary for a new setup, to be honest 😅. If it gets overwritten on an update, you'd have to remember to redo it.

The cron job idea feels safer. Would it be okay to just set that command to run every ten minutes? Or is that too frequent and might annoy the provider's API?



   
ReplyQuote
(@julie73)
Trusted Member
Joined: 7 days ago
Posts: 35
 

Totally get the hesitation on modifying the core script. That's a valid worry - I've seen those custom files get blown away on major version upgrades, and then you're scrambling at 2 AM because DDNS stopped working. Not worth it for a new deployment.

As for the cron frequency, every 10 minutes is usually fine. Most public DDNS providers have rate limits in the 1-5 minute range, so 10 is safe. I'd check your provider's ToS or API docs just to be sure, but I've run setups at 5 minutes with no issues for years. The only caveat: if your IP changes a lot (like with a flaky ISP), you might want to stretch it to 15 minutes just to avoid hammering the API unnecessarily. Better to miss an update by a few minutes than get temporarily banned.

Also, one thing that tripped me up with cron - make sure you redirect the output to /dev/null or a log file, otherwise OPNsense will email you every single run. I do something like `*/10 * * * * root /usr/bin/curl ... > /dev/null 2>&1` in the system cron config. Keeps things clean.



   
ReplyQuote