こんにちは、技術開発室の滝澤です。
TLS証明書チェッカーcheck-tls-certを開発して公開したので紹介します。
このcheck-tls-certについて簡単に説明すると次の通りです。
- check-tls-certは、TLS証明書の有効性と証明書チェインの検証するツール
- 主な用途は、TLS証明書の設置・更新作業の際の各種確認およびTLS証明書の(有効期限を含む)有効性の監視
- 様々な検査を実施し、各検査結果を出力することで問題箇所を把握しやすい
check-tls-certの概要
TLS証明書チェッカーcheck-tls-certはTLS証明書の有効性と証明書チェインを検証します。 主にTLS証明書の設置・更新作業の際の各種確認およびTLS証明書の(有効期限を含む)有効性の監視のために利用できます。
次のサイトで公開しており、ReleaseページからLinux向けとmacOS向けのバイナリをダウンロードできます。
https://github.com/heartbeatsjp/check-tls-cert
なお、開発言語はGo言語で、動作環境はUNIX系OSのみです。
背景
TLS証明書チェッカーcheck-tls-certを開発した背景を簡単に説明します。
弊社ハートビーツのマネージドサービスにおいて、運用代行としてお客様のシステムのTLS証明書の更新作業を行うことがあります。 その際に、プライベート鍵とサーバー証明書と中間証明書の整合性確認を行いますが、様々な確認を行うため、作業が煩雑でした。 社内のヒアリングでは整合性確認手順の作業だけで10分くらいかかっていたということです。
社内でこの整合性確認作業を支援するためのツールが欲しいという話があり、今回の開発に至りました。 開発した結果として、新たにcheck-tls-cert自体の設置作業が追加されますが、check-tls-certのコマンドを2回実行するだけで整合性確認を行えるようになりました。
開発言語としてはGo言語を利用しました。これは、お客様のサーバー内にツールを設置する際に、バイナリファイルをダウンロードして置くだけですむためです。
check-tls-certの紹介
利用用途
次のような用途に利用できます。
- TLS証明書の設置・更新作業の際の各種確認
- 【ローカル/リモート】サーバー証明書の情報の表示
- 【ローカル】証明書ファイル内の証明書の有効性の検査(ファイル内の複数の証明書に対応)
- 【リモート】サーバーから受け取った証明書一覧の表示と有効性の検査
- 【ローカル】プライベート鍵とサーバー証明書の鍵ペアの検査
- 【ローカル/リモート】ホスト名の検査
- 【ローカル/リモート】サーバー証明書の有効期間の検査
- 【ローカル/リモート】証明書チェインの検査
- 【リモート】OCSP Staplingによる証明書が失効されていないことの検査
- TLS証明書の(有効期限を含む)有効性の監視
ここで、【ローカル】は証明書ファイルやプライベート鍵ファイルに対する検査です。後述するfileコマンドにより検査を行えます。
【リモート】はネットワーク越しにサーバーにTLS接続する検査になります。SMTP, POP3, IMAPのSTARTTLS接続にも対応しています。後述するnetコマンドにより検査を行えます。
TLS証明書の設置作業の更新前にfileコマンドで設置したファイルの検査を実施し、更新直後にnetコマンドでリモートからのTLS接続の検査を実施することにより、手軽に確認できます。
また、Nagios/Sensuプラグインとしても動作します。証明書の有効期限の監視にも利用できます。
制約事項
制約事項は以下の通りです。
- プライベート鍵と証明書の形式はPEM形式をサポート
- デジタル署名アルゴリズムはRSA、ECDSA、Ed25519をサポート。さらにECDSAはuncompressed formのみをサポート。
OCSPレスポンダーの検査は不完全。一部のOCSPレスポンダーからのレスポンスの処理に失敗する。注記:2021-07-24 修正しました
コマンド
2つのコマンドfileとnetがあります。
fileコマンド
fileコマンドは、TLS証明書ファイルとプライベート鍵ファイルを検査します。
実行方法は次のとおりです。
check-tls-cert file -H ホスト名 -k プライベート鍵ファイル -f 証明書ファイル -v
証明書ファイルはサーバー証明書と中間証明書を1つのファイルにまとめたものです。中間証明書を別ファイルにするときには中間証明書ファイルを-C
オプションで指定します。
さらに、OCSP Stapling用のCA証明書ファイルがあるときには--ca-file
オプションで指定します。
なお、プライベート鍵ファイルの暗号化にも対応しています。プライベート鍵ファイルが暗号化されているときには、-P
オプションでパスワードが記述されたファイルを指定できますし、指定しないときにはパスワードの入力プロンプトが出力されるのでそこでパスワードを入力できます。
実際に次のように実行してみます。
check-tls-cert file -H heartbeats.jp -k private.pem -f certificates.pem -v
実行結果は次のようになります。SummaryセクションでOKが出力されれば問題ないということになります。
この例のように-v
オプションを付けることで検査結果を詳細に出力するため、問題がある場合にはどこに問題があるかがわかりやすくなっています。
netコマンド
netコマンドは、ネットワーク越しにサーバーにTLS接続して検査します。SMTP, POP3, IMAPのSTARTTLS接続にも対応しています。
実行方法は次の通りです。
check-tls-cert net -H ホスト名 -p ポート番号 -v
ポート番号のデフォルトは443であるため、ウェブサイトを検査するときには省略できます。
サーバーが複数台あるようなときには、-I
オプションでサーバー個別のIPアドレスを指定できます。
SMTP, POP3, IMAPのSTARTTLS接続するときには--starttls
オプションにsmtp, pop3, imapを指定します。
次のように実行してみます。
check-tls-cert net -H heartbeats.jp -v
実行結果は次のようになります。SummaryセクションでOKが出力されれば問題ないということになります。
この例のように-v
オプションを付けることで検査結果を詳細に出力するため、問題がある場合にはどこに問題があるかがわかりやすくなっています。
Nagios/Sensu監視プラグイン
外形監視として有効期限を含む有効性を監視したいときには、Nagios/Sensu監視プラグインとして実行できます。
この場合は単に-v
オプションを付けずに実行するだけです。
-w
, -c
オプションにWARNING, CRITICALとなる有効期限切れまでの日数を指定できます。デフォルトではそれぞれ14日と28日になっています。
実行例は次のとおりです。
$ check-tls-cert net -H heartbeats.jp -w 14 -c 28 OK: all checks have been passed $ echo $? 0
有効期限が近くなると次のようにCRITICALになります。
$ check-tls-cert net -H heartbeats.jp -w 14 -c 28 CRITICAL: the certificate will expire in 7 days on 2021-07-18 08:59:59 +0900 $ echo $? 2
以上で概要の説明は終わりです。
後半は検査項目について紹介します。どのような検査を行っているかご興味のある方はお読みください。
検査項目
Certificate (証明書)
サーバー証明書の情報を出力します。
出力例は次の通りです。
Certificate Files (証明書ファイル)
証明書ファイルに含まれる証明書の順番および証明書の有効性を検査します。
証明書ファイルに記載された順番で署名を検証します。次の順番の証明書が親の証明書であると仮定して検証するため、順番が間違っていたり、異なる中間証明書が入っていたりすると、エラーが発生します。
また、各証明書の有効期限を確認し、有効期限切れであればエラーが発生します。
注記:ルート証明書からの証明書チェインは検査しません。そのため、ルート証明書がシステムにインストールされていなくても、エラーは発生しません。
出力例は次の通りです。
次の出力例は順番が間違っている例です。
Peer Certificate List (サーバーから受け取った証明書一覧)
サーバーから受け取った証明書の順番と証明書の有効性を検査します。
受け取った証明書の順番で署名を検証します。次の順番の証明書が親の証明書であると仮定して検証するため、順番が間違っていたり、異なる中間証明書が入っていたりすると、エラーが発生します。
また、各証明書の有効期限を確認し、有効期限切れであればエラーが発生します。
注記:ルート証明書からの証明書チェインは検査しません。そのため、ルート証明書がシステムにインストールされていなくても、エラーは発生しません。
出力例は次のとおりです。
Private Key/Certificate Pair (プライベート鍵とサーバ証明書の組み合わせ)
プライベート鍵とサーバー証明書がペアであることを検査します。
具体的には、プライベート鍵に含まれている公開鍵とサーバー証明書に含まれている公開鍵を検査しています。
公開鍵の出力はopensslコマンドのpkeyサブコマンドの出力形式に合わせています。
出力例は次のとおりです。Modulusの値が一致していることがわかります。
次の出力例はペアでない場合の例です。Modulusの値が異なっていることがわかります。
Hostname (ホスト名)
指定したホスト名がサーバー証明書の有効なホスト名であるか検査します。
証明書に記載されているSANs (Subject Alternative Names)のDNSフィールドを検証します。なお、SubjectのCN (Common Name)での検証は非推奨になっているため行いません。
出力例は次のとおりです。
次の出力例は指定したホスト名がサーバー証明書のホスト名として有効でない場合の例です。
Validity (有効性/有効期限)
証明書の有効期限を検査します。
オプション-w/--warning
、-c/--critical
を指定することでWARNING, CRITICALとなる有効期限までの日数を指定できます。デフォルトではそれぞれ14日と28日です。
出力例は次のとおりです。
次の出力例は有効期限に近づいてWARNINGが出力される例です。
Certificate Chains (証明書チェイン)
証明書チェインの有効性を検査します。
ルート証明書からサーバー証明書までの証明書チェインを検査します。そのため、ルート証明書がシステムにインストールされていなければ、エラーが発生します。
出力例は次のとおりです。
また、クロスルート証明書にも対応しており、次のように出力されます。 これは2021年7月時点でのLet's Encryptにより発行されたRSAの証明書の例です。 DST Root CA X3によりクロス署名されたISRG Root X1が中間証明書として利用されているため、このようになります。
OCSP Stapling
OCSP Staplingによるサーバ証明書の有効性を確認します。
オプション--ocsp as-is
, --ocsp stapling
, --ocsp fallback
を指定することにより、このチェックは実行されます。--ocsp as-is
がデフォルトです。
オプション--ocsp as-is
を指定すると、OCSPレスポンスが無くてもエラーになりません。
オプション--ocsp stapling
を指定すると、OCSPレスポンスが無ければ、2回まで再試行できます。それでもOCSPレスポンスを受け取れなかったらWARNINGステータスとなります。これは、ウェブサーバ起動直後にアクセスするとOCSPレスポンスを受け取れないことがあるためです。OCSP Staplingの設定をサーバに行っているときに利用するとよいでしょう。
オプション--ocsp fallback
を指定すると、OCSPレスポンスが無ければ、OCSP Responderのチェックを実行します。
出力例は次のとおりです。
なお、OCSPレスポンスがなければ次のように出力されます。
OCSP Responder (OCSPレスポンダー)
OCSPレスポンダーへ直接リクエストを送り、受け取ったレスポンスによりサーバー証明書の有効性を確認します。
オプション--ocsp responder
や--ocsp fallback
を指定することにより、このチェックは実行されます。
ただし、このチェッカーは実験的ステータスです。であり、一部のOCSPレスポンダーへのリクエストや一部のOCSPレスポンダーからのOCSPレスポンスの解析に失敗することがわかっています。 注記:2021-07-24 修正しました
出力例は次のとおりです。
以上で検査項目の紹介は終わりです。
まとめ
TLS証明書チェッカーcheck-tls-certについて次のことを紹介しました。
- check-tls-certは、TLS証明書の有効性と証明書チェインを検証するツール
- 主な用途は、TLS証明書の設置・更新作業の際の各種確認およびTLS証明書の(有効期限を含む)有効性の監視
- 様々な検査を実施し、各検査結果を出力することで問題箇所を把握しやすい
Let's EncryptやクラウドサービスなどではTLS証明書を自動更新できる状況ではありますが、手動での更新が必要な際にお役に立てていただければ幸いです。