Knot Resolver の permissive mode (寛容モード) は非常に危険なので、もしこれを普段使いしている人がいれば、即刻利用をやめることをお勧めします。
permissive mode は委譲を追いかける際に NS の A レコードが additional に付加されていたら、それをすべてノーチェックで信用することにより、検索を速くしようという趣旨のもののようです。
ふと悪い予感がしてある実験をしてみたところ、このモードが恐ろしく危険であることがわかりました。
以下はその実験の説明です。brau.jp へ毒入れを試みます。(すべて私が登録しているドメイン名です)
~% dig @ns.internat.jp -t txt brau.internat.jp +norec ; <<>> DiG 9.9.5 <<>> @ns.internat.jp -t txt brau.internat.jp +norec ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 53242 ;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1 ;; QUESTION SECTION: ;brau.internat.jp. IN TXT ;; AUTHORITY SECTION: brau.internat.jp. 300 IN NS ns.brau.jp. ;; ADDITIONAL SECTION: ns.brau.jp. 300 IN A 150.42.6.9これは internat.jp から brau.internat.jp の委譲応答ですが、同居ゾーンを用いて Additional Section に ns.brau.jp の偽の A レコードを加えてあります。これは glue ではないので安全に考慮した実装であれば無視すべきものです。本物の ns.brau.jp は 150.42.6.4 です。
~% dig @127.0.0.3 -t txt brau.internat.jp ; <<>> DiG 9.9.5 <<>> @127.0.0.3 -t txt brau.internat.jp ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 8904 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;brau.internat.jp. IN TXT ;; ANSWER SECTION: brau.internat.jp. 60 IN TXT "brau.internat.jp"本物の ns.brau.jp = 150.42.6.4 に brau.internat.jp ゾーンはありません。この TXT は 偽 ns.brau.jp = 150.42.6.9 に用意した brau.internat.jp ゾーンが応答したものです。minimal response なので分かり辛いのですがこの時点で 偽 ns.brau.jp = 150.42.6.9 がキャッシュされ、それに誘導されたものと考えられます。
~% dig @127.0.0.3 -t soa brau.jp (snip) ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;brau.jp. IN SOA ;; ANSWER SECTION: brau.jp. 120 IN SOA ns.brau.jp. tss.e-ontap.com. ( 2020082501 ; serial 3600 ; refresh (1 hour) 600 ; retry (10 minutes) 86400 ; expire (1 day) 60 ; minimum (1 minute) )これは brau.jp の NS をキャッシュに入れるためです。NS を直接問い合わせてもよいです。Answer Section の SOA は本物の ns.brau.jp 由来のものです。Minimal response で分かり辛いですが、Authority Section から brau.jp IN NS ns.brau.jp. が、Additional Section から ns.brau.jp IN A 150.42.6.4 が返ってきているはずです。(パケットダンプで確認済)
~% dig @127.0.0.3 -t txt brau.jp (snip) ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;brau.jp. IN TXT ;; ANSWER SECTION: brau.jp. 60 IN TXT "NG"この Answer Section の TXT "NG" は偽 ns.brau.jp 由来のものです。ステップ 2 で注入された偽 A レコードで誘導された結果だと考えられます。
以上からわかることは permissive mode の Knot Resolver には任意のドメインのキャッシュポイズニングが可能だということです。
そこで、開発元の NIC.CZ に問い合わせたところ以下の返事がありました。
Documentation for version 5.1.1 (at https://knot-resolver.readthedocs.io/en/v5.1.1/config-dnssec.html#mode) describes that "permissive mode" accepts all glue records without checks. This is definition of cache-poisoning security hole, so we can conclude that the permissive mode works as intended - and that's why it is not enabled by default.
要約すると「permissive mode はすべてのグルーレコードをノーチェックで受け入れる。これはキャッシュポイズニング脆弱性を意味している。貴方の指摘はその仕様どおりだと言える。我々がこのモードをデフォルトにしていない理由でもある」という回答です。
私はそんなことは承知で質問したのです。設計の趣旨はあくまで委譲を追いかけるための情報として referral に付随する A レコード (これを彼らは glue と読んでいますがそれは定義の間違い) を効率よく利用するためであり、もしその A レコードが悪意あるものだった場合に被害を受けるのは問い合わせ対象のドメインに限定されているはずだと考えていました。
ところが私の実験では特定条件下に置かれたドメインだけでなく、任意のドメインにキャッシュポイズニングができてしまいました。これは彼らの意図 (intended) から外れているのではないでしょうか。
まあ本当のところを追求すのは面倒なのでやめておきますが、permissive mode が危険なことは彼らも認めているわけなので、実験目的以外に使用するのは止めましょう。改めて文書を見るとこう書いてあります。
Knot Resolver uses secure configuration by default, and this configuration should not be changed unless absolutely necessary
なお、nic.cz からのメールの最後にはこうありました。(1.1.1.1 は?)
On the other hand we have not seen anyone relying on permissive mode for along time, so we might just remove it in next releases.
p.s.
ところでこの件は DNS 温泉常連の大塚さんのこのツイートに端を発しています。
これは 1.1.1.1 で私の実験のステップ 2 と同じ現象が起きていることを意味しているものです。1.1.1.1 は Knot Resolver を使用していると言われているのですが、これだけ見ても危険ではないかと疑われます。(どういう攻撃が可能であるかは解説を控えておきます)
そして私のゼミの M2 の太田くんから permissive mode で大塚さんの事例が再現できたという報告を受けたのが今回の実験の発端でした。
私の実験通りのことが 1.1.1.1 でも起きるとすれば大変なことなのですが、今のところ再現はできていません。さすがに permissive mode をそのまま運用しているわけではないでしょうが一抹の不安が残るところです。
labs.nic.cz にブログの翻訳を送って意見を求めたところ以下の返信がありましたので転載しておきます。(転載は彼らも歓迎とのことです)
私の記事はあくまで permissive mode が危険なことを確認したまでであり、normal mode までが危険だという主張はしていないことをここに記しておきます。彼らの文書からはどれほど危険なのかが読み取れなかったので実験を行い、このモードに関する注意喚起の意味でブログを書いたまでです。
From: Petr Špaček <petr.spacek @ nic.cz> To: "T.Suzuki" <tss @ e-ontap.com> Cc: knot-resolver @ labs.nic.cz, Masato OTSUKA , Kenya Ohta Subject: Re: [knot-resolver@labs] a vulnerability of permissive mode Date: Fri, 28 Aug 2020 09:22:35 +0200 Organization: CZ.NIC Hello, and thank you for sharing link to translation! Unfortunatelly nobody in our team speaks Japanese so we are not able to write an explanatory article with reaction. For that reason I ask you to amend the article so it starts with information that _default is secure_ and that _only an explicit configuration can make it insecure_. Rationale for this request: Translation of the current version seems unnecessairly alarmist to me. From my perspective the current text says: - Step 1: Explicitly configure Knot Resolver into insecure mode (which is documented). - Step 2: Test that the explicit configuration is really insecure. What is the purpose? I'm really confused, and I believe some readers might be confused as well. The only explanation I could see is that documentation might be unclear in some aspect. If it is that case please be constructive and point out what exactly what is unclear/confusing so we can fix it. Articles with statements like "it's too much trouble to pursue the truths" do not help to improve software or documentation quality. In similar spirit there could be an article saying "we disabled DNSSEC validation, and then our tests shown that this is insecure configuration, so do not use this configuration". It is exactly the same logic as the article above. Also your article seems to imply that 1.1.1.1 should behave exactly the same as Knot Resolver, which is incorrect assumption. Cloudflare is heavily customising our code so they can provide features unique to 1.1.1.1. This naturally causes divergence in behavior. In other words 1.1.1.1 is not equal to latest publicly available release of Knot Resolver. I would appreciate if you article clarified that aspect as well. I ask you to amend the article as indicated above and thank you for your time. Petr Špaček @ CZ.NIC
Copyright by T.Suzuki