DNS resolver Split Horizon

Hello all. I saw another topic on here, but to my understanding it didn’t seem to be looking for the same solution that I’m interested in.

For this question, assume the following conditions.

LAN network: 192.168.1.0/24

LAN network contains pfsense router at 192.168.1.1 running HAProxy listening on port 443 (pfsense gui is moved to a different port) that serves access via subdomains to various services (ie. Plex) running in docker containers in an unraid machine at 192.168.1.200.

vLan10: 192.168.10.0/24

vLan20: 192.168.20.0/24

Let’s say vlan10 is my WiFi network, and vlan20 is my IOT network.

Assume I have sufficient firewall rules in pfsense that all networks can access the HA proxy listening port and access the services using their subdomain with main domain address.

In an effort to create better separation of my LAN network and my IOT network vLan, I added a listening Ip address to HAProxy to also listen at port 443 on the subnet address of 192.168.20.1.

I would like all of my IOT devices to resolve my domain name, including all subdomains (like a wildcard) to ip address of 192.168.20.1, while also having that same domain and subdomains resolve to LAN address of 192.168.1.1 on all other networks.

This would prevent any IOT device ever having a need to cross into my LAN network at all.

I’ve arrived at this configuration in DNS resolver in pfsense, but it seems the only way to make this work properly is to list every subdomain and assign it an IP.

Is there a way to do this without having to list every subdomain?

DNS resolver example config:

server:
access-control-view: 192.168.1.0/24 main_view
access-control-view: 192.168.10.0/24 main_view
access-control-view: 192.168.20.0/24 iot_view

access-control: 192.168.1.0/24 allow
access-control: 192.168.10.0/24 allow
access-control: 192.168.20.0/24 allow

view:
  name: "main_view"
  view-first: yes
  local-zone: “mydomain.com” transparent
  local-data: "mydomain.com. IN A 192.168.1.1"
  local-data: "plex.mydomain.com. IN A 192.168.1.1"
  local-data: "otherservice.mydomain.com. IN A 192.168.1.1"

view:
  name: "iot_view"
  view-first: yes
  local-zone: “mydomain.com” transparent
  local-data: "mydomain.com. IN A 192.168.20.1"
  local-data: "plex.mydomain.com. IN A 192.168.20.1"

I’m so confused on what you are trying to accomplish. If you are looking at separation, then create an IP alias and bind your HAproxy to that. This way you aren’t having to open up firewall rules on your LAN network at all. Or any network for that matter.

the DNS thing is also weird. Not sure why that matters. So what if you can resolve DNS for a blocked internal service. the firewall has you covered. You aren’t gaining much security on this.

Maybe I am missing something?

Basically I have a single domain that I own and use for all my services through HAProxy with ssl certs

With a standard domain redirect, I can point that domain at HAProxy and everything works. But that means devices on separate subnets/vLans have to cross networks to access the LAN HAProxy IP via allow firewall rules.

So instead I want devices on my IOT network to resolve that domain to 192.168.20.1, and devices everywhere else to resolve that domain to 192.168.1.1

This would mean I don’t need to create any allow rules to my LAN network from the IOT network.

it’s more security from an internal standpoint of keeping IOT possibly insecure devices from attempting anything malicious on other networks/devices. Not so much an intruder poking around in the public net through the firewall.

try this:

server:
local-data: “mydomain.com redirect”
local-data: “.mydomain.com 86400 IN A 192.168.20.1”

I tried changing from

view:
name: “iot_view”
view-first: yes
local-zone: “mydomain.com” transparent
local-data: “mydomain.com. IN A 192.168.20.1”
local-data: “plex.mydomain.com. IN A 192.168.20.1”

to

view:
name: “iot_view”
view-first: yes
local-data: “mydomain.com redirect”
local-data: “.mydomain.com 86400 IN A 192.168.20.1”

EDIT: The correct syntax is

view:
name: “iot_view”
view-first: yes
local-zone: “mydomain.com.” redirect
local-data: “mydomain.com. 86400 A 192.168.20.1”

But then HAProxy logs badreq and noserv errors.

I ran packet capture, and I see that requests for Amazon servers are being directed to 192.168.20.1, which would tell me somehow the DNS of something like an Amazon server to 192.168.1.1. This would then have the firestick send an update request to HAProxy causing the noserv and badreq errors.

Just to be clear - what DNS resolver are you using? DNS resolver via pfsense?

Yes, dns resolver in pfsense.

Is 20.1 the dns server that iot devices get from dhcp? I am a bit confused on what you are trying to accomplish now and what have you done so far. Can you clarify?

Yes. Iot subnet is 192.168.20.0/24, dns server is 192.168.20.1.

What im trying to accomplish is to have devices on the 192.168.20.0/24 subnet resolve my domain to 192.168.20.1. While at the same time having devices on all other networks resolve that same domain to 192.168.1.1.

What I’ve tried is the setups posted above using transparent and redirect’s and it seems that transparent works, but I have to list every subdomain that I want that particular view to be able to access.

Redirect also seems to work, but for some reason seems to resolve more then just the specified domain to the redirect IP address causing errors in my HAProxy logs as it is directing domains that don’t pertain to my services.

Ok I’ve been doing a lot of diagnosing of what is happening and I believe I found the issue.

The device in question that seems to be causing the most issues is a fire stick on the Iot network.

the problem appears to stem from the fire stick device attempting to locate dns records for a particular domain. When it can’t find that domain, it runs it again with the “search domain” appended to the end of the original domain.

in the case of my recent packet capture these are my findings:

I have rash of noserv/badreq entries in my HAProxy log. I can see they originate from a device identified as 192.168.20.137

I ran packet capture for the same time period of those errors. Using tshark I discovered the SNI used in those requests is notify.firetv.bugsnag.appstore.a2z.com.

I further used tshark to then search the packet capture for dns request including “bugsnag” and found there are two domains that dns records were requested for.

This is the interesting part…..well to me I guess.

The first one is the same as the SNI attempting to connect to HAProxy, but the second one is notify.firetv.bugsnag.appstore.a2z.com.my domain.com

Apparently, the fire stick will ask for a DNS record for the domain it is looking for, and if it can’t find it, it appends the “search domain” as configured by the DHCP server.

I then confirmed this with tshark by searching the packet capture for the IP address returned for the dns queries and these were the results.

200.564598000 notify.firetv.bugsnag.appstore.a2z.com.mydomain.com 192.168.20.1

Which confirms the problem I’m observing

So I went into PFSense and I set the domain name, and domain search list to “void.arpa”

Now, these requests should have void.arpa appended to the end instead of my custom domain, and I shouldn’t have any more issues

Also the final configuration of the pfsense dns resolver view is:

view:
name: “iot_view”
view-first: yes
local-zone: “mydomain.com.” redirect
local-data: “mydomain.com. IN A 192.168.20.1”

you could always remove the search domain from your dhcp so that behavior stops.

After some more observation, I’ve reset the firestick and forgot and reconnected to my iot WiFi. It has a new lease and it’s on a new IP address.

I seem to still be getting dns requests with mydomain appended to the end along with others that have void.arpa appended.

Not really sure why it’s still appending mydomain as I’ve explicitly set void.arpa in both the search domain and domain name selections in the dhcp server.

I guess at this point, everything works, besides some errors being logged that for all intents and purposes seems to be relatively harmless.

It does bother my I can’t seem to get rid of those errors, but I think it’s good enough for now.

Ok after some time has passed it seems all the caches have finally cleared and I’m not longer getting any badreq/noserv log entries.

Final working example config for split horizon DNS is here:

server:

#LAN subnet
access-control-view: 192.168.1.0/24 main_view

#IOT subnet
access-control-view: 192.168.20.0/24 iot_view

#WIFI subnet
access-control-view: 192.168.30.0/24 main_view

#Guest Subnet
access-control-view: 192.168.40.0/24 guest_view

access-control: 192.168.1.0/24 allow

access-control: 192.168.20.0/24 allow

access-control: 192.168.30.0/24 allow

access-control: 192.168.40.0/24 allow

view:
name: “iot_view”
view-first: yes
local-zone: “mydomain.com.” redirect
local-data: “mydomain.com. IN A 192.168.20.1”

view:
name: guest_view
view-first: yes
local-zone: “mydomain.com.” redirect
local-data: “mydomain.com. IN A 192.168.40.1”

view:
name: main_view
view-first: yes
local-zone: “mydomain.com.” redirect
local-data: “mydomain.com. IN A 192.168.1.1”

You can avoid listing every subdomain by using a wildcard record in the Unbound view. For the iot_view, use something like:

local-zone: “mydomain. com” transparent

local-data: “mydomain.com. IN A 192.168.20.1”

local-data: “*.mydomain.com. IN A 192.168.20.1”

Then keep the corresponding wildcard pointing to 192.168.1.1 in main_view. The important part is making sure the wildcard is supported by the pfSense/Unbound version you’re running. If it isn’t, the alternative is to use an explicit local-zone configuration or another DNS resolver that supports wildcard responses in views. :face_blowing_a_kiss: