手当たり次第に書くんだ

飽きっぽいのは本能

Ubuntu 22.04 Apache TLS – 内部 CA 証明書で HTTPS を有効化する

Ubuntu 22.04 の Apache で内部向け HTTPS を使う場合、証明書を置くだけでなく、サーバー証明書、秘密鍵、内部 CA 証明書、VirtualHost、クライアント側の信頼を一つずつ確認します。

この記事では、内部 CA で発行した SAN 付き証明書を Apache に設定し、curlopenssl s_client で検証する流れを扱います。Ubuntu 22.04 の既存環境を保守するための確認記事です。

関連する記事
この記事で確認すること
  • Apache で TLS を有効化する前提
  • 証明書、秘密鍵、CA 証明書の配置
  • TLS 用 VirtualHost の作成
  • curlopenssl s_client による検証
  • HTTP から HTTPS へのリダイレクト
参考
書籍
参考書籍

暗号技術入門 第3版 秘密の国のアリス

TLS、証明書、CA の基本を確認したい場合の参考書籍です。価格や在庫はリンク先で確認してください。

Amazon で見る

このリンクは Amazon アソシエイトリンクです。

Apache TLS で確認するもの

Apache 側で必要になるファイルは、サーバー証明書、サーバー秘密鍵、必要に応じて CA 証明書または中間 CA 証明書です。内部 CA の秘密鍵は Apache サーバーへ置きません。

  • サーバー証明書の SAN に接続名が入っている
  • サーバー証明書と秘密鍵が対応している
  • 秘密鍵の権限が広すぎない
  • Apache の ssl モジュールが有効である
  • クライアント側が内部 CA を信頼している

ここでは例として server.example.local を使います。実際の FQDN、証明書名、DocumentRoot に置き換えてください。

証明書と秘密鍵を配置する

証明書と秘密鍵は用途が分かる場所へ配置します。秘密鍵は ssl-cert グループに限定し、通常ユーザーから読めない権限にします。

sudo install -d -m 0750 -o root -g ssl-cert /etc/ssl/local
sudo install -m 0644 server.example.local.crt /etc/ssl/local/server.example.local.crt
sudo install -m 0644 internal-ca.crt /etc/ssl/local/internal-ca.crt
sudo install -m 0640 -o root -g ssl-cert server.example.local.key /etc/ssl/local/server.example.local.key
sudo ls -l /etc/ssl/local

Apache が秘密鍵を読めない場合は、TLS 設定そのものが正しくても起動や reload に失敗します。権限を広げる前に、Apache の実行ユーザーとグループを確認します。

ps -eo user,group,comm | grep '[a]pache2'
groups www-data
sudo apache2ctl -M | grep ssl || true

SSL モジュールを有効化する

Apache で HTTPS を扱うには ssl モジュールを有効化します。設定変更後は configtest を通してから reload します。

sudo a2enmod ssl
sudo apache2ctl configtest
sudo systemctl reload apache2

TLS 用 VirtualHost を作成する

TLS 用の VirtualHost を /etc/apache2/sites-available/ に作成します。SSLCertificateFileSSLCertificateKeyFile には、配置したファイルを指定します。

sudo tee /etc/apache2/sites-available/server.example.local-ssl.conf >/dev/null <<'EOF'
<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerName server.example.local
    ServerAdmin webmaster@example.local
    DocumentRoot /var/www/html
    SSLEngine on
    SSLCertificateFile /etc/ssl/local/server.example.local.crt
    SSLCertificateKeyFile /etc/ssl/local/server.example.local.key
    ErrorLog ${APACHE_LOG_DIR}/server.example.local-ssl-error.log
    CustomLog ${APACHE_LOG_DIR}/server.example.local-ssl-access.log combined
</VirtualHost>
</IfModule>
EOF

中間 CA がある場合は、サーバー証明書と中間 CA を連結した full chain を SSLCertificateFile に指定する構成を検討します。内部 CA が 1 段だけなら、サーバー証明書だけで足りる場合があります。

サイトを有効化する

設定ファイルを作成したらサイトを有効化し、構文確認後に Apache を reload します。

sudo a2ensite server.example.local-ssl.conf
sudo apache2ctl configtest
sudo systemctl reload apache2
sudo systemctl status apache2 --no-pager

reload に失敗する場合は、Apache のエラーログと journal を確認します。証明書ファイルの path、秘密鍵の権限、VirtualHost の重複がよくある原因です。

sudo journalctl -u apache2 -n 80 --no-pager
sudo tail -n 80 /var/log/apache2/server.example.local-ssl-error.log

curl で確認する

まず curl で HTTPS 接続を確認します。クライアント側に内部 CA が登録されていない場合は、--cacert で CA 証明書を指定して切り分けます。

curl -Iv https://server.example.local/
curl --cacert internal-ca.crt -Iv https://server.example.local/

通常の curl で失敗し、--cacert で成功する場合は、クライアント側の信頼ストア登録が不足しています。

openssl s_client で確認する

openssl s_client では、Apache が提示している証明書、SAN、検証結果を詳しく見られます。名前検証のために -servername を指定します。

openssl s_client -connect server.example.local:443 -servername server.example.local -verify_return_error </dev/null
openssl s_client -connect server.example.local:443 -servername server.example.local -CAfile /etc/ssl/certs/ca-certificates.crt -verify_return_error </dev/null

Verify return code: 0 になれば、証明書チェーンの検証は成功しています。失敗する場合は、CA 登録、SAN、Apache が提示している証明書を分けて確認します。

証明書と秘密鍵の対応を確認する

証明書と秘密鍵が対応していないと Apache は TLS を開始できません。RSA 鍵の場合は modulus の hash で対応を確認できます。EC 鍵の場合は公開鍵を取り出して比較します。

openssl x509 -noout -modulus -in /etc/ssl/local/server.example.local.crt | openssl md5
sudo openssl rsa -noout -modulus -in /etc/ssl/local/server.example.local.key | openssl md5
openssl x509 -in /etc/ssl/local/server.example.local.crt -pubkey -noout | openssl sha256
sudo openssl pkey -in /etc/ssl/local/server.example.local.key -pubout | openssl sha256

HTTP から HTTPS へリダイレクトする

HTTP でアクセスされたときに HTTPS へ誘導する場合は、80 番用の VirtualHost を分けて設定します。TLS の疎通確認が終わってから有効化すると切り分けやすいです。

sudo tee /etc/apache2/sites-available/server.example.local.conf >/dev/null <<'EOF'
<VirtualHost *:80>
    ServerName server.example.local
    Redirect permanent / https://server.example.local/
</VirtualHost>
EOF
sudo a2ensite server.example.local.conf
sudo apache2ctl configtest
sudo systemctl reload apache2

リダイレクト後は、HTTP と HTTPS の両方を確認します。内部 CA を信頼していないクライアントでは、HTTPS へ移動した後に証明書エラーになります。

curl -I http://server.example.local/
curl -I https://server.example.local/

運用上の注意

  • 内部 CA の秘密鍵を Apache サーバーへ置かない
  • サーバー証明書の SAN とアクセス名を合わせる
  • 秘密鍵の権限を広げすぎない
  • 証明書更新後は Apache の reload と実接続確認を行う
  • クライアント側の信頼ストア登録も手順に含める

Apache の TLS 設定は、サーバー側だけで完結しません。内部 CA を使う場合は、証明書発行、Apache 設定、クライアントの CA 信頼、更新時の反映までを一つの流れとして確認します。

まとめ

Ubuntu 22.04 の Apache で内部 CA 証明書を使う場合は、サーバー証明書、秘密鍵、VirtualHost、クライアント側の信頼を分けて確認します。curlopenssl s_client を併用すると、Apache が提示している証明書とクライアント側の信頼を切り分けやすくなります。

TLS 化そのものよりも、SAN、秘密鍵の権限、証明書更新、HTTP から HTTPS への誘導、内部 CA の配布範囲を明確にしておくことが重要です。

関連する記事
Ubuntu 22.04 Apache TLS – 内部 CA 証明書で HTTPS を有効化する

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

トップへ戻る