0

I have a FreeBSD machine with two NICs set up as follows:

  • em0 ---> IP set via DHCP (192.168.1.0/24). "home" domain
  • em1 ---> IP set statically (10.0.0.2). "lab" domain

For all intents and purposes, my home domain works fine. I can get to the internet and ping any host on the network. Routing also works, I can ping any host from either domain from the FreeBSD machine via IP but, I can only resolve names on the home network.

I created a /etc/resolvconf.conf file to prepend the search domain and name server to the resolv.conf file as follows:

search_domains="lab"
name_servers="10.0.0.10" 

I then update resolv.conf with the command:

$ sudo resolvconf -u

I can now resolve names on the lab network, but no longer on the home network. Manually editing the resolv.conf file and reversing the order of domains and name servers results in resolving home but not lab - exactly opposite.

How can I tell resolv.conf to use one DNS server for a particular domain (the statically set IP) and allow it to get the DNS info for the other IP via DHCP?


Just for reference....

/etc/rc.conf:

hostname="beastie1"
ifconfig_em0="DHCP"
ifconfig_em1="inet 10.0.0.2 netmask 255.255.255.0"
defaultrouter="192.168.1.1"

/etc/resolv.conf

# Generated by resolvconf
search lab home.
nameserver 10.0.0.10
nameserver 192.168.1.1

The DNS "server" on the lab domain 10.0.0.0 is nothing more than a cheap consumer Netgear router that does provide DHCP leases. I only have this set statically because it's a TFTP server for bootimages and I purposely set it to 10.0.0.2 for ease of use when trying to flash firmware updates on some Cisco gear.

  • Rather than try to straddle across two desperate DNS servers, you could try one of two alternative architectures... A simple solution would be to use /etc/hosts on the FreeBSD machine to resolve lab addresses, leaving DNS pointing to home only. This would only work for address resolution on the FreeBSD machine itself. Alternatively, run a DNS server on the FreeBSD machine. There are a number of ways to configure it such that unresolved domains are forwarded to the home DNS. – Richard Smith Dec 29 '17 at 10:18
  • @RichardSmith I agree that in my scenario, it would simple enough to manually edit /etc/hosts and solve the issue, but the reason for my approach/question is more academic in nature. I wanted to know if I was in a large network with a sizeable lab how I would accomplish this without having to modify /etc/hosts on every workstation in the lab. – Allan Dec 29 '17 at 11:05
  • Any workstation that can see both domains should use a DNS that can see both domains, so that unresolved requests are forwarded towards the internet. – Richard Smith Dec 29 '17 at 11:41
2

You are using entirely the wrong tool for the job.

This job is not done within the DNS client library. DNS client libraries are not complex enough to make decisions about routing queries to different sets of content DNS server based upon the name being looked up. DNS client libraries delegate the grunt work of query resolution, including this sort of stuff, to resolving proxy DNS servers. They are what implement split-horizon DNS service, which is the mechanism that you want here.

In your case, if you are using just what comes with FreeBSD (or its derivatives such as DragonFly BSD and TrueOS) out of the box, this will be an instance of unbound running locally.

You do three things:

  • You run unbound. Enable it to auto start with local_unbound_enable=YES in /etc/rc.conf in the usual way.
  • You configure unbound to perform split horizon DNS service. You do this with stub zones in unbound.conf for your lab.example.com. and your home.example.com. domains, denoting 10.0.0.10 and 192.168.1.1 as the content DNS servers for those domain names and everything below them.
  • You tell the DNS client library to query your server, and only your server. You have one nameserver line in /etc/resolv.conf (from one name_servers key-value pair in /etc/resolvconf.conf) that directs your DNS client library to talk to unbound.

Notes:

  • You do not use home. and lab.. These are real top-level domain names, that you do not own. home. is currently the subject of 10 applications at ICANN. Use a domain name that you own, not ones that you do not. Substitute that for example.com. in the above. No, you do not own local., localhost., dev., corp. or many others.

    If, for example, you owned radiantnexus.com., you would use home.allan.radiantnexus.com. and lab.allan.radiantnexus.com..

  • Adjust your search domains appropriately, if you want non-fully qualified domain names to be found in your local namespace.

    search_domains="home.allan.radiantnexus.com lab.allan.radiantnexus.com" to continue the aforegiven example.

  • Do not think that you can fall back to other people's resolving proxy DNS servers. A big mistake is to add in a resolving proxy DNS server provided by your off-the-shelf router, by your ISP, or by Google. All of the servers that your DNS client library directly talks to must provide the same view of the DNS name space, consistent with one another. Google Public DNS knows nothing about your internal namespace, for starters. If you want a fallback DNS server, you need another local DNS server somewhere, configured with your same split-horizon setup.
  • You also need stub zones for all of the non-public IPv6 and IPv4 address-to-name lookup names. There are actually quite a lot of these, and the lookup traffic for them really should not be leaking out over your/your organization's borders. And yes, they really should be stub zones, not local ones, if you want address-to-name lookup to work for the leases handed out by your combined DHCP/DNS server.

Bonus content

I use djbdns (as patched by … well … me) on FreeBSD.

  • The nosh toolset's configuration import subsystem sets me up with a dnscache@127.0.0.1 service that runs a local resolving proxy DNS server, and a tinydns@127.53.0.1 and an axfrdns@127.53.0.1 service that runs a local root content DNS server that dnscache@127.0.0.1 talks to.

    I enable these services with enable directives in /etc/system-control/presets/20-djbwares.preset:

    enable axfrdns@127.53.0.1
    enable cyclog@axfrdns
    enable tinydns@127.53.0.1
    enable cyclog@tinydns
    enable dnscache@127.0.0.1
    enable cyclog@dnscache
  • The local root content DNS server has in its database an admixture of the public . data, pulled from ICANN every year or so using axfr-get, and data for internal names beneath domain names that I own.

    % ls -dl root/{data*,p*,root*,Makefile}
    -rw-r--r--  1 root   wheel      968 16 Sep 09:43 root/Makefile
    -rw-r--r--  1 root   wheel   571334 28 Nov 00:33 root/data
    -rw-r--r--  1 root   wheel  1088169 28 Nov 00:33 root/data.cdb
    -rw-r--r--  1 root   wheel     3243 16 Sep 09:55 root/private
    -rw-r--r--  1 root   wheel     6962 28 Nov 00:32 root/public
    -rw-r--r--  1 root   wheel   560853 11 Mar  2017 root/root
    -rw-r--r--  1 root   wheel  3668733 11 Mar  2017 root/root.zone
    %

    The root/private file is where I will have the private data such as:

    =machine97.jdebp.eu:192.168.100.97:::lo
  • I clone the root/servers/@ file in dnscache@127.0.0.1 for the various split horizon prune points, so that dnscache knows to override any public content DNS server address information for those points that it might happen to be sent:

    % ls -dli root/servers/{@,C.E.F.ip6.arpa,machine97.jdebp.eu}
    352608 -rw-r--r--  46 root  wheel  11 23 Nov  2016 root/servers/@
    352608 -rw-r--r--  46 root  wheel  11 23 Nov  2016 root/servers/C.E.F.ip6.arpa
    352608 -rw-r--r--  46 root  wheel  11 23 Nov  2016 root/servers/machine97.jdebp.eu
    %
    (Actually, the nosh toolset sets up the private IP address ones for me, as standard. There's a whole chapter on what gets provided and the various ways to use it, in the nosh Guide.)

This is a private root setup. It is one of the other ways (there being several) of providing split-horizon DNS service with two content DNS servers. (In the aforegiven unbound set up, you have a multiple content DNS server arrangement as well; your local content DNS servers being the ones on 10.0.0.10 and 192.168.1.1 on other machines on your LAN rather than a private one on 127.53.0.1 on the machine itself.)

A private root also yields me the benefit of duff DNS query traffic for nonexistent stuff, from Google Chrome's probes to stuff that is trying to reverse-map IPv6 addresses in fec0::/12 and IPv4 addresses in 192.168.0.0/16, not escaping to Internet at large.

You can do a private root with unbound too. It is more complex than stub zones, though. I leave that as an exercise for the reader, it being beyond the scope of this answer.

Further reading

  • That's a lot to digest. I did want to clarify that the home and lab domains are private and I wasn't (in the least) expecting public DNS servers to handle those name resolutions. I should have added that my main firewall is a pfsense router with DNS enabled and the "cheap" Netgear is a DD-WRT upgrade with DNSmasq running to serve as a DNS server for the lab. – Allan Jan 1 '18 at 16:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.