証明書の作成
-
自己認証局 秘密鍵・証明書作成
openssl req \ -new \ -out ca.crt \ -keyout ca.key \ -x509 \ -days 3650 \ -newkey rsa:2048 \ -nodes \ -subj "/CN=PrivateCA"
-
サーバ証明書作成
-
秘密鍵・CSR作成
openssl req \ -new \ -out example.local.csr \ -keyout example.local.key \ -newkey rsa:2048 \ -nodes \ -subj "/CN=example.local"
-
Subject Alternative Name の準備
ここでは
san_server.txt
とします。echo "subjectAltName = DNS:localhost, DNS:example.local, IP:127.0.0.1, IP:192.168.1.10" > san_server.txt
-
CSR へ署名
openssl x509 \ -req \ -days 3650 \ -in example.local.csr \ -out example.local.crt \ -CA ca.crt \ -CAkey ca.key \ -CAcreateserial \ -extfile san_server.txt
-
-
クライアント証明書
-
秘密鍵・CSR作成
openssl req \ -new \ -out client.csr \ -keyout client.key \ -newkey rsa:2048 \ -nodes \ -subj "/CN=client.example.local"
-
Subject Alternative Name の準備
ここでは
san_client.txt
とします。echo "subjectAltName = DNS:client.example.local, IP:192.168.1.100" > san_client.txt
-
CSR へ署名
openssl x509 \ -req \ -days 3650 \ -in client.csr \ -out client.crt \ -CA ca.crt \ -CAkey ca.key \ -CAcreateserial \ -extfile san_client.txt
-
作成した証明書の確認
openssl x509 -in example.local.crt -text -noout
openssl x509 -in client.crt -text -noout
OS の信頼する CA に PrivateCA を追加する
-
PrivateCA 証明書を
/usr/local/share/ca-certificates/
にコピーsudo cp ca.crt /usr/local/share/ca-certificates/privateca.crt
-
証明書の更新
sudo update-ca-certificates
-
更新の確認
ls /etc/ssl/certs/privateca.pem
初めから PrivateCA 証明書を
/etc/ssl/certs/
にコピーすれば良いような気もしますが、更新コマンドが用意されているので、正しい手段を使用しています。
Apache の設定例
-
Apache Web サーバのインストール
sudo apt install -y apache2
-
SSL モジュールの有効化
sudo a2enmod ssl
-
証明書の格納
sudo cp example.local.crt /etc/ssl/certs/ sudo cp example.local.key /etc/ssl/private/
-
TLS 設定
/etc/apache2/sites-available/default-ssl.conf の編集
--- /tmp/default-ssl.conf 2024-09-22 21:01:12.605553001 +0900 +++ /etc/apache2/sites-available/default-ssl.conf 2024-09-22 21:03:21.713735006 +0900 @@ -29,8 +29,8 @@ # /usr/share/doc/apache2/README.Debian.gz for more info. # If both key and certificate are stored in the same file, only the # SSLCertificateFile directive is needed. - SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem - SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key + SSLCertificateFile /etc/ssl/certs/example.local.crt + SSLCertificateKeyFile /etc/ssl/private/example.local.key # Server Certificate Chain: # Point SSLCertificateChainFile at a file containing the @@ -48,7 +48,7 @@ # Note: Inside SSLCACertificatePath you need hash symlinks # to point to the certificate files. Use the provided # Makefile to update the hash symlinks after changes. - #SSLCACertificatePath /etc/ssl/certs/ + SSLCACertificatePath /etc/ssl/certs/ #SSLCACertificateFile /etc/apache2/ssl.crt/ca-bundle.crt # Certificate Revocation Lists (CRL):
-
SSL サイトの有効化
sudo a2ensite default-ssl.conf sudo service apache2 reload
-
動作確認
curl https://localhost/
サーバ証明書の
Subject Alternative Name
で設定した FQDN と IP アドレスであれば--insecure
無しでもエラーにならないと思います。
mTLS
-
mTLS 設定 (クライアント証明書を必須にする)
--- /tmp/default-ssl.conf 2024-09-22 21:19:36.582552012 +0900 +++ /etc/apache2/sites-available/default-ssl.conf 2024-09-22 21:19:59.752602009 +0900 @@ -66,8 +66,8 @@ # none, optional, require and optional_no_ca. Depth is a # number which specifies how deeply to verify the certificate # issuer chain before deciding the certificate is not valid. - #SSLVerifyClient require - #SSLVerifyDepth 10 + SSLVerifyClient require + SSLVerifyDepth 2 # SSL Engine Options: # Set various options for the SSL engine.
sudo service apache2 reload
-
動作確認
curl --cert client.crt --key client.key https://localhost/
その他
Python で動作確認をする場合
import requests
url = "https://localhost/"
cert = ('./client.crt', './client.key')
response = requests.get(url, cert=cert, verify='/etc/ssl/certs/privateca.pem', timeout=5)
print(f"Status Code: {response.status_code}")
Python の Requests では、OS の信頼する CA リストを参照していないので、verify=
で PrivateCA の証明書のファイルパスを指定するか、/usr/local/lib/python3.10/dist-packages/certifi/cacert.pem
に PrivateCA の証明書を追加する必要があります。