Remote access stopped after moving from UniFi to OPNsense router

I switched routers, from UniFi to OPNSense and now I’m having issues accessing my HomeAssistant server remotely. I’m struggling to work out why it’s not working.

I have HomeAssistant running with DuckDNS addon.

I’ve setup NAT Port Forwarding in OPNsense. Forwarding 8123 and 443 from WAN to to the local IP of the HomeAssistant server on port 8123.

I’ve checked on https://canyouseeme.org/ that both 443 and 8123 show as open. :white_check_mark: Port Forwarding looks like it’s working correctly.

I can access HA on my local IP on the :8123 port over HTTPS. I obvs, get an SSL cert warning.

I’ve also checked DuckDNS, which is showing the correct IP for my domain name. And when I use a nslookup the DuckDNS name resolves to the correct public IP address. I also tried a port scanner with domain name resolution, using that to scan the DuckDNS domain name on ports 8123 and 443. It shows both as open.

When I try to access the duckdns URL xxxxx.duckdns.org:8123 or :443, I get a HomeAssistant logo and spinnning / Loading Data. But nothing ever happens. It’ll then turn to the Unable to connect to Home Assistant...

It looks like DuckDNS addon in HomeAssistant is managing to correctly connect and issue new SSL certs via LetsEncrypt.

What else can I try or where can I look to try and find out what’s going wrong? I’m stumped.

DuckDNS Addon Log

image

My DuckDNS Log

s6-rc: info: service legacy-cont-init successfully started
s6-rc: info: service legacy-services: starting
s6-rc: info: service legacy-services successfully started
# INFO: Using main config file /data/workdir/config
+ Account already registered!
[08:08:23] INFO: Renew certificate for domains: xxxxxxxxx.duckdns.org and aliases: 
# INFO: Using main config file /data/workdir/config
Processing xxxxxxxxx.duckdns.org
 + Checking domain name(s) of existing cert... unchanged.
 + Checking expire date of existing cert...
 + Valid till Aug 10 01:43:05 2024 GMT (Longer than 30 days). Skipping renew!
s6-rc: info: service legacy-services: stopping
s6-rc: info: service legacy-services successfully stopped
s6-rc: info: service legacy-cont-init: stopping
s6-rc: info: service legacy-cont-init successfully stopped
s6-rc: info: service fix-attrs: stopping
s6-rc: info: service fix-attrs successfully stopped
s6-rc: info: service s6rc-oneshot-runner: stopping
s6-rc: info: service s6rc-oneshot-runner successfully stopped
s6-rc: info: service s6rc-oneshot-runner: starting
s6-rc: info: service s6rc-oneshot-runner successfully started
s6-rc: info: service fix-attrs: starting
s6-rc: info: service fix-attrs successfully started
s6-rc: info: service legacy-cont-init: starting
s6-rc: info: service legacy-cont-init successfully started
s6-rc: info: service legacy-services: starting
s6-rc: info: service legacy-services successfully started
# INFO: Using main config file /data/workdir/config
+ Generating account key...
+ Registering account key with ACME server...
+ Fetching account URL...
+ Done!
[08:21:34] INFO: Renew certificate for domains: xxxxxxxxx.duckdns.org and aliases: 
# INFO: Using main config file /data/workdir/config
 + Creating chain cache directory /data/workdir/chains
Processing xxxxxxxxx.duckdns.org
 + Creating new directory /data/letsencrypt/xxxxxxxxx.duckdns.org ...
 + Signing domains...
 + Generating private key...
 + Generating signing request...
 + Requesting new certificate order from CA...
 + Received 1 authorizations URLs from the CA
 + Handling authorization for xxxxxxxxx.duckdns.org
 + 1 pending challenge(s)
 + Deploying challenge tokens...
OK + Responding to challenge for xxxxxxxxx.duckdns.org authorization...
 + Challenge is valid!
 + Cleaning challenge tokens...
OK + Requesting certificate...
 + Checking certificate...
 + Done!
 + Creating fullchain.pem...
 + Done!
s6-rc: info: service legacy-services: stopping
s6-rc: info: service legacy-services successfully stopped
s6-rc: info: service legacy-cont-init: stopping
s6-rc: info: service legacy-cont-init successfully stopped
s6-rc: info: service fix-attrs: stopping
s6-rc: info: service fix-attrs successfully stopped
s6-rc: info: service s6rc-oneshot-runner: stopping
s6-rc: info: service s6rc-oneshot-runner successfully stopped
s6-rc: info: service s6rc-oneshot-runner: starting
s6-rc: info: service s6rc-oneshot-runner successfully started
s6-rc: info: service fix-attrs: starting
s6-rc: info: service fix-attrs successfully started
s6-rc: info: service legacy-cont-init: starting
s6-rc: info: service legacy-cont-init successfully started
s6-rc: info: service legacy-services: starting
s6-rc: info: service legacy-services successfully started
# INFO: Using main config file /data/workdir/config
+ Account already registered!
[10:35:25] INFO: Renew certificate for domains: xxxxxxxxx.duckdns.org and aliases: 
# INFO: Using main config file /data/workdir/config
Processing xxxxxxxxx.duckdns.org
 + Checking domain name(s) of existing cert... unchanged.
 + Checking expire date of existing cert...
 + Valid till Aug 19 06:21:41 2024 GMT (Longer than 30 days). Skipping renew!
s6-rc: info: service legacy-services: stopping
s6-rc: info: service legacy-services successfully stopped
s6-rc: info: service legacy-cont-init: stopping
s6-rc: info: service legacy-cont-init successfully stopped
s6-rc: info: service fix-attrs: stopping
s6-rc: info: service fix-attrs successfully stopped
s6-rc: info: service s6rc-oneshot-runner: stopping
s6-rc: info: service s6rc-oneshot-runner successfully stopped
s6-rc: info: service s6rc-oneshot-runner: starting
s6-rc: info: service s6rc-oneshot-runner successfully started
s6-rc: info: service fix-attrs: starting
s6-rc: info: service fix-attrs successfully started
s6-rc: info: service legacy-cont-init: starting
s6-rc: info: service legacy-cont-init successfully started
s6-rc: info: service legacy-services: starting
s6-rc: info: service legacy-services successfully started
# INFO: Using main config file /data/workdir/config
+ Account already registered!
[10:46:14] INFO: Renew certificate for domains: xxxxxxxxx.duckdns.org and aliases: 
# INFO: Using main config file /data/workdir/config
Processing xxxxxxxxx.duckdns.org
 + Checking domain name(s) of existing cert... unchanged.
 + Checking expire date of existing cert...
 + Valid till Aug 19 06:21:41 2024 GMT (Longer than 30 days). Skipping renew!

additional info

I can access HomeAssistant remotely from my phones cellular. The issue seems to be restricted to access it remotely via the DuckDNS url from within my LAN.

You can’t forward 2 external ports to an internal port. You’d need a proxy. Otherwise you should only have 443 to 8123 and you’ll only be able to access HA via your DuckDNS url.

I’ve disabled the Port Forward rule for WAN:8123 → HA:8123. So there;s now only 1x port forward from WAN:443 → HA-Local:8123.

However, I’m still unable to access the HA server remotely from inside my LAN.

Try accessing from your phone, outside your network. If that works, then it’s set up properly and your router doesn’t support nat-loopback.

Looks like OPNSense doesn’t support it out of the box.

With only 1x port forward rule set to WAN:443 → HA-Local:8123, I’m still able to access HA remotely via the DuckDNS issue.

This has helped to narrow down the issue. Like you said, I presume it’s NAT Loopback that’s not working.

I’ve tried adding the NAT reflection: enabled in the Port Forward rule in OPNSense as suggested in that link. But that hasn’t resolved this issue. But I can try and find support in the OPNSense community.

Hi Sentur

I just canged from USG 3P to UCG ultra, then my reverse proxy for e.g. hass stopped working. I have heard in another forum that it is a known problem at least at UCG.

Have you found a solution?

Yes I did. Just not had the time to fully detail out how I got it working.

As petro mentioned, it was a specific OPNsense issue. Where NAT loopback / reflection / hairpin / 1:1 isn’t set as default in OPNsense. Once I’d set this correctly, I was able to access HomeAssistant on the external URL from my LAN.

Unsure if this would be the cause in your case. I have no experience with the UniFi UCG Ultra. Check if you can access the proxy from another location like a mobile connection.