目次
背景
- 昔のHPのSSLのメモがあったので持ってきた
X.509のプロトコル
X.509のプロトコルとは
- X.509 は、公開鍵証明書(Public Key Certificate)の形式や認証局(CA: Certification Authority)の運用方法を定めた標準規格
- X.509は、PKIの標準規格で、デジタル証明書を使ってデバイスやサーバー、ユーザー間の通信を認証し、暗号化するために使用される
X.509の特徴
証明書の構造
- バージョン(Version)
- X.509証明書のバージョン情報。現在では主にバージョン3(v3)が使用されてる
- シリアル番号(Serial Number)
- 各証明書に一意に割り当てられる番号。CAによって発行された証明書を識別するために使用される
- 署名アルゴリズム(Signature Algorithm)
- 証明書の署名に使用されたアルゴリズム(例: SHA256 with RSA)
- 発行者(Issuer)
- 証明書を発行したCAの情報
- 有効期間(Validity)
- 証明書の有効開始日時(Not Before)と有効終了日時(Not After)
- 対象者(Subject)
- 証明書が証明するエンティティ(例: ドメイン名や個人)の情報
- 公開鍵情報(Subject Public Key Info)
- 対象者の公開鍵およびそのアルゴリズム
- 拡張情報(Extensions)
- 証明書の用途や制約を追加で記述するセクション
- 例として、キー使用目的(Key Usage)、拡張キー使用目的(Extended Key Usage)、サブジェクト代替名(Subject Alternative Name)などがある
- 証明書の署名(Signature)
- 発行者CAによる証明書全体の署名。証明書の改ざんを防止する
証明書の種類
- エンドエンティティ証明書(End-Entity Certificate)
- 最終的な利用者(サーバやクライアント)に発行される証明書
- 中間CA証明書(Intermediate CA Certificate)
- ルートCAとエンドエンティティ証明書の間に位置するCAに発行される証明書
- チェーン認証を構築する
- ルートCA証明書(Root CA Certificate)
- 信頼の基点となるCAの証明書
- 通常、オペレーティングシステムやブラウザにプリインストールされている
- 証明書チェーン(Certificate Chain)
- 複数の証明書が連なって信頼関係を構築する仕組み
- エンドエンティティ証明書が中間CA証明書によって、中間CA証明書がルートCA証明書によって信頼される
- これにより、信頼できるルートCAから発行された証明書のみが有効と認識される
PKIとは?
公開鍵基盤(PKI:Public-Key Infrastructure)
- PKI(Public-Key Infrastructure)は公開鍵暗号を利用した認証基盤
- PKIでは通信相手が本物であるかどうかの確認(認証)に公開鍵証明書(以下、証明書)を利用する
- PKIにおける証明書は、発行者の名前といった情報が記述されており、身分証明書の役割を果たす
- 身分証明書を、信頼できるTTP(Trusted Third Party)に発行してもらうことで、その身分証明書を信頼できるようにするのがPKIの特徴
認証局(CA:Certification Authority)
- PKIで用いられる証明書は、認証局(CA:Certification Authority)によって発行される
- PKIでは、このCAが「信頼できる第三者」にあたる
- CAは、いわば身分の証明を行っている機関なので、ユーザーに強く信頼されていなければならない
- ユーザーは、自分が信頼しているCAが発行した証明書であれば信じられるということになる
X.509証明書(Cert:Certificate)
- 証明書の中身は次。
オンライン証明書の失効状態の確認(OCSP)
- OCSP(Online Certificate Status Protocol)は、証明書の失効をリアルタイムで確認する仕組み
- 暗号化やデジタル署名に用いるX.509証明書の有効期限前に失効している証明書を、速やかに知ることができる
PKIのアナロジー
PKIはある意味運転免許とおなじような仕組み。
- 運転免許の発行の仕組み: PKI
- 運転免許証:X.509証明書(pemファイル形式)
- 公安委員会:CA
- 運転免許証の有効性の確認:OCSP
他には、印鑑証明書もおなじ仕組み。
X.509証明書の詳細
証明書の拡張子
概ね、X.509証明書は次の3つにおフォーマットがある。
拡張子/形式 | エンコード形式 | ファイル内容の形式 | 主な用途 |
---|---|---|---|
.pem | Base64 | テキスト形式 | Linux系、Apache、汎用的な用途 |
.crt | Base64 または DER | テキストまたはバイナリ形式 | Webサーバー、ブラウザ |
.cer | Base64 または DER | テキストまたはバイナリ形式 | Windows環境 |
pemファイル
pem証明書のフォーマット
pemファイルとはpemの書式はシンプルで、任意の証明書、鍵をbase64エンコードして以下のBEGIN/END行で挟んでつなげたテキストファイル。
pemの書式(鍵+証明書)
|
|
pemの例(証明書+鍵)
|
|
このままでは人の目では証明書・鍵の情報が見えないので、 それを見やすくするには openssl コマンドを使う。
pem証明書の中身の例
example.orgでlet’s encryptで発行した例。Issuerはlet’s encryptで、subjectはexample.org.になっている
|
|
pem証明書の中身の意味
|
|
ASN.1とは?
- ASN.1はAbstract Syntax Notation Oneの意味
- 下のような形式のドキュメント
- pemファイルはこの形式に従っている
|
|
ACME
ACMEとは?
- ACMEは、X.509証明書の自動ドメイン検証とインストールのための標準プロトコル
- ACMEはAutomated Certificate Management Environment(自動証明書管理環境)の意味
- つまり、Webサーバと認証局との間の相互作用を自動化するための通信プロトコル、いわゆるチャレンジ方式のこと
ACMEチャレンジとは?
- ACMEチャレンジは、ACMEプロトコルに基づいて実行される「ドメイン所有権を証明するための特定のタスクや手続き」のこと
- 証明書を発行する前に、認証局(CA)がドメインの所有者であることを確認するために実施する
ACMEチャレンジの種類
- DNS-01チャレンジ:
- ドメインのDNS設定に特定のTXTレコードを追加し、CAがDNSを確認
- HTTP-01チャレンジ:
- ウェブサーバーに特定のトークンを含むファイルを配置し、CAがそのファイルをHTTPで確認
- TLS-ALPN-01チャレンジ:
- サーバーが特定のTLSプロトコルを利用して応答し、CAがそれを検証
ACMEチャレンジのフロー
HTTP-01のACMEチャレンジのフロー
ACMEチャレンジの詳細
DNS-01 チャレンジ
- あるドメインのSSL証明書をリクエストしたユーザーが、そのドメインに対する権限を有しているかを、DNSサーバーを通じて確認・認証する方式
- DNS サーバー上に認証用のTXT レコードを生成し、Let’s Encrypt 側からその TXT レコードを読み取ることで認証を行う
- TXTレコードは手動で設定するか、自動化したスクリプトなどで設定する
- いわゆる、AWS Certificate Managerでやっていること
HTTP-01チャレンジ
- HTTP-01 チャレンジは、あるドメインのSSL証明書をリクエストしたユーザー(Web サーバー)がそのドメインに対する権限を有しているかを HTTP通信経由で確認・認証する方式
- Web サーバー上に認証用のファイルを生成し、Let’s Encrypt 側からそのファイルにHTTPアクセスすることで認証を行う
- いわゆるcertbotの
--webroot
を指定した時の処理
tls-sni-01チャレンジ とは
- HTTPS(443)をつかうデジタル署名の更新手法
オレオレ証明書
オレオレ証明書
- 正式な認証機関(CA)によって発行されていない、自己署名のSSL/TLS証明書のこと
- 通常のSSL証明書は、信頼されたCAによって署名され、第三者による認証が行われる
Lets’encrypt vs. オレオレ証明書
Let’s EncryptはISRGがRootで、ブラウザから信頼されている。
他方、自己証明書の場合は信頼されない。
- なお、CNはCommon Name(コモンネーム)の略称
- これは証明書の主体を一意に識別するためのフィールド
オレオレ証明書の作成
CA無し
|
|
引数
req
- 秘密鍵と証明書を一度に生成する
- 使いまわすわけではないので、証明書が出来てしまえばCSRは不要なので生成しない
-nodes
node
の複数形ではなく、no DES
= 秘密鍵を暗号化しないの意味
-newkey rsa:2048
RSA
で2048bit
の秘密鍵を生成を指定する
-keyout privkey.pem
- 生成した秘密鍵の保存先の指定する
-x509
- 証明書の生成を示す
req
コマンドはデフォルトだとCSR
生成
-sha256
SHA256
の証明書が生成される- デフォルトだと
SHA1
なので注意
-days 1
- で有効日数を指定する
- 0日や1日未満での指定はできないが
-days -1
とすれば遡った指定もできる(必要性はないだろうけど)
-out chain.pem
- 生成した証明書の保存先を指定
-subj "/C=.../ST=.../L=.../O=.../OU=.../CN=..."
- CSRを生成する場合に指定するのと同じで証明書の情報
CA有り
オレオレ中間CAの生成
|
|
自身のIPに対するCSRと秘密鍵の生成
|
|
オレオレ認証局による証明書の生成
|
|
独自のRootCAのインストール方法
前提として、Ubuntu Linuxを使っている。
CA更新コマンド
|
|
コマンドの意味
- フォルダの作成
/usr/share/ca-certificates/
の下に適当なディレクトリを作成する- ここでは、
mylocal
とする - 以下、
/usr/share/ca-certificates/mylocal/
とする - ディレクトリは管理組織単位などでまとめるためのもの
- (おそらく、
mozilla/
というディレクトリがあると思うが、これは触らない)
- (おそらく、
- ディレクトリは無くても構わないが、ローカルなものは、ディレクトリでまとめた方が、後々、管理しやすい
- 証明書の設置
- 作成したフォルダ
mylocal
の下に、証明書ファイルを置く - ここでは、
mylocal-root-cacert.crt
とする - つまり、
/usr/share/ca-certificates/mylocal/mylocal-root-cacert.crt
となる
- 作成したフォルダ
- 設定ファイルの編集
/etc/ca-certificates.conf
に、追加したファイルの/usr/share/ca-certificates/
以下の相対パスを追加する- つまり、
mylocal/mylocal-root-cacert.crt
を追加する
- CA-certの更新
update-ca-certificates
(/usr/sbin/update-ca-certificates
)を実行する
- シンボリックリンクの確認
/etc/ssl/certs/
下に/usr/share/ca-certificates/mylocal/mylocal-root-cacert.crt
へのシンボリックリンクができていることを確認
NOTE:
- 余談だが、これが正しく行われると、CA bundleとしてすべてのCA証明書が含まれる
/etc/ssl/certs/ca-certificates.crt
が作成される - なので、必要に応じて、これを参照すると良い
- 例
- python の
requests()
の引数に CA Bundleのパスを指定するような場合、 update-ca-certificates
が自動的に/etc/ssl/certs/ca-certificates.crt
をアップデートする- なのので、独自に追加するのは、厳禁
- python の
Let’s Encryptの基本
Let’s Encryptとは?
- Let’s Encrypt は、無料で自動化された証明書発行サービスを提供する認証局(CA)
- Webサイトが HTTPS(TLS/SSL)通信を導入するために必要な X.509 証明書を簡単に取得・更新できる仕組みを提供する
Certbotとは?
- Certbotとは Certbotは無料かつ自動でSSL証明書を発行できるツール
- CSRとKEYファイルの作成からWebサーバーの設定まで自動で行ってくれる
- さらにCronと組み合わせることで、証明書の更新作業までも完全に自動化することが可能
ISRGとEFF
- ISRG(Internet Security Research Group)
- HTTPSの普及を通じて、インターネット全体のセキュリティを向上させることを主な目的とする非営利団体
- EFF(Electronic Frontier Foundation)
- プライバシー、表現の自由、オープンインターネットの推進を目指す非営利団体
Certbot
HTTPSまでの流れ
- 有効なドメイン名を取得
- ドメインのDNS設定で、サーバーのIPアドレスに向ける
- NGINXのインストールと基本設定を行う
- NGINXをインストール
- ドメイン名に対応するサーバーブロック(仮想ホスト)を設定
- ポート80でHTTPリクエストを受け付けるように設定
- Certbotのインストール
- CertbotはLet’s Encryptの公式クライアントで、SSL証明書の取得と更新を自動化
- サーバーにCertbotをインストール
- SSL証明書の取得
- Certbotを使用して、Let’s Encryptから無料のSSL証明書を取得
- ウェブサーバーの設定に応じて、
webroot
やstandalone
モードを選択
- NGINXのSSL設定
- 取得した証明書を使用して、NGINXでSSLを有効化
- ポート443でHTTPSリクエストを受け付けるように設定
- HTTPからHTTPSへのリダイレクトを設定
- SSL証明書の自動更新設定
- Let’s Encryptの証明書は有効期限が90日間
- Certbotをcronやsystemdタイマーで定期的に実行し、証明書を自動更新
Certbotのプラグインとオプションの違い
--dns-<provider>
オプション- チャレンジタイプ: DNS-01チャレンジ
- 使用条件: DNSプロバイダのAPI経由でTXTレコードを変更できる場合
- 特徴:
- ポート80や443を開放する必要がなく、内部ネットワークやファイアウォールの背後でも使用可能
- 自動化が可能で、サーバーの公開ポートに依存しません
--webroot
オプション- チャレンジタイプ: HTTP-01チャレンジ
- 使用条件: ポート80がアクセス可能で、既存のウェブサーバーが稼働している場合
- 特徴:
- ウェブサーバーを停止する必要がなく、既存のウェブサーバーのドキュメントルートを利用
- 自動化が容易で、ウェブサーバーの設定変更が最小限で済む
--standalone
オプション- チャレンジタイプ: HTTP-01チャレンジ
- 使用条件: ウェブサーバーがない、または一時的に停止できる場合
- 特徴:
- Certbotが一時的なウェブサーバーを起動し、ポート80または443を使用
- 既存のウェブサーバーが稼働している場合は停止が必要
--nginx
オプション- チャレンジタイプ: HTTP-01チャレンジ
- 使用条件: NGINXプラグインであり、NGINXが稼働している場合に利用
- 特徴:
- CertbotがNGINXの設定を自動的に編集し、SSLを有効化
- ウェブサーバーの停止が不要で、設定のバックアップや復元も自動化
- HTTPからHTTPSへのリダイレクト設定も自動的に行われる
他には、--apache
プラグイン(オプション)もある。
AuthenticatorとInstallerの違い
CertbotはAuthenticatorとInstallerを柔軟に組み合わせることで、様々な環境でSSLの取得と設定を自動化する。
- Authenticator(認証器)
- 役割: ドメインの所有権を証明するために、Let’s Encryptのサーバーと通信して認証を行うプラグイン
- 機能: ドメインの認証プロセス(チャレンジ)を処理する
- Installer(インストーラー)
- 役割: 取得したSSL証明書をウェブサーバーや他のサービスにインストールし、必要な設定変更を自動的に行うプラグイン
- 機能: サーバーの設定ファイルを編集し、SSL/TLSの設定を有効化
Certbotの使用するファイル
フォルダの意味
/etc/letsencrypt/live/
- 最新の証明書と鍵へのシンボリックリンクを保持
/etc/letsencrypt/archive/
- 過去の証明書と鍵の履歴を保持
/etc/letsencrypt/renewal/
- 証明書の更新に必要なパラメータ持つファイル(
xxx.conf
)を保持 - 自動更新プロセスでそのパラメーターを使用
- 証明書の更新に必要なパラメータ持つファイル(
ファイルの意味
cert.pem
: サーバー証明書privkey.pem
: 秘密鍵chain.pem
: 中間証明書fullchain.pem
: サーバー証明書と中間証明書を結合したもの
webroot
の設定ファイルの例
|
|
--staging
と--dry-run
オプションの違い
両方ともLet’s Encrypt のレートリミットを回避できるが次の違いがある。
--staging
- テスト用の証明書を実際に取得し、ディスクに保存する
- 証明書の取得や設定のテストに使用される
- テスト後は証明書が残るため、設定ファイルやディレクトリ構造を確認できる
--dry-run
- 証明書の取得プロセスをシミュレートするが、証明書は保存されない
- 自動更新のテストやエラーの検証に使用される
- ディスクに変更を加えないため、安全にテストできる
オプションの違い
--nginx
- SSL/TLS サーバ証明書を取得と、Nginxへの証明書のインストール(Nginx設定ファイルの書き換え)を自動的に行う
- Certbot 0.9.0以降に、Nginxプラグインのアルファ版が同梱されている
設定ファイル
authenticator
とinstaller
はnginxになっているwebroot
と違い、.well-known/acme-challenge
フォルダをnginxで設定することは不要
|
|
--webroot
- 動作の流れは以下のようになる
- 事前準備
- DNSの設定
- NGINXの設定
- アクター
- Certbot
- Let’s encrypt server
- Nginx server
- 動作
- CertbotはLet’s Encrypt Serverに証明書発行依頼をし、トークンを発行してもらう
- CertbotはACMEプロトコルに定義されている
.well-known/acme-challenge
にそのトークンを設置する - Let’s Encrypt の認証サーバがHTTPリクエストで
.well-known/acme-challenge
にグローバルからアクセスし、そのトークンのチェックを行う - トークンが正しければLet’s Encryptの証明書を発行しCertbotに返す
- Certbotは証明書を
/etc/letsencrypt
以下に設置する
準備として、ACMEプロトコル用のフォルダを作る。
|
|
また、NGINXの設定は次のような感じになる。
|
|
下のように指定した場合は、指定した全てのドメイン名に使用できる1枚のSSL/TLSサーバ証明書が発行される。
|
|
- renewalの設定ファイルは次のようになっている
authenticator
がwebroot
になっている
|
|
--standalone
- Webrootの自動版、チャレンジタイプはhttp-01となる
- ドメイン使用権者の認証の際には、Certbotクライアントに内蔵されている簡易的なウェブサーバが機能が一時的に使われる
- このプラグインは80や443のPortをListenしている動作中のウェブサーバを一時的に終了させる必要がある
参考文献
- インターネット10分講座 - JPNIC
- https://www.ipa.go.jp/security/pki/043.html
- X509
- 図解 X.509 証明書 #x.509 - Qiita
- (4) OAuth & OIDC 勉強会 クライアント認証編 by #authlete - 4. X.509 証明書 (1) - YouTube
- Certbotを使ってSSL証明書を発行し、HTTP通信を暗号化しよう - Avinton Japan
- マカオの図書館が世界文化遺産登録 | カレントアウェアネス・ポータル
- どのACMEチャレンジタイプを使用する必要がありますか? HTTP-01またはDNS-01? –SSL.com
- https://ww7.try-and-test.net/letsencrypt.html?usid=22&utid=3135555998
- ユーザーガイド - Let’s Encrypt 総合ポータル
- 認証局とは|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典
- Let’s Encrypt で SSL/TLS 証明書をインストールして自己証明書から脱却 #Let’sEncrypt - Qiita
- 自己署名証明書の生成方法 #OpenSSL - Qiita
- 独自(root)CA のインストール方法 #Python - Qiita