kakkotetsu

Unbound の cache-max-ttl 設定

概要

Unbound には cache-max-ttl という設定があります。
unbound.conf(5)

       cache-max-ttl: <seconds>
              Time  to  live maximum for RRsets and messages in the cache. De-
              fault is 86400 seconds (1 day).  When the TTL expires, the cache
              item  has  expired.   Can  be set lower to force the resolver to
              query for data often, and not trust  (very  large)  TTL  values.
              Downstream clients also see the lower TTL.

少し古いバージョン(今回の例だと Ubuntu 18.04 に apt で降ってくる 1.6.7)だと、特定の構成では巧く働いてくれない...という話です。
解決策は Ubuntu を 20.04 にあげて Unbound も 1.9.4 にあげることです。

なお、本問題は cache-max-ttl というメールスレッド(パッチ付)を見ると簡潔に纏まっています。

発生した問題

構成は以下

  • クライアントは Ubuntu 18.04 で systemd-resolved が cache 有効で動いている
    • systemd-resolved で以下のDNSキャッシュサーバ(Unbound)を指定している (設定は netplan でやっている)
  • DNSキャッシュサーバは Ubuntu 18.04 + Unbound 1.6.7 で cache-max-ttl 設定は 1800s

クライアントから original ttl が 1800 以上のレコードを引いて ttl の様子を見てみると、最初は original ttl の 10800 だったのが cache-max-ttl 設定の 1800s 後に 9000 から 10800 に戻っています。10800 から始まるから分かりにくいものの 1800s で cache が切れてくれてはいます。

$ dig www5e.biglobe.ne.jp @<Unbound ip address>

; <<>> DiG 9.11.3-1ubuntu1.15-Ubuntu <<>> www5e.biglobe.ne.jp @<Unbound ip address>
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2113
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www5e.biglobe.ne.jp.           IN      A

;; ANSWER SECTION:
www5e.biglobe.ne.jp.    10800    IN      A       133.208.182.75

;; Query time: 0 msec
;; SERVER: <Unbound ip address>#53(<Unbound ip address>)
;; WHEN: Fri Oct 01 12:34:16 JST 2021
;; MSG SIZE  rcvd: 64


$ dig www5e.biglobe.ne.jp @<Unbound ip address>

; <<>> DiG 9.11.3-1ubuntu1.15-Ubuntu <<>> www5e.biglobe.ne.jp @<Unbound ip address>
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2113
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www5e.biglobe.ne.jp.           IN      A

;; ANSWER SECTION:
www5e.biglobe.ne.jp.    9000    IN      A       133.208.182.75

;; Query time: 0 msec
;; SERVER: <Unbound ip address>#53(<Unbound ip address>)
;; WHEN: Fri Oct 01 13:04:17 JST 2021
;; MSG SIZE  rcvd: 64



$ dig www5e.biglobe.ne.jp @<Unbound ip address>

; <<>> DiG 9.11.3-1ubuntu1.15-Ubuntu <<>> www5e.biglobe.ne.jp @<Unbound ip address>
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2113
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www5e.biglobe.ne.jp.           IN      A

;; ANSWER SECTION:
www5e.biglobe.ne.jp.    10800    IN      A       133.208.182.75

;; Query time: 0 msec
;; SERVER: <Unbound ip address>#53(<Unbound ip address>)
;; WHEN: Fri Oct 01 13:04:19 JST 2021
;; MSG SIZE  rcvd: 64

ここで cache 有効な systemd-resolved が噛む形にすると original ttl の値が使われてしまい、Unbound で設定している cache-max-ttl 設定が想定通りに働かなくなってしまいます。1800sを超えても cache が残り続けます...。

$ dig www5e.biglobe.ne.jp

; <<>> DiG 9.11.3-1ubuntu1.15-Ubuntu <<>> www5e.biglobe.ne.jp
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64774
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;www5e.biglobe.ne.jp.           IN      A

;; ANSWER SECTION:
www5e.biglobe.ne.jp.    10800   IN      A       133.208.182.75

;; Query time: 179 msec
;; SERVER: 127.0.0.53#53(127.0.0.53)
;; WHEN: Fri Oct 01 13:24:34 JST 2021
;; MSG SIZE  rcvd: 64



$ dig www5e.biglobe.ne.jp

; <<>> DiG 9.11.3-1ubuntu1.15-Ubuntu <<>> www5e.biglobe.ne.jp
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64774
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;www5e.biglobe.ne.jp.           IN      A

;; ANSWER SECTION:
www5e.biglobe.ne.jp.    8400   IN      A       133.208.182.75

;; Query time: 179 msec
;; SERVER: 127.0.0.53#53(127.0.0.53)
;; WHEN: Fri Oct 01 14:04:35 JST 2021
;; MSG SIZE  rcvd: 64

対処

というわけで調査したところ、まんま本問題を示している前述の cache-max-ttl というメールスレッドを見つけました。
この改修パッチは unbound/doc/Changelog の通り 2018/12 には取り込まれているようです。

Ubuntu 18.04 に apt で入れた Unbound 1.6.7 (2017/10 release) では踏むけれど、Ubuntu 20.04 なら Unbound 1.9.4 (2019/10 release)で踏まない筈... ということで Unbound を動かしている Ubuntu を 18.04 から 20.04 に upgarade して Unbound も 1.9.4 にあげたところ、問題は解決しました。

Unbound からは cache-max-ttl より大きな original ttl ではなく cache-max-ttl 設定値が返ってくるようになり、

$ dig www5e.biglobe.ne.jp @<Unbound ip address>

; <<>> DiG 9.11.3-1ubuntu1.15-Ubuntu <<>> www5e.biglobe.ne.jp @<Unbound ip address>
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 3042
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www5e.biglobe.ne.jp.           IN      A

;; ANSWER SECTION:
www5e.biglobe.ne.jp.    1800    IN      A       133.208.182.75

;; Query time: 20 msec
;; SERVER: <Unbound ip address>#53(<Unbound ip address>)
;; WHEN: Fri Oct 01 18:48:24 JST 2021
;; MSG SIZE  rcvd: 64

cache 有効な systemd-resolved が噛む形にしても Unbound で設定している cache-max-ttl 設定が効いてくれるようになりました。

$ dig www5e.biglobe.ne.jp

; <<>> DiG 9.11.3-1ubuntu1.15-Ubuntu <<>> www5e.biglobe.ne.jp
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 63263
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;www5e.biglobe.ne.jp.           IN      A

;; ANSWER SECTION:
www5e.biglobe.ne.jp.    1756    IN      A       133.208.182.75

;; Query time: 1 msec
;; SERVER: 127.0.0.53#53(127.0.0.53)
;; WHEN: Fri Oct 01 18:49:31 JST 2021
;; MSG SIZE  rcvd: 64

余談

前述のメールスレッドを追うと「必ずしもクライアントからの問い合わせに上流の resolver が override した ttl 値を返すのが良い挙動ではない (元の挙動が望ましいこともある)」という意見が出ています。
現状の実装を見ると serve-original-ttl という設定で挙動を切り替えられるようにしているようです。デフォルトは no なので override する挙動です。

       serve-original-ttl: <yes or no>
              If  enabled,  unbound will always return the original TTL as re-
              ceived from the upstream name server rather than the  decrement-
              ing  TTL  as stored in the cache.  This feature may be useful if
              unbound serves as a front-end to  a  hidden  authoritative  name
              server.  Enabling  this feature does not impact cache expiry, it
              only changes the TTL unbound embeds  in  responses  to  queries.
              Note  that enabling this feature implicitly disables enforcement
              of the configured minimum and maximum  TTL,  as  it  is  assumed
              users  who enable this feature do not want unbound to change the
              TTL obtained from an upstream server.  Thus, the values set  us-
              ing  cache-min-ttl  and  cache-max-ttl  are ignored.  Default is
              "no".
 if(!SERVE_ORIGINAL_TTL && (*rr_ttl > MAX_TTL))
        *rr_ttl = MAX_TTL;