simplest way to forward to diff resolver based on src

Dear all,

I have a default unbound instance for the lan and I’d like to add two more specialized ones (python scripting is involved) and direct queries to those depending on client.

So all machines get default dns 1.1.1.1, but when queries come in on that machine unbound would look at the src and:

  • if in range 1.1.1.x just resolve it
  • if in range 1.1.2.x send it to 1.1.2.1
  • if in range 1.1.3.x send it to 1.1.2.3

I can’t see a simple way of doing that, the forward zones seems to be based on destination, not source, and a firewall would involve natting which isn’t great.
Also caching seems to be an issue, the fw zones are used if a response cannot be found from cache afaik. My scenario requires that requests from ranges 2 and 3 are never cached and requests always forwarded.

any common/clean way of doing this?

thanks,

Spike

Hi Spike
If you have one subnet 1.1.0.0/16, then it doesn't look supported (even
looking at dnsmasq as an intermediary). Usually the kind of access
control I'd imply from your question is done with subnets. Isolation is
often done for other reasons. If you have three subnets (and VLAN)
1.1.1.0/24, 1.1.2.0/24, and 1.1.3.0/24, then you can have three unique
Unbound instances. Each only listens on one interface respective of the
subnet. If they need to share local DNS, then you can add the necessary
forward clauses.

#example
server:
  # serve only subnet3
  interface: 1.1.3.1@53
  # accept forward from Unbound-subnet2 and Unbound-subnet1
  interface: 127.0.0.1@5303

# Get local DNS about subnet2
forward:
   name: "subnet2.example.com."
   forward-addr: 127.0.0.1@5302

forward:
   name: "2.1.1.in-addr.arpa."
   forward-addr: 127.0.0.1@5302

-Eric

There may be another way. Its a bit tricky and I don't know the
pitfalls. Unbound views and tags are new. You would 4 need Unbound
instances. The first instance would forward _ALL_ DNS zones to a dummy
forward host name. You can define that host name local data under tags
or views. The tags or views associate with query address. 3 other
Unbound instances would do the real work, only listening on unusual
local host addresses (127.0.1.1, 127.0.1.2, 127.0.1.3).

# example leading dummy instance
server:
   define-tags: "group1 group2 group3"
   access-control-view: 1.1.1.0/24 group1
   access-control-view: 1.1.2.0/24 group2
   access-control-view: 1.1.3.0/24 group3

view:
   name: group1
   local-zone: example.com transparent
   local-data: "ghost-ns.example.com. 3600 IN A 127.0.1.1"

view:
   name: group2
   local-zone: example.com transparent
   local-data: "ghost-ns.example.com. 3600 IN A 127.0.1.2"

view:
   name: group3
   local-zone: example.com transparent
   local-data: "ghost-ns.example.com. 3600 IN A 127.0.1.3"

# This _ALL_ zone forward host will resolve respective of view
forward:
   name: "."
   forward-host: "ghost-ns.example.com"

Hi,

AFAIK Unbound doesn't have "view" functionality associating
multiple cache/resolver instances.

One of way to implement such "view" function is running
multiple Unbound instances in combination with dnsdist ( http://dnsdist.org ):

-- dnsdist.conf

-- queries from 1.1.1.0/24 are forwarded to 192.0.2.1.
newServer({address="192.0.2.1", pool="dns1"})
pc1 = newPacketCache(100000)
getPool("dns1"):setCache(pc1)
client_dns1 = newNMG()
client_dns1:addMask("1.1.1.0/24")
addAction(NetmaskGroupRule(client_dns1), PoolAction("dns1"))

-- queries from 1.1.2.0/24 are forwarded to 192.0.2.2
newServer({address="192.0.2.2", pool="dns2"})
pc2 = newPacketCache(100000)
getPool("dns2"):setCache(pc2)
client_dns2 = newNMG()
client_dns2:addMask("1.1.2.0/24")
addAction(NetmaskGroupRule(client_dns2), PoolAction("dns2"))

-- queries from 1.1.3.0/24 are forwarded to 192.0.2.3
newServer({address="192.0.2.3", pool="dns3"})
pc3 = newPacketCache(100000)
getPool("dns3"):setCache(pc3)
client_dns3 = newNMG()
client_dns3:addMask("1.1.3.0/24")
addAction(NetmaskGroupRule(client_dns3), PoolAction("dns3"))

-- the others are REFUSED.
addAction(AllRule(), RCodeAction(5))

setACL({})
addACL("0.0.0.0/0")
addACL("::0/0")