Windows Server に Let’s Encrypt を導入する

クラウド

Windows Server 上の Web サーバに SSL を導入したい場合、Apache だと非常に簡単に Let’s Encrypt を導入できます。
ここでは mod_md モジュールを利用して Apache に Let’s Encrypt を導入する手順を説明いたします。
なお、mod_md モジュールは、Apache 2.4.30 以降より利用可能です。

参考: Windows Server + Apache + PHP + MariaDB のサーバ構築


httpd.conf の設定
Apache の設定ファイルであるhttpd.confを編集します。
httpd.confは、Apache のインストール先をc:\Apache24とすると、その配下のc:\Apache24\confフォルダにあります。

説明の便宜上、設定値の横にコメントを入れている箇所がありますが、Apache が正しく起動しない場合があるので、コメント行と設定行は分けてください。

●Listen ディレクティブ(Apache MPM
httpdがリクエストを受信するポート番号を設定します。
通常 HTTPS であれば 443 がデフォルトで使用されるポート番号です。

#Listen 12.34.56.78:80
Listen 443

●LoadModule ディレクティブ(Apache モジュール mod_so
必要となるモジュールのコメントを外します。

LoadModule md_module	modules/mod_md.so # mod_mdモジュール本体
LoadModule socache_shmcb_module	modules/mod_socache_shmcb.so # セションキャッシュ
LoadModule ssl_module	modules/mod_ssl.so # SSL
LoadModule watchdog_module	modules/mod_watchdog.so # mod_mdが利用するフック機構

●ServerAdmin ディレクティブ(Apache Core
エラーメッセージ中に記述するお問合せ先(メールアドレス)を設定します。
デフォルトのままだと証明書発行の認証に失敗します。

#ServerAdmin admin@example.com
ServerAdmin webmaster@mydomain.com

●SSL の設定
SSL の設定を記述します。
専用のファイル( c:\Apache24\conf\extra\httpd-ssl.conf)も用意されていますが、デフォルトで記述されている行がほとんど使えないので、httpd.confに追記した方が早いです。

# Let's Encrypt
MDBaseServer            on
MDCAChallenges          tls-alpn-01
MDCertificateAuthority  https://acme-staging-v02.api.letsencrypt.org/directory
MDCertificateAgreement  https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf
MDomain mydomain.com

SSLSessionCache  "shmcb:${SRVROOT}/logs/ssl_scache(512000)"
SSLSessionCacheTimeout  300

<VirtualHost *:443>
	SSLEngine on
	ServerName mydomain.com
	DocumentRoot "${SRVROOT}/htdocs"
	Protocols http/1.1 acme-tls/1
</VirtualHost>

以下、<VirtualHost> 外にあるディレクティブの説明です。
※これらのディレクティブは <VirtualHost> ディレクティブの中に含めることができません。

・MDBaseServer ディレクティブ(Apache モジュール mod_md
ONにすることで、mod_md が利用できるようになります。

・MDCAChallenges ディレクティブ(Apache モジュール mod_md
証明書発行手続きの認証方式を指定します。
HTTP 認証(http-01)、DNS 認証(dns-01)、TLS 認証(tls-alpn-01)の3種類がありますが、今回は TLS 認証を採用します。

・MDCertificateAuthority ディレクティブ(Apache モジュール mod_md
認証局の証明書発行手続き用の URL を指定します。
証明書発行のリクエストには上限があり、発行手続きに何度も失敗してしまうとしばらくの間リクエストが通らなくなってしまうため、まずは安全のためにテスト用の URL を指定します。
テストの結果が良好であればこの行をコメントアウトして実際の発行手続きを行います

・MDCertificateAgreement ディレクティブ(Apache モジュール mod_md
Let’s Encrypt の利用規約へのリンクです。

・MDomain ディレクティブ(Apache モジュール mod_md
HTTPS でアクセスさせるドメイン名を指定します。

・SSLSessionCache ディレクティブ(Apache モジュール mod_ssl
mod_socache_smhcb 用の設定です。
利用する SSL セッションキャッシュのストレージタイプを指定します。

・SSLSessionCacheTimeout ディレクティブ(Apache モジュール mod_ssl
mod_socache_smhcb 用の設定です。
セションタイムアウト値の設定で、デフォルトは5分(300)です。


●<VirtualHost> ディレクティブ(Apache Core
<VirtualHost> に含めることのできるディレクティブは以下の通りです。

・SSLEngine ディレクティブ(Apache モジュール mod_ssl
ONにすることで、mod_ssl が利用できるようになります。

・ServerName ディレクティブ(Apache Core
アクセスされるドメイン名を設定します。

・DocumentRoot ディレクティブ(Apache Core
公開ディレクトリを設定します。

・Protocols ディレクティブ(Apache Core
使用するプロトコルのリストを指定します。
証明書発行手続きの認証方式である TLS 認証では、acm-tls/1 を使用します。


ポートの開放
「スタートメニュー」→「Windows 管理ツール」→「セキュリティが強化された Windows Defender ファイアウォール」をクリックします。

セキュリティが強化された Windows Defender ファイアウォール

受信規則から新しい規則を作成します。

新しい受信規則

ウィザードにしたがってそれぞれ入力していきます。

規則の種類:ポート
プロトコルおよびポート:TCP、特定のローカルポート 443
操作:接続を許可する
プロファイル:ドメイン、プライベート、パブリック
名前:HTTPS

HTTPSの受信規則

受信規則が作成されました。

サーバ事業者側のサービスが独自のセキュリティ設定を持っている場合、そのセキュリティ設定を変更するまではポートが開放されません。
例えば AWS【Amazon Web Services】では、コンソールからセキュリティグループのインバウンドルールを追加する必要があります。

AWS の例:
上部メニューの「サービス」から「EC2」を選択し、インスタンス一覧画面を表示します。
該当のインスタンスを選択し「セキュリティ」タブをクリックすると、このインスタンスのセキュリティグループが表示されているのでそれをクリックします。
「インバウンドルール」タブにある「Edit inbound rules」をクリックするとインバウンドルールの編集画面が表示されます。

インバウンドルールの編集

「ルールを追加」をクリックすると行が増えるので、タイプ「HTTPS」を選択し、ソース「Anywhere-IPv4」を選択します。
右下「ルールを保存」をクリックすれば完了です。

これで 443 ポートの開放ができました。


証明書の発行
mod_md では Apache を再起動することで自動的に認証が行われ証明書が発行されます。
管理者権限のコマンドプロンプトより再起動のコマンドを実行します。

>cd \Apache24\bin
>httpd.exe -k restart # Apacheの再起動

1回目の再起動では、HTTPS でアクセスしてみてもエラーとなるようです。

SSLエラー画面

error_log を見てみると、次回サーバ再起動時より変更が有効になる旨のメッセージが出力されています。

[ssl:warn] AH10085: Init: mydomain.com:443 will respond with '503 Service Unavailable' for now. There are no SSL certificates configured and no other module contributed any.
[md:notice] AH10059: The Managed Domain mydomain.com has been setup and changes will be activated on next (graceful) server restart.

証明書は Apache の仮証明書 Apache Managed Domain Fallback になっています。

Apache の仮証明書

再度、Apache を再起動してみます。
画面はエラーのままですが、証明書は Let’s Encrypt が発行したもの (STAGING) Artificial Apricot R3 になっているようです。

Let's Encryptのステージング証明書

※ドメイン名は加工してあります。

うまくいきそうなので、httpd.confMDCertificateAuthority をコメントアウトして本番用の URL にリクエストします。
その前にテスト用の証明書が Apache のインストール先フォルダ配下のmdというフォルダにインストールされているのでこれをフォルダごと削除します。

証明書インストール先フォルダ

httpd.confMDCertificateAuthority の行をコメントアウトし、Apache を再起動します。

[ssl:warn] AH10085: Init: mydomain.com:443 will respond with '503 Service Unavailable' for now. There are no SSL certificates configured and no other module contributed any.
[md:notice] AH10059: The Managed Domain mydomain.com has been setup and changes will be activated on next (graceful) server restart.

証明書が Apache Managed Domain Fallback に戻り、error_log にも同じメッセージが出力されます。
ここで再起動をかけると、画面が正常に出力され、証明書もきちんと発行されます。

Let's Encryptの証明書

以上で Let’s Encrypt の導入が完了しました。

参考: Windows Server + Apache + PHP + MariaDB のサーバ構築
参考: AWS EC2 に Let’s Encrypt をインストールする

コメント