How to prevent OPNsense Web UI from responding directly?

Started by TarteTatin, January 23, 2025, 06:33:44 AM

Previous topic - Next topic
January 23, 2025, 06:33:44 AM Last Edit: January 25, 2025, 08:02:18 PM by TarteTatin Reason: not solved actually
Hello,

I have a setup where my OPNsense router and firewall is also running Unbound DNS for internal name resolution. I am using an external HAProxy instance (on a VM) to handle reverse proxying and SSL termination for all my services, including the OPNsense Web UI.

  • Unbound DNS on OPNsense has an override configured to redirect requests for the domain opnsense.mydomain.com to the IP address of the external HAProxy server.
  • HAProxy has a valid Let's Encrypt certificate and is responsible for handling requests for opnsense.mydomain.com.
  • The OPNsense Web UI is only accessible via LAN and is configured with the default self-signed certificate.

When I try to access the OPNsense Web UI using the domain name opnsense.mydomain.com from a device on my LAN:
  • The request bypasses HAProxy and is answered directly by OPNsense because it identifies the domain as its own.
  • This causes the browser to display a certificate error since OPNsense serves its self-signed certificate instead of routing the request to HAProxy, which has the Let's Encrypt certificate.

I need OPNsense to never respond directly to requests for its Web UI, even if it resolves the domain as pointing to itself. Instead, it should always forward these requests to HAProxy as defined in the Unbound DNS override.

How can I achieve that?

I look for only allowing the IP address of my HAproxy server in System: Settings: Administration, with DNS Rebind Check checked or unchecked, and using Listen Interfaces to only allow the IP address of my HAProxy server, but could only chose my LAN interface, and OPNsense and the HAProxy server are on the same LAN. So i am stuck here.

Thanks for your help!

Move the web UI to a port other than 443 and disable the HTTP --> HTTPS redirect.
Deciso DEC750
People who think they know everything are a great annoyance to those of us who do. (Isaac Asimov)

OP, do you have your (System -> Settings -> General -> System -> Domain) set to "mydomain.com"? If so, I think you may be confused because Unbound host overrides are not really true overrides - they are more like additional host records in the local DNS server. If you add a host override for "opnsense.mydomain.com", a DNS query for that would return that additional record BUT ALSO the default (automatically generated) system records for your firewall itself, and your browser may choose to use one of the default records. You could potentially hack around this with (Services -> Unbound DNS -> General -> Do not register system A/AAAA records).

I would caution a bit against convoluting admin access to your firewall, though - it may come back to bite you some day, when something goes wrong, and you can't easily get into your firewall to fix it.

Personally I think it's probably not a great idea to try to have "mydomain.com" resolve differently internally vs externally. I use "subdomain.lan" as my internal domain (I have a couple of locations, with different subdomains). Proxied stuff could still be accessed using "mydomain.com" URLs by enabling (Firewall -> Settings -> Advanced -> Reflection for port forwards). If your browser might be on the same LAN subnet as the proxy, you may also need "Automatic outbound NAT for Reflection", though that has the side-effect of making internal connections appear to come from the firewall's address, not the actual client's. I have my proxy in an isolated VLAN, which mitigates that issue, as well as being a bit more secure (I have firewall rules to control what the proxy host can access internally).

Quote from: Patrick M. Hausen on January 23, 2025, 07:16:16 AMMove the web UI to a port other than 443 and disable the HTTP --> HTTPS redirect.
Thank you Patrick, I did just that and added the port to the OPNsense HAProxy backend and it seems to work. Great!


Quote from: dseven on January 23, 2025, 10:49:40 AMOP, do you have your (System -> Settings -> General -> System -> Domain) set to "mydomain.com". If so, I think you may be confused because Unbound host overrides are not really true overrides - they are more like additional host records in the local DNS server. If you add a host override for "opnsense.mydomain.com", a DNS query for that would return that additional record BUT ALSO the default (automatically generated) system records for your firewall itself, and your browser may choose to use one of the default records.
It is exactly my situation. It sometimes use the Unbound DNS override, but almost all times the system DNS record.

Quote from: dseven on January 23, 2025, 10:49:40 AMYou could potentially hack around this with (Services -> Unbound DNS -> General -> Do not register system A/AAAA records).
For now, I will try Patrick's solution. If I encounter some problem's with this setup, I will look into it, thanks.

Quote from: dseven on January 23, 2025, 10:49:40 AMI would caution a bit against convoluting admin access to your firewall, though - it may come back to bite you some day, when something goes wrong, and you can't easily get into your firewall to fix it.
In this case, I just have to use https://ip_address:port or https://opnsense.mydomain.com:port to bypass HAProxy. It's a simple home setup. But it's always great to have explanations to become more aware of weaknesses.
I also have ssh access with a key (no password).

Quote from: dseven on January 23, 2025, 10:49:40 AMPersonally I think it's probably not a great idea to try to have "mydomain.com" resolve differently internally vs externally. I use "subdomain.lan" as my internal domain (I have a couple of locations, with different subdomains). Proxied stuff could still be accessed using "mydomain.com" URLs by enabling (Firewall -> Settings -> Advanced -> Reflection for port forwards). If your browser might be on the same LAN subnet as the proxy, you may also need "Automatic outbound NAT for Reflection", though that has the side-effect of making internal connections appear to come from the firewall's address, not the actual client's. I have my proxy in an isolated VLAN, which mitigates that issue, as well as being a bit more secure (I have firewall rules to control what the proxy host can access internally).
Yes, I wanted to use the same domain externally and internally, but it makes my HAProxy configuration more complex. I do not have much time to rethink my setup at the moment, but you're right, it would be more secure to use another subnet for all my servers.
Not sure to understand "reflection" now, but I will dig into it.
Thank you.

Quote from: TarteTatin on January 23, 2025, 06:33:44 AMHello,
...
I need OPNsense to never respond directly to requests for its Web UI, even if it resolves the domain as pointing to itself. Instead, it should always forward these requests to HAProxy as defined in the Unbound DNS override.
...

Let me rephrase: you definitely want OPNsense to respond to requests for its WebUI, otherwise HAProxy won't be able to serve that content.
By changing the port, you just made sure that it's not served on the default HTTPS port.
IOW, if you just type the OPNsense IP or a FQDN that resolves to that IP, you'll get a timeout...

Your problem appears to be that sometimes opnsense.mydomain.com resolves to an IP associated with OPNsense.
Since you seem to want to access it remotely as well, I assume you have HTTP* port forwarded to HAProxy and a wildcard DNS pointing at your WAN IP.
If your local override is not picked up (e.g. asking from a public DNS server), your request will match the wildcard and return the WAN IP.
That's when reflection could come in handy (check out the help tip in Firewall > Settings > Advanced > Reflection for port forwards).

The OPNsense WebGUI is unaware of HAProxy. It never forwards requests there.
It's the other way around. opnsense.mydomain.com resolves to HAProxy's IP and requests to HAProxy are forwarded to OPNsense.
Classic reverse proxy behavior.

With Patrick's change, you've made sure that when opnsense.mydomain.com resolves incorrectly (to OPN), your browser will timeout (instead of getting content with the untrusted cert). Then you can investigate why DNS resolution failed... And you can still access OPN at IP:port.

And you're not helping by having your OPNsense host name set to opnsense.mydomain.com either (pointing to LAN IP).
That's now a third possible IP depending on who you ask (AGH for one seems to rewrite queries for the host's FQDN, and maybe other entries in the hosts file).

Thank you, Eric.

In my case, I don't access OPNsense from WAN, do you think it can request the public DNS before using the Unbound overrides from my LAN?

I just wanted to use a domain I own for all my services, to avoid the security advertisement of the self-signed certificates.

If I understand correctly, the proper way to configure my setup would be to assign OPNsense a different hostname or domain, using a local domain instead of the one I currently use, for example?

Not to sure to understand all at the moment, but I have some sleep to catch up. :p

January 24, 2025, 04:46:41 PM #7 Last Edit: January 25, 2025, 05:00:11 AM by TarteTatin Reason: not working
In System: Settings: General, I have changed my domain to home.arpa.
And in System: Settings: Administration, I also had to check :
- Disable DNS Rebinding Checks
- Disable HTTP_REFERER enforcement check

[Edit] In fact, it's not working after flushing DNS cache. :/

AND, I lose Internet connection if I check Do not register system A/AAAA records in Services: Unbound DNS: General.

Assuming:
- WAN_IP is the OPN WAN IP
- LAN_IP is the OPN LAN IP
- PORT is the Web GUI port
- HA_IP is the HAProxy IP

If your OPNsense name is opnsense.mydomain.com, there's a line in /etc/hosts:
LAN_IP OPNsense OPNsense.mydomain.comIf Unbound is set to register system A/AAAA records, it will include that mapping (opnsense.mydomain.com -> LAN_IP)

Additionally, you have an Unbound host override that says: opnsense.mydomain.com -> HA_IP
Per dseven, an Unbound DNS lookup for opnsense.mydomain.com will return HA_IP & LAN_IP (and the browser will use one of them).
Hence the recommendation to either change the host name or not register the system name, so Unbound will return HA_IP only.
AFAIK, DNS Rebinding check had to be disabled because you have Unbound query an external name (ending in .com) and return a private IP.
Check the link in that option's info tip for details.

Per reply #3, you sometimes access HAProxy externally for various services hosted internally, so I suspect you have *.mydomain.com -> WAN_IP in a public DNS.
And obviously you have HTTPS port forward to HAProxy, and HAProxy configured to forward to LAN_IP:PORT for opnsense.mydomain.com.
If your browser gets DNS from Unbound, it should get HA_IP (modulo the above) because it's more specific.
Any other DNS server will reply WAN_IP, which is fine when remote, but less so internally.

Externally, you have no choice but to access the web Gui but using https://WAN_IP or https://opnsense.mydomain.com (since the Gui does NOT listen on WAN nor do you have FW rule allowing direct access).
Internally:
https://WAN_IP:PORT would work if the Gui was left to listen on all interfaces (recommended, FW is used for control). Served by OPN internally hence cert warning.
https://WAN_IP would work with NAT reflection (details in dseven's reply). Served by HAProxy so NO cert warning.
https://LAN_IP:PORT has to work (otherwise HAProxy will timeout). Served by OPN internally hence cert warning.
https://LAN_IP will timeout if PORT != HTTPS(443).
https://HA_IP should work and is served by HAProxy, obviously (NO cert warning).

So depending on what the DNS lookup for opnsense.mydomain.com returns (one of the 3 IPs), you get a timeout, a cert warning or the Gui (No warning).
I suspect the HTTP_REFERER has to be disabled because you're accessing the Gui via a proxy.