zkat’s diary

技術ブログ

TLSAレコードでTrust Anchor Assertionを設定する

概要

  • 私の管理するドメイン名、mtcq.jpにTLSAレコードを設定してみました。
  • その時に調べたことなどをメモしておきます。

TLSAレコードでできること

TLSAレコードを設定することで、ドメイン名とサーバー証明書(以下、エンドエンティティ証明書)に関する情報をDNSで紐づけすることができます。

TLSクライアントが対象ドメイン名に対してTLS通信を試行する際に、この紐づけ情報をチェックすることができるようになります。 *1

紐づける方法(以下、Certificate Usage)は、4つが存在します。

Certificate Usage ドメイン名に紐づけする情報
0 対象ドメイン名に対してエンドエンティティ証明書を発行した認証局の情報
1 対象ドメイン名に対して発行されたエンドエンティティ証明書の情報
2 対象ドメイン名に対して発行されたエンドエンティティ証明書のルート証明書の情報
3 対象ドメイン名に対して発行されたエンドエンティティ証明書の情報(上述の1と異なり、自己署名証明書でよい)

なぜTLSAレコードが作られたか

エンドエンティティ証明書を発行する認証局が過去に起こした事故が関係しています。
現在ウェブで用いられているエンドエンティティ証明書は、技術的にはどの認証局がどのドメイン名に対しても発行することができます。
例えば、example.comの管理者はいつも認証局Aから証明書を発行していたとします。悪意のある第三者が何らかの方法でexample.comの証明書を 認証局B(システムが脆弱でクラックされてしまったなど)から得たとします。この場合、認証局Bから得た証明書も問題なく使えてしまうという課題があります。*2 *3

具体的な事故事例としては、オランダの認証局DigiNotarが過去に起こした事故などがあります。

internet.watch.impress.co.jp

TLSAレコードが存在することにより、あるドメインで使用されるべき本物の証明書がどれであるのかを明確にすることができますので、このような問題の発生を低減することができます。

なお、TLSAレコードはその性質上DNSSECが有効化されていることが必須となります。*4

CAAレコードとの違い

ドメインの管理者はCAAレコードを設定することで、自身のドメインに証明書を発行してもよい認証局を指定することができます。認証局は、証明書を発行するタイミングでCAAレコードを引き、もし自身を指定する情報が記載されていなかった場合は証明書を発行しない挙動をとります。 *5

CAAレコードが証明書を発行するタイミングで働くの対し、TLSAレコードはTLSの証明書チェーン検証のタイミングで働く違いがあります。

設定した内容

Let's Encryptのエンドエンティティ証明書を設定している私のドメイン mtcq.jp について、以下のTLSAレコードを設定してみました。 Certificate Usageは2番で、ルート証明書に対するアサーションを入れるものとなります。

$ dig +short _443._tcp.mtcq.jp. -t TLSA
2 1 1 0B9FA5A59EED715C26C1020C711B4F6EC42D58B0015E14337A39DAD3 01C5AFC3

なお、Shumon Huque氏が作った以下のツールを用いることで、TLSAレコードの内容を簡単に作ることができます。

www.huque.com

ただ念のため、レコードの内容が正しいかどうかチェックしてみます。 今回私は以下の設定でレコードを作成しています。

Certificate Usage Selector Matching Type
2 1(証明書のSubjectPublicKeyInfo部分の情報を用いる) 1(sha-256ハッシュで表す)

Let's Encrtyptのルート証明書のPEMを取得し、SubjectPublicKeyInfoの情報を保存します。 (241バイトからSubjectPublicKeyInfoの情報が始まっています)
抜き出した情報のsha-256をとればよいです。

$ openssl asn1parse -strparse 241 -in ISRG-ROOT-X1 -noout -out spki.der
$ sha256sum spki1.der
0b9fa5a59eed715c26c1020c711b4f6ec42d58b0015e14337a39dad301c5afc3

レコードは正しく作れていそうです。

TLSAレコードの面白いところ

今回試せていませんが、Certificate Usageの3がとても面白いと思いました。
これを用いれば、TLSAレコードで自己署名証明書を提供することができます。TLSAレコードは、DNSSECで署名されることが期待されますので、認証局のような余分なTTPを必要とせずに信頼の連鎖を構築することができます。別の機会に設定してみて、対応しているクライアントを探すなどしてみたいと思います。

TLSAレコードの課題

個人的に感じる課題についてです。

  • TLSAレコードをチェックするTLSクライアントがほとんど存在しない?
  • DNSSECが普及していない

*1:実態として、現状TLSAレコードをチェックしているTLSクライアント(ブラウザ)は少ない、または存在しないと思われます。

*2:そういった悪意のある証明書の存在に気付く手段として、CTという仕組みがあります

*3:意図せず悪意のある証明書を発行してしまうことを防ぐためにCAAという仕組みがあります。

*4:TLSAレコード自体が詐称されていないことは、DNSSECで担保する

*5:2017年9月から