0

I am searching for possible solutions for splitted DNS for internal/external worlds. Thing is, those two "worlds" (in reality different sets of nameservers) are partialy overlaping.

Here is example for domain example.com.

External world zone data:

@       IN SOA          ns01.example.com. hostmaster.example.com. (
                                2022082908      ; Serial
                                10800           ; Refresh
                                3600            ; Retry
                                864000          ; Expire
                                10800 )        ; Minimum
                                
@       IN NS    ns01.example.com.
@       IN NS    ns02.example.com.
@       IN MX   50      smtp01.example.com.
@       IN MX   20      smtp02.example.com.
www     IN A    90.80.70.60
portal  IN A    90.80.70.60

Internal world zone data:

@       IN SOA          ins01.example.com. hostmaster.example.com. (
                                2022082908      ; Serial
                                10800           ; Refresh
                                3600            ; Retry
                                864000          ; Expire
                                10800 )        ; Minimum
                                
@       IN NS    ins01.example.com.
@       IN NS    ins02.example.com.
@       IN MX   50      exchange.example.com.
portal  IN A    192.168.10.100

What is a purpose is to have some "resolver" (IP address) which can resolve both worlds for internal clients. So when internal client is accessing portal.example.com he needs to go to internal website. But he also needs to have access to www.example.com. Are there any possible solution for this situation?

Current solution is some very old software on internal side, which is doing (from cron) AXFR from external nameserver and then do some modifications for a zone based on data in internal world. Which produces it's own set of problems. (for example ignoring TTL in internal world)

The best solution that I can imagine could be some resolver/dns-proxy which is able to query internal nameserver first (which would contain only internal DNS records). If internal NS returns NXDOMAIN or just anything besides answer with value, it should try to resolve query like resolver (or just forward query to some real resolver). Does something like that exists?

Another kinda obvious solution is to update/rewrite that internal DNS management software for modern OS's. And get rid of it's known problems (but some of them just cannot be solved I believe).

Or is there any other way that just does not come to my mind?

2
  • 1
    In the long run, you are better investing your time in fixing the systems that are not using the DNS correctly. Split views exist, but will most of the time create more problems than solution. In your case, if you duplicate www internally then it solves it, but you get lots of maintenance issues. Plus possible breakage of DNSSEC. Besides dnsmasq that is good enough for simple needs as @larsks answered, dnsdist is a also a swiss-knife kind of DNS utility, and should be able to do your logic of retries... but honestly it feels as the wrong solution for your problem. Aug 29, 2022 at 14:20
  • Thanks for the hint with dnsdist. This seemed like most promising possible solution. But I think it is not possible to send query to another pool in addResponseAction. I am able to drop packet when I do not recieve some data in ANSWER section, or return a SERVFAIL code. But it does not allow me to run query again to different servers pool. Maybe it's just impossible, or I am just missing some option how to do that.
    – Kisuke
    Sep 15, 2022 at 13:29

2 Answers 2

1

If the number of hosts that need to be different for internal clients is small, one option would be to serve those clients using dnsmasq. You could point dnsmasq at your upstream DNS server, and then override specific entries.

A configuration like this would cause dnsmasq to reply with 192.168.10.100 for portal.example.com, but all other queries would be passed on to an upstream server (which is either extracted from /etc/resolv.conf or specified explicitly with server= directives in your dnsmasq configuration):

address=/portal.example.com/192.168.10.100
1
  • Unfortunately in real it's hundreds of records in multiple (~20) zones. But seems like an option maybe.
    – Kisuke
    Aug 29, 2022 at 14:06
1

Thanks for the hints, especially to @Patrick Mevzek. It showed me right direction.

The solution that I found in the end is a combination of dnsdist and coredns.

Example config files if anyone is interested.

For coredns it is /etc/coredns/Corefile:

.:53 {
    forward . 127.0.0.1:5353
    alternate SERVFAIL,NXDOMAIN . 8.8.8.8:53
}

For dnsdist it is /etc/dnsdist/dnsdist.conf:

-- Set control console and secret key to control
-- to generate key use makeKey() command on dnsdist console (launched from shell - dnsdist -l)
controlSocket('127.0.0.1:5299')
setConsoleACL('127.0.0.1/32')
setKey("KEYHASH")

-- HOW TO CONNECT TO CONSOLE
-- Run command: dnsdist -k "ENCODED KEY" -c 127.0.0.1:5299

-- Set addressess and ports where to accept DNS queries
addLocal('127.0.0.1:5353')

-- Set web server with statistics and run it in specified port
-- to generate password hash use hashPassword() command on dnsdist console
webserver('0.0.0.0:8084')
setWebserverConfig({password="PASSWORDHASH", acl="10.0.0.0/8, 127.0.0.1, ::1"})

-- Add internal nameservers pool and set it's caching policy
newServer({address="10.0.0.253:53", pool="internal"})
newServer({address="10.0.0.254:53", pool="internal"})
internalpc = newPacketCache(10000, {maxTTL=86400, minTTL=0, temporaryFailureTTL=60, staleTTL=60, dontAge=false})
getPool("internal"):setCache(internalpc)

-- Set ACL to allow anyone to query
setACL({'::/0','0.0.0.0/0'})

-- Send all queries to internal DNS
addAction(AllRule(), PoolAction("internal"))

-- LUA function that simply returns SERVFAIL RCODE
function NoAnswerAction(dq)
    return DNSResponseAction.ServFail
end


-- If RESPONSE does not contain data in answer section, run LUA function
addResponseAction(NotRule(RecordsCountRule(DNSSection.Answer, 1, 999)), LuaResponseAction(NoAnswerAction))

It's not nice, but it works. You can also add another dnsdist instance in front of coredns to not send all queries to internal servers...

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .