我正在寻找内部/外部世界分离 DNS 的可能解决方案。问题是,这两个“世界”(实际上是不同的名称服务器集)部分重叠。
这是域的示例example.com
。
外部世界区域数据:
@ 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
内部世界区域数据:
@ 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
目的是要有某种“解析器”(IP 地址),可以为内部客户端解析两个世界。因此,当内部客户端访问时,portal.example.com
他需要访问内部网站。但他也需要访问www.example.com
。这种情况有什么可能的解决方案吗?
目前的解决方案是内部使用一些非常老旧的软件,这些软件从外部名称服务器执行(从 cron)AXFR,然后根据内部世界的数据对区域进行一些修改。这会产生一系列问题。(例如忽略内部世界的 TTL)
我能想到的最佳解决方案可能是一些能够首先查询内部名称服务器(仅包含内部 DNS 记录)的解析器/dns-proxy。如果内部 NS 返回 NXDOMAIN 或除带值的答案之外的任何内容,它应该尝试像解析器一样解析查询(或只是将查询转发给某个真正的解析器)。有类似的东西吗?
另一种显而易见的解决方案是更新/重写现代操作系统的内部 DNS 管理软件。并消除其已知问题(但我认为其中一些问题无法解决)。
或者还有其他我暂时想不到的方法吗?
答案1
如果内部客户端需要不同的主机数量很少,则一种选择是使用dnsmasq
。您可以指向dnsmasq
上游 DNS 服务器,然后覆盖特定条目。
像这样的配置将导致使用fordnsmasq
回复,但所有其他查询将被传递到上游服务器(可以从dnsmasq 配置中提取或使用指令明确指定):192.168.10.100
portal.example.com
/etc/resolv.conf
server=
address=/portal.example.com/192.168.10.100
答案2
感谢您的提示,尤其是@帕特里克·梅夫泽克.它给我指明了正确的方向。
如果有人感兴趣的话,示例配置文件。
因为coredns
它是/etc/coredns/Corefile
:
.:53 {
forward . 127.0.0.1:5353
alternate SERVFAIL,NXDOMAIN . 8.8.8.8:53
}
因为dnsdist
它是/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))
虽然不太好,但确实有效。您还可以dnsdist
在前面添加另一个实例,coredns
以不将所有查询发送到内部服务器...