跳转到内容
搜索 Rocky Linux 文档

    浏览当前文档目录

    Rocky 10:dnsmasq 做转发缓存,为什么第二条查询还是转发

    Rocky Linux 10.2 Server 组虚拟机,dnsmasq-2.90-7.el10_2。

    这台机器不权威任何域,只把查询转发给局域网内的 DNS(192.168.2.241)并缓存结果。截图:public/evidence/dnsmasq/rocky-forwarder.png。

    /etc/dnsmasq.d/lab.conf
    listen-address=192.168.2.243
    bind-interfaces
    server=192.168.2.241
    no-resolv
    cache-size=1000
    log-queries
    • server=:唯一上游;
    • no-resolv:忽略 /etc/resolv.conf,避免上游被系统配置覆盖;
    • cache-size=1000:缓存条目上限;
    • log-queries:把每次查询与命中写进 journal——这是排障的关键开关。

    用日志判断「有没有命中缓存」

    Section titled “用日志判断「有没有命中缓存」”
    $ dig @192.168.2.243 c1.lab.test A +short
    $ dig @192.168.2.243 c1.lab.test A +short
    $ journalctl -u dnsmasq --since "-40s" --no-pager | grep -E "c1"
    ... dnsmasq[11792]: query[A] c1.lab.test from 192.168.2.243
    ... dnsmasq[11792]: forwarded c1.lab.test to 192.168.2.241
    ... dnsmasq[11792]: query[A] c1.lab.test from 192.168.2.243
    ... dnsmasq[11792]: cached c1.lab.test is 192.168.2.241

    两次 query[A],第一次 forwarded、第二次 cached——这才是「缓存生效」的可靠证据。用 dig 的 Query time 看不出来:局域网里两者都是 0 msec。

    一个真实的坑:TTL 0 让缓存失效

    Section titled “一个真实的坑:TTL 0 让缓存失效”

    第一轮实验里,两次查询都是 forwarded,没有 cached。原因在上游:

    $ dig @192.168.2.241 web.lab.test A +noall +answer
    web.lab.test. 0 IN A 192.168.2.241

    上游用 address=/lab.test/… 生成的记录 TTL 为 0,下游缓存按规范不能保存,于是每次都回源。

    给上游加上 local-ttl=60 之后:

    $ dig @192.168.2.241 web.lab.test A +noall +answer
    web.lab.test. 60 IN A 192.168.2.241
    $ journalctl -u dnsmasq | grep c1 | tail -2
    ... query[A] c1.lab.test from 192.168.2.243
    ... cached c1.lab.test is 192.168.2.241

    结论:「转发器不缓存」的第一嫌疑不是 cache-size,而是上游给了 TTL 0。

    Rocky Linux 10.2:forwarded 与 cached 的日志对照

    1) ss -lunp | grep ':53 ' # 监听在哪个地址(bind-interfaces 时只在一个)
    2) dig @<本机> <name> A +noall +answer # 上游到底返回了什么 TTL
    3) journalctl -u dnsmasq -n 20 # forwarded / cached / 拒绝来源
    4) nft list ruleset | grep 53 # 防火墙是否拦了

    log-queries 没开的话,第 3 步什么都看不到——这是最容易浪费时间的点。

    • 只查一次就下结论:缓存命中要看第二次;
    • 用 127.0.0.1 测试:listen-address 之外会被拒绝,日志里连 query 都没有;
    • 上游 TTL 0:如上;
    • server= 与 no-resolv 只写一个:前者不写会去问系统解析器,后者不写可能被 NM 覆盖。

    练习:把缓存命中做成可重复的实验

    Section titled “练习:把缓存命中做成可重复的实验”
    Terminal window
    for i in 1 2; do dig @192.168.2.243 d1.lab.test A +short; done
    sudo journalctl -u dnsmasq --since "-30s" --no-pager | grep -E "d1"
    sudo systemctl restart dnsmasq
    dig @192.168.2.243 d1.lab.test A +short # 重启后第一次必然 forwarded

    检查:

    1. 前两次里至少第二次是 cached;
    2. 重启 dnsmasq 后第一次一定 forwarded(缓存是内存态);
    3. 上游 TTL 变化会直接改变缓存行为;
    4. 日志里没有 query 说明请求根本没到(地址/防火墙问题)。

    常见问题

    cache-size 设多大合适?

    家用/小办公室 1000–10000 足够;条目占用很小,瓶颈通常在 TTL 而非容量。

    能按域名指定不同上游吗?

    能,dnsmasq 2.86+ 支持 server=/domain/1.1.1.1 的域级转发。

    为什么重启后变慢?

    缓存是内存态,重启即清空;首个查询必然回源,属正常。