1. 概要
2. 自己認証局と自己署名証明書の作り方
— 2.1. 自己認証局の作り方
— 2.2. CRL(証明書失効リスト)の作成
— 2.3. 自己署名証明書の作り方
— 2.4. Apacheに証明書と秘密鍵を配置
3. curl 疎通確認
— 3.1. /etc/ssl/certsにCA証明書を配置する
— 3.2. 自己署名証明書利用時に指定するcurl オプション
4. 参考資料
概要
- 今回はテストのため、開発環境に自己認証局を構築し、自己認証局による自己署名証明書を発行しました。手順をまとめます。
- 自己署名証明書は、自分を認証局(CA)として立て、自分で自分の正当性を証明するいわゆる「オレオレ証明書」となります。自己署名証明書の利用で、通信は暗号化されますが、組織の実在性確認はできません。あくまでもテスト向けであり、サービス向けには信頼できる第三者認証局が発行した証明書を利用します。
- AWS では、ACM(AWS Certificate Manager)で証明書を発行する構成が多いですが、Load Balancer ではSSL終端せず、バックエンドのEC2やコンテナでSSL終端もあり得ます。このような構成では、ACMではなく、外部認証局 or 自己認証局で発行した証明書をバックエンド側で配置することもあります。
自己認証局と自己署名証明書の作り方
自己認証局の作り方
- 先ず、自己認証局用の秘密鍵と証明書を作成します。
- Linuxサーバーにhttpd, mod_sslをインストールします。(下記ログには含まず)
- openssl genrsaコマンドで、RSA 2048 bit の秘密鍵を作成します。秘密鍵は、/etc/pki/CA/private/niikawa-test-ca.key として配置しています。
- openssl reqコマンドで上記秘密鍵を使用して、CSRを作成します。-keyで秘密鍵を指定します。証明書の署名アルゴリズムにSHA-256を指定します。CSRは、/etc/pki/CA/niikawa-test-cacert.csr として配置しています。
- openssl x509コマンドで、CA証明書を発行します。-inでCSRを指定します。CAの秘密鍵で署名します。-signkeyで秘密鍵を指定します。-daysで有効期間を指定します。有効期間は3年(1095日)とします。証明書は/etc/pki/CA/certs/niikawa-test-cacert.pem として配置します。
# openssl genrsa 2048 > /etc/pki/CA/private/niikawa-test-ca.key Generating RSA private key, 2048 bit long modulus ......+++ ....+++ e is 65537 (0x10001) # openssl req -new -key /etc/pki/CA/private/niikawa-test-ca.key -sha256 -out /etc/pki/CA/niikawa-test-cacert.csr You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [XX]:JP State or Province Name (full name) []:Mie Locality Name (eg, city) [Default City]:Kuwana Organization Name (eg, company) [Default Company Ltd]:oji-cloud Organizational Unit Name (eg, section) []: Common Name (eg, your name or your server's hostname) []:niikawa-test-ca Email Address []: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: # openssl x509 -days 1095 -in /etc/pki/CA/niikawa-test-cacert.csr -req -signkey /etc/pki/CA/private/niikawa-test-ca.key -out /etc/pki/CA/certs/niikawa-test-cacert.pem Signature ok subject=/C=JP/ST=Mie/L=Kuwana/O=oji-cloud/CN=niikawa-test-ca Getting Private key
CRL(証明書失効リスト)の作成
- 次にCAとして管理するCRL(証明書失効リスト)を作成します。CRLは、失効した公開鍵証明書のリスト(証明書のシリアル番号のリスト)です。CRLがない場合、次の証明書作成でエラーとなります。今回はテストのため、証明書のシリアル番号は”0x1″ とします。本来はもっと桁数の多いシリアル番号です。
- 有効(Valid)な証明書は、index.txt の先頭に“V”がマークされます。失効された(Revoked)証明書は、先頭に“R”がマークされます。
# touch /etc/pki/CA/index.txt # echo 01 > /etc/pki/CA/serial
自己署名証明書の作り方
- openssl genrsaコマンドで、RSA 2048 bit の秘密鍵を作成します。秘密鍵は、/etc/pki/tls/private/niikawa-test-servercert.key として配置しています。
- openssl reqコマンドで上記秘密鍵を使用して、CSRを作成します。-keyで秘密鍵を指定します。証明書の署名アルゴリズムにSHA-256を指定します。CSRは、/etc/pki/tls/niikawa-test-servercert.csr として配置しています。
- openssl caコマンドで、サーバー証明書を発行します。-inでCSRを指定します。CAの秘密鍵で署名します。-keyfileで秘密鍵を指定します。-certでCAの証明書を指定します。-daysで有効期間を指定します。有効期間は3年(1095日)とします。証明書は/etc/pki/tls/certs/niikawa-test-servercert.pem として配置します。
# openssl genrsa 2048 > /etc/pki/tls/private/niikawa-test-servercert.key Generating RSA private key, 2048 bit long modulus ........................................................................+++ ...................................................................................................................................................+++ e is 65537 (0x10001) # openssl req -new -key /etc/pki/tls/private/niikawa-test-servercert.key -sha256 -out /etc/pki/tls/niikawa-test-servercert.csr You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [XX]:JP State or Province Name (full name) []:Mie Locality Name (eg, city) [Default City]:Kuwana Organization Name (eg, company) [Default Company Ltd]:oji-cloud Organizational Unit Name (eg, section) []: Common Name (eg, your name or your server's hostname) []:niikawa-test-http.oji-cloud.net Email Address []: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: # openssl ca -days 1095 -in /etc/pki/tls/niikawa-test-servercert.csr -out /etc/pki/tls/certs/niikawa-test-servercert.pem -keyfile /etc/pki/CA/private/niikawa-test-ca.key -cert /etc/pki/CA/certs/niikawa-test-cacert.pem Using configuration from /etc/pki/tls/openssl.cnf Check that the request matches the signature Signature ok Certificate Details: Serial Number: 1 (0x1) Validity Not Before: Sep 24 12:33:47 2020 GMT Not After : Sep 24 12:33:47 2023 GMT Subject: countryName = JP stateOrProvinceName = Mie organizationName = oji-cloud commonName = niikawa-test-http.oji-cloud.net X509v3 extensions: X509v3 Basic Constraints: CA:FALSE Netscape Comment: OpenSSL Generated Certificate X509v3 Subject Key Identifier: 35:D0:A1:40:EC:F3:8D:C9:FC:16:E2:7B:69:55:C7:0E:46:1D:F1:6B X509v3 Authority Key Identifier: DirName:/C=JP/ST=Mie/L=Kuwana/O=oji-cloud/CN=niikawa-test-ca serial:9F:CC:AC:49:33:C1:34:FD Certificate is to be certified until Sep 24 12:33:47 2023 GMT (1095 days) Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated #
- 下記の通り、CRL(証明書失効リスト)が更新されました。index.txtに証明書の情報が追加されています。有効(Valid)な証明書のため、”V”がマークされています。CAで失効された(Revoked)場合は、”R” がマークされます。
- serialのシリアル番号がカウントアップし、次の証明書には”0x2″が使われます。
# cat /etc/pki/CA/index.txt V 230924123347Z 01 unknown /C=JP/ST=Mie/O=oji-cloud/CN=niikawa-test-http.oji-cloud.net # cat /etc/pki/CA/serial 02
- opensslコマンドで、発行された証明書の内容を確認します。
# openssl x509 -text -noout -in /etc/pki/tls/certs/niikawa-test-servercert.pem Certificate: Data: Version: 3 (0x2) Serial Number: 1 (0x1) Signature Algorithm: sha256WithRSAEncryption Issuer: C=JP, ST=Mie, L=Kuwana, O=oji-cloud, CN=niikawa-test-ca Validity Not Before: Sep 24 12:33:47 2020 GMT Not After : Sep 24 12:33:47 2023 GMT Subject: C=JP, ST=Mie, O=oji-cloud, CN=niikawa-test-http.oji-cloud.net Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:c8:0b:07:48:f4:f1:ed:21:13:fd:94:b3:6c:bf: f8:a6:ce:5c:94:85:9f:e0:40:d2:26:f2:f7:54:5e: 59:60:39:96:c9:48:fc:bf:a4:67:dc:64:f2:50:76: 33:37:3f:9c:b0:06:df:fa:a2:11:3d:84:63:e1:8f: 25:23:c1:f6:df:da:ff:d0:21:70:f6:f4:42:5d:af: 2c:83:0e:42:fc:91:85:24:4e:f1:ae:a7:45:e4:44: ba:73:c4:d4:1a:78:22:98:ee:8b:8a:ec:90:e6:6b: f8:62:a0:d9:5a:3d:06:da:9c:e6:72:ff:2d:fe:e9: 06:dd:2c:71:d4:6e:90:b7:02:9f:0f:ea:2c:b6:07: c9:a8:74:74:a6:db:90:05:75:19:bb:05:f8:e4:5c: 54:22:6d:df:d8:9c:ed:e7:5a:da:a3:ba:98:be:62: b0:2d:5f:c7:62:29:50:65:59:bd:0e:ce:17:c5:dc: 19:24:6d:38:06:08:0c:81:3b:26:84:d9:89:aa:a6: 4d:1d:bb:d2:b2:04:82:90:9b:df:31:65:b7:91:e3: 81:08:6b:03:58:c9:4a:73:d7:50:d7:c1:99:21:81: 41:db:1f:c4:48:56:35:ef:d4:10:e2:b9:9e:70:9b: 9a:a0:ba:23:96:c6:ab:f9:71:ec:ed:5d:67:63:c7: 3f:8b Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: CA:FALSE Netscape Comment: OpenSSL Generated Certificate X509v3 Subject Key Identifier: 35:D0:A1:40:EC:F3:8D:C9:FC:16:E2:7B:69:55:C7:0E:46:1D:F1:6B X509v3 Authority Key Identifier: DirName:/C=JP/ST=Mie/L=Kuwana/O=oji-cloud/CN=niikawa-test-ca serial:9F:CC:AC:49:33:C1:34:FD Signature Algorithm: sha256WithRSAEncryption bd:40:7e:ec:c3:ca:dd:80:d4:8c:53:28:72:70:62:62:ca:27: 7c:c1:9b:49:f4:cd:c3:ac:43:68:1c:db:fa:2e:29:06:61:b6: 4a:ef:6b:fa:fb:cf:1a:0c:d0:d5:7d:3d:85:65:3d:95:63:ca: 70:88:90:43:ba:df:cc:a7:94:18:16:9b:ff:4f:e6:69:3a:6c: 26:e4:fd:48:92:29:f3:78:d6:6a:e9:b2:e1:8c:6d:35:a4:a0: 34:6b:44:5e:e3:a3:c9:ab:60:ac:d1:8d:51:f4:d7:19:ea:d5: 5a:64:c9:05:3f:8c:61:72:b8:47:59:fb:3b:ce:b0:73:ae:11: f5:20:0e:e7:97:a3:50:be:a0:cf:3e:6f:7d:ef:49:f2:47:ae: e0:17:e5:64:cf:4f:cd:fb:c8:c6:81:d8:4d:da:e8:91:e7:0e: f1:bc:70:de:9b:da:fa:25:0a:f5:b1:97:15:57:a0:77:b3:7d: 61:a6:13:72:46:b7:3d:1c:c7:f5:59:a5:40:75:e1:6a:53:2a: d2:94:24:6f:a8:3b:2f:d6:21:b1:3a:6e:72:8f:da:e9:95:18: 28:78:d6:38:25:05:eb:df:65:06:9f:0e:6e:40:b7:2c:b1:f5: 53:96:e3:6e:fb:88:14:a8:30:3d:14:27:4e:d0:8e:9a:1f:20: a4:09:2b:a8
Apacheに証明書と秘密鍵を配置
- /etc/httpd/conf.d/ssl.conf に証明書および秘密鍵を指定します。vhost を作成している場合は、vhostのconf を編集します。
# Server Certificate: # Point SSLCertificateFile at a PEM encoded certificate. If # the certificate is encrypted, then you will be prompted for a # pass phrase. Note that a kill -HUP will prompt again. A new # certificate can be generated using the genkey(1) command. SSLCertificateFile /etc/pki/tls/certs/niikawa-test-servercert.pem ← 変更 # Server Private Key: # If the key is not combined with the certificate, use this # directive to point at the key file. Keep in mind that if # you've both a RSA and a DSA private key you can configure # both in parallel (to also allow the use of DSA ciphers, etc.) SSLCertificateKeyFile /etc/pki/tls/private/niikawa-test-servercert.key ← 変更 # Certificate Authority (CA): # Set the CA certificate verification path where to find CA # certificates for client authentication or alternatively one # huge file containing all of them (file must be PEM encoded) SSLCACertificateFile /etc/pki/CA/certs/niikawa-test-cacert.pem ← 変更
- httpdを再起動します。
systemctl restart httpd
curl 疎通確認
/etc/ssl/certsにCA証明書を配置する
- クライアントからcurl を実行します。今回、クライアントにはCA証明書が存在しないため、/etc/ssl/certsにCA証明書を配置しています。
- しかし、今回は自己証明書を利用しているため、“SSL certificate problem" が出力されました。"self signed certificate in certificate chain" とあり、自己署名証明書のためエラーとなっているようです。
niikawa@niikawa1:~$ curl -vv https://niikawa-test-http.oji-cloud.net * Rebuilt URL to: https://niikawa-test-http.oji-cloud.net/ * Trying XX.XX.XX.XX... * TCP_NODELAY set * Connected to niikawa-test-http.oji-cloud.net (XX.XX.XX.XX) port 443 (#0) * ALPN, offering h2 * ALPN, offering http/1.1 * successfully set certificate verify locations: * CAfile: /etc/ssl/certs/ca-certificates.crt CApath: /etc/ssl/certs * TLSv1.3 (OUT), TLS handshake, Client hello (1): * TLSv1.3 (IN), TLS handshake, Server hello (2): * TLSv1.2 (IN), TLS handshake, Certificate (11): * TLSv1.2 (OUT), TLS alert, Server hello (2): * SSL certificate problem: self signed certificate in certificate chain * stopped the pause stream! * Closing connection 0 curl: (60) SSL certificate problem: self signed certificate in certificate chain More details here: https://curl.haxx.se/docs/sslcerts.html curl failed to verify the legitimacy of the server and therefore could not establish a secure connection to it. To learn more about this situation and how to fix it, please visit the web page mentioned above.
自己署名証明書利用時に指定するcurl オプション
- 自己署名証明書利用時に出力された”SSL certificate problem” を回避するため、curl に“–insecure”オプションを追加します。次は無事にリクエストが送られ、レスポンス 200 OK も返りました。
niikawa@niikawa1:~$ curl -vv https://niikawa-test-http.oji-cloud.net --insecure * Rebuilt URL to: https://niikawa-test-http.oji-cloud.net/ * Trying XX.XX.XX.XX... * TCP_NODELAY set * Connected to niikawa-test-http.oji-cloud.net (XX.XX.XX.XX) port 443 (#0) * ALPN, offering h2 * ALPN, offering http/1.1 * successfully set certificate verify locations: * CAfile: /etc/ssl/certs/ca-certificates.crt CApath: /etc/ssl/certs * TLSv1.3 (OUT), TLS handshake, Client hello (1): * TLSv1.3 (IN), TLS handshake, Server hello (2): * TLSv1.2 (IN), TLS handshake, Certificate (11): * TLSv1.2 (IN), TLS handshake, Server key exchange (12): * TLSv1.2 (IN), TLS handshake, Server finished (14): * TLSv1.2 (OUT), TLS handshake, Client key exchange (16): * TLSv1.2 (OUT), TLS change cipher, Client hello (1): * TLSv1.2 (OUT), TLS handshake, Finished (20): * TLSv1.2 (IN), TLS handshake, Finished (20): * SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384 * ALPN, server accepted to use http/1.1 * Server certificate: * subject: C=JP; ST=Mie; O=oji-cloud; CN=niikawa-test-http.oji-cloud.net * start date: Sep 24 12:33:47 2020 GMT * expire date: Sep 24 12:33:47 2023 GMT * issuer: C=JP; ST=Mie; L=Kuwana; O=oji-cloud; CN=niikawa-test-ca * SSL certificate verify result: self signed certificate in certificate chain (19), continuing anyway. > GET / HTTP/1.1 > Host: niikawa-test-http.oji-cloud.net > User-Agent: curl/7.58.0 > Accept: */* > < HTTP/1.1 200 OK < Date: Thu, 24 Sep 2020 16:36:19 GMT < Server: Apache/2.4.46 () OpenSSL/1.0.2k-fips < Upgrade: h2,h2c < Connection: Upgrade < Last-Modified: Thu, 24 Sep 2020 07:29:39 GMT < ETag: "d-5b00a29b46f92" < Accept-Ranges: bytes < Content-Length: 13 < Content-Type: text/html; charset=UTF-8 < niikawa-test * Connection #0 to host niikawa-test-http.oji-cloud.net left intact