linux:openssl_private_ca

OpenSSL によるプライベート CA の構築

$ sudo dnf install openssl

メタデータの期限切れの最終確認: 0:26:53 時間前の 2023年05月15日 08時55分29秒 に実施しました。
依存関係が解決しました。
==============================================================================================================
 パッケージ              アーキテクチャー       バージョン                       リポジトリー           サイズ
==============================================================================================================
インストール:
 openssl                 x86_64                 1:3.0.8-2.fc38                   fedora                 1.0 M

トランザクションの概要
==============================================================================================================
インストール  1 パッケージ

ダウンロードサイズの合計: 1.0 M
インストール後のサイズ: 1.6 M
これでよろしいですか? [y/N]: y
パッケージのダウンロード:
openssl-3.0.8-2.fc38.x86_64.rpm                                               629 kB/s | 1.0 MB     00:01    
--------------------------------------------------------------------------------------------------------------
合計                                                                          395 kB/s | 1.0 MB     00:02     
トランザクションの確認を実行中
トランザクションの確認に成功しました。
トランザクションのテストを実行中
トランザクションのテストに成功しました。
トランザクションを実行中
  準備             :                                                                                      1/1 
  インストール中   : openssl-1:3.0.8-2.fc38.x86_64                                                        1/1 
  scriptletの実行中: openssl-1:3.0.8-2.fc38.x86_64                                                        1/1 
  検証             : openssl-1:3.0.8-2.fc38.x86_64                                                        1/1 

インストール済み:
  openssl-1:3.0.8-2.fc38.x86_64                                                                               

完了しました!

$ sudo mkdir -p /etc/pki/mgcCA/{certs,client,crl,newcerts,private}
$ sudo touch /etc/pki/mgcCA/{index.txt,index.txt.attr,serial}
$ sudo bash -c "echo '01' > /etc/pki/mgcCA/serial"
$ ll /etc/pki/mgcCA/
drwxr-xr-x 1 root root 0  2月 11 11:26 certs
drwxr-xr-x 1 root root 0  2月 11 11:26 client
drwxr-xr-x 1 root root 0  2月 11 11:26 crl
-rw-r--r-- 1 root root 0  2月 11 11:27 index.txt
-rw-r--r-- 1 root root 0  2月 11 11:27 index.txt.attr
drwxr-xr-x 1 root root 0  2月 11 11:26 newcerts
drwxr-xr-x 1 root root 0  2月 11 11:26 private
-rw-r--r-- 1 root root 3  2月 11 11:27 serial

ディレクトリ 説明 ファイル 説明
certs 証明書保管用 index.txt newcerts ディレクトリ内に保管される証明書の
通番(nn)と識別名DN(Distinguished Name)との対応表
client クライアント CSR、証明書、秘密鍵、PKCS#12 フォーマットのファイルのバックアップ用 index.txt.attr index.txtにて管理する通番に重複を許すかどうかの設定
unique_subject = yes : 重複を許さない(デフォルト)
unique_subject = no : 重複を許す
crl 失効リスト(Certificate Revocation List)保管用 serial 次に発行する証明書の通番(nn)
newcerts 新規に発行した証明書保管用
private CAの秘密鍵保管用

証明書作成の際に入力の手間を省くために、デフォルト値を設定しておく。

設定ファイルをコピーする。

$ sudo cp /etc/pki/tls/openssl.cnf /etc/pki/mgcCA/


設定ファイルを編集する。

$ sudo vi /etc/pki/mgcCA/openssl.cnf
[ CA_default ]
dir		= /etc/pki/mgcCA	# 認証局ディレクトリパス
default_days    = 36500			# 証明書の有効期限は100年
 
[ req ]
default_bits			= 2048
default_md			= sha256
 
[ req_distinguished_name ]
countryName_default		= JP # 国コード
stateOrProvinceName_default	= Hokkaido Pref. # 都道府県
localityName_default		= Sapporo City # 市町村区
# 会社名 or ドメイン名(行末の#がコメントとして扱われない、' が無視されるので注意)
0.organizationName_default	= Monster's Garage Co.,Ltd.
organizationalUnitName_default	= - # 組織部門名
emailAddress_default		= domain-admin@monsters-g.com # 管理者メールアドレス

openssl.cnf をコピーして、認証局(ca)、サーバー(server)、クライアント(client)用の設定ファイルを準備する。

$ sudo bash -c 'd=/etc/pki/mgcCA; for f in $d/openssl-mgc-{ca,server,client}.cnf; do cp $d/openssl.cnf $f; done'
ファイル 説明
private/cakey.pem CA 秘密鍵
cacert.pem CA 証明書
mgc_ca_cert.der CA 証明書(DER形式)

openssl-mgc-ca.cnf(認証局用設定ファイル)を編集する。

$ sudo vi /etc/pki/mgcCA/openssl-mgc-ca.cnf
[ usr_cert ]
basicConstraints=CA:TRUE # CA証明書
 
[ v3_ca ]
# nsCertType = sslCA, emailCA
nsCertType = sslCA, emailCA # SSL認証局、電子メール認証局

CA の秘密鍵と証明書を作成する。

$ sudo openssl req -new -config /etc/pki/mgcCA/openssl-mgc-ca.cnf -x509 -days 36500 -keyout /etc/pki/mgcCA/private/cakey.pem -out /etc/pki/mgcCA/cacert.pem
Generating a RSA private key
.................................................+++++
..................................................................................+++++
writing new private key to '/etc/pki/mgcCA/private/cakey.pem'
Enter PEM pass phrase: # プライベート認証局のパスフレーズを入力
Verifying - Enter PEM pass phrase: # プライベート認証局の確認用パスフレーズを入力
-----
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) [JP]: # Enter を入力
State or Province Name (full name) [Hokkaido Pref.]: # Enter を入力
Locality Name (eg, city) [Sapporo City]: # Enter を入力
Organization Name (eg, company) [Monsters Garage Co.,Ltd.]:Monster's Garage Co.,Ltd. # 会社名 or ドメイン名を入力
Organizational Unit Name (eg, section) [-]: # Enter を入力
Common Name (eg, your name or your server's hostname) []:Monster's Garage CA # CA名称 or ホスト名を入力
Email Address [domain-admin@monsters-g.com]: # Enter を入力

CA証明書の確認。

$ openssl x509 -in /etc/pki/mgcCA/cacert.pem -text -noout
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            46:fa:04:8a:29:79:6e:68:cd:9f:45:54:be:42:5b:ef:4f:8f:54:4c
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = JP, ST = Hokkaido Pref., L = Sapporo City, O = "Monster's Garage Co.,Ltd.", OU = -, CN = Monster's Garage CA, emailAddress = domain-admin@monsters-g.com
        Validity
            Not Before: Feb 10 14:33:39 2019 GMT
            Not After : Jan 17 14:33:39 2119 GMT
        Subject: C = JP, ST = Hokkaido Pref., L = Sapporo City, O = "Monster's Garage Co.,Ltd.", OU = -, CN = Monster's Garage CA, emailAddress = domain-admin@monsters-g.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:dd:7e:eb:e7:ee:3c:f9:d8:58:0c:03:70:a2:96:
                    d6:97:7c:5a:31:6c:23:a8:93:b6:5b:21:99:31:21:
                    ca:3c:0e:21:d6:5b:85:09:66:54:c1:ef:db:89:a8:
                    f5:dc:8c:a2:5c:b2:b5:37:a1:69:80:1a:86:0d:92:
                    96:cb:22:47:a6:a6:ff:be:48:fc:f5:ac:02:bf:8c:
                    8a:0b:e0:84:32:f5:78:c1:67:bd:f6:5a:05:70:eb:
                    50:97:1b:19:8d:2a:62:59:30:9e:fe:cc:65:8f:94:
                    a1:aa:8f:39:df:b4:be:46:73:0c:5e:94:df:6a:62:
                    82:ba:6b:74:66:db:80:7c:9c:9c:58:aa:6a:0f:f9:
                    04:47:c1:3f:e0:05:eb:31:da:f6:f0:a8:b7:48:e0:
                    d8:16:42:17:86:49:36:d6:b1:72:ff:ba:18:08:ae:
                    01:71:41:b4:ba:e5:d7:ca:68:c4:64:0b:22:43:55:
                    fc:b6:bb:43:39:d4:51:83:39:a4:40:37:00:0f:9f:
                    2b:dd:f0:48:1b:3c:67:c3:df:e6:89:11:fb:cd:37:
                    c9:62:07:44:bb:e6:5f:7c:de:6f:5a:1e:61:b9:fa:
                    92:14:44:44:47:5b:8a:41:a8:d2:4a:02:18:a9:d2:
                    cc:ed:a2:1b:f1:15:10:86:23:7d:bf:78:ee:fa:c0:
                    bd:a3
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                75:0E:6F:10:D2:10:CF:F2:CF:6E:20:12:C7:AE:25:70:00:F0:CD:65
            X509v3 Authority Key Identifier: 
                keyid:75:0E:6F:10:D2:10:CF:F2:CF:6E:20:12:C7:AE:25:70:00:F0:CD:65

            X509v3 Basic Constraints: critical
                CA:TRUE
            Netscape Cert Type: 
                SSL CA, S/MIME CA
    Signature Algorithm: sha256WithRSAEncryption
         15:19:19:52:db:b6:bb:54:fd:94:1c:58:2f:28:8c:53:81:8d:
         ed:b1:5d:0e:f1:fe:c6:ec:ae:88:ab:b6:e2:13:40:07:78:2f:
         75:4b:ee:5f:77:a5:1f:55:b4:c3:25:fb:a6:02:3e:4d:3c:71:
         b6:2a:f9:d0:bf:75:dd:13:97:22:2b:b4:8a:aa:5c:c6:27:b7:
         af:4f:17:49:04:98:81:4b:55:14:3c:20:2c:86:74:75:47:d5:
         59:34:09:ab:02:a5:22:97:bf:5f:d9:e1:84:e3:68:18:93:c9:
         fd:df:1b:02:c7:96:93:52:2e:f1:8b:a5:1d:e8:d6:32:52:62:
         5f:1b:63:aa:a3:39:75:8e:82:1e:06:46:f4:a6:1b:b9:3f:db:
         88:78:9f:db:4c:f0:5d:ef:62:1b:37:37:63:31:1d:54:44:ff:
         04:a7:13:3b:82:af:e4:f2:46:de:ff:56:dc:d8:cc:86:7e:51:
         5a:69:5a:17:2c:4c:ee:38:3b:3b:3f:f0:30:1f:d5:7b:4c:d0:
         2e:27:3f:0d:cb:a7:0f:83:f9:18:68:b2:af:c9:9b:a0:ec:13:
         80:13:26:0b:af:25:75:5a:71:fa:6b:20:36:d7:da:09:b3:4c:
         de:60:68:02:24:43:59:cf:8a:0f:26:1f:71:de:a4:f4:78:44:
         90:bb:e5:7d

CA のカレントディレクトリの private/ に CA 秘密鍵とカレントディレクトリにCA 証明書が作成される。

$ ll /etc/pki/mgcCA/private/
-rw------- 1 root root 1854  2月 11 11:40 cakey.pem # CA 秘密鍵
$ ll /etc/pki/mgcCA/
-rw-r--r-- 1 root root  1586  2月 11 11:40 cacert.pem # CA 証明書

DER(Distinguished Encoding Rules) 形式は Windows OS で証明書や秘密鍵をインポートするのに使えるフォーマットである。
ここでは PEM 形式の CA 証明書を DER 形式に変換する。

$ sudo openssl x509 -inform pem -outform der -in /etc/pki/mgcCA/cacert.pem -out /etc/pki/mgcCA/mgc_ca_cert.der

CAのカレントディレクトリにCA 証明書(DER形式)が作成される。

$ ll /etc/pki/mgcCA/
-rw-r--r-- 1 root root  1126  2月 11 09:40 mgc_ca_cert.der # CA 証明書(DER形式)
ファイル 説明
serverkey.pem サーバー秘密鍵
serverreq.csr サーバー CSR
servercert.crt サーバー証明書
serverkey-nopwd.pem サーバー秘密鍵(パスフレーズなし)
san.ext SAN 追加設定ファイルを作成

 サーバー CSR は、パブリック認証局(Verisignなど)やプライベート認証局に対するサーバー証明書の署名要求である。
 認証局に署名して貰うことによって、証明書として利用できるようになる。

openssl-mgc-server.cnf(サーバー用設定ファイル)を編集する。

$ sudo vi /etc/pki/mgcCA/openssl-mgc-server.cnf
[ usr_cert ]
basicConstraints=CA:FALSE # CA証明書以外
nsCertType			= server # サーバー証明書


サーバー CSR(Certificate Signing Request) を作成する。

$ sudo openssl req -new -config /etc/pki/mgcCA/openssl-mgc-server.cnf \
-addext 'subjectAltName=DNS:localhost,DNS:*.tomoyan.net' \
-keyout /etc/pki/mgcCA/serverkey.pem -out /etc/pki/mgcCA/serverreq.csr
Generating a RSA private key
...................................+++++
......................................+++++
writing new private key to '/etc/pki/mgcCA/serverkey.pem'
Enter PEM pass phrase: # パスフレーズを入力
Verifying - Enter PEM pass phrase: # 確認用パスフレーズを入力
-----
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) [JP]: # Enter を入力
State or Province Name (full name) [Hokkaido Pref.]: # Enter を入力
Locality Name (eg, city) [Sapporo City]: # Enter を入力
Organization Name (eg, company) [Monsters Garage Co.,Ltd.]:Monster's Garage Co.,Ltd. # 会社名 or ドメイン名を入力
Organizational Unit Name (eg, section) [-]: # Enter を入力
Common Name (eg, your name or your server's hostname) []:tomoyan.net # Web サーバーで利用する場合はドメイン名を入力
Email Address [domain-admin@monsters-g.com]:domain-admin@tomoyan.net # 管理者メールアドレスを入力

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: # Enter を入力
An optional company name []: # Enter を入力


CAのカレントディレクトリにサーバー秘密鍵とサーバー CSR(証明書署名要求)が作成される。

$ ll /etc/pki/mgcCA/
-rw------- 1 root root  1854  210 23:57 serverkey.pem # サーバー秘密鍵
-rw-r--r-- 1 root root  1106  211 00:03 serverreq.csr # サーバー CSR(証明書署名要求)

※サーバー CSR は認証局に渡して署名して貰うことで証明書として利用できるようになる。
 秘密キーは証明書をサーバーで利用する際に必要になるので大事に保管しておくこと。


サーバー CSR の内容を確認する。

$ openssl req -in /etc/pki/mgcCA/serverreq.csr -text -noout
Certificate Request:
    Data:
        Version: 1 (0x0)
        Subject: C = JP, ST = Hokkaido Pref., L = Sapporo City, O = "Monster's Garage Co.,Ltd.", OU = -, CN = tomoyan.net, emailAddress = domain-admin@tomoyan.net
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:ad:8b:53:f7:40:38:70:8b:cb:b1:12:e0:55:77:
~省略~
                Exponent: 65537 (0x10001)
        Attributes:
        Requested Extensions:
            X509v3 Subject Alternative Name: 
                DNS:localhost, DNS:*.tomoyan.net
    Signature Algorithm: sha256WithRSAEncryption
         89:2e:52:e2:cd:cb:d5:77:6a:05:73:32:6d:67:bf:73:09:17:
~省略~

証明書作成の手前で追加設定ファイルを作成する。

$ sudo vi /etc/pki/mgcCA/san.ext
/etc/pki/mgcCA/san.ext
basicConstraints=CA:FALSE # CA証明書以外
nsCertType=server # サーバー証明書
nsComment="OpenSSL Generated Certificate"
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
subjectAltName=DNS:localhost,DNS:*.tomoyan.net

サーバー CSR(Certificate Signing Request) に認証局で署名する。

$ sudo openssl ca -config /etc/pki/mgcCA/openssl-mgc-server.cnf -keyfile /etc/pki/mgcCA/private/cakey.pem -in /etc/pki/mgcCA/serverreq.csr -out /etc/pki/mgcCA/servercert.crt -extfile /etc/pki/mgcCA/san.ext
Using configuration from /etc/pki/mgcCA/openssl-mgc-server.cnf
Enter pass phrase for /etc/pki/mgcCA/private/cakey.pem: # プライベート認証局のパスフレーズを入力
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 10 (0xa)
        Validity
            Not Before: Feb 16 11:33:35 2019 GMT
            Not After : Jan 23 11:33:35 2119 GMT
        Subject:
            countryName               = JP
            stateOrProvinceName       = Hokkaido Pref.
            organizationName          = Monster's Garage Co.,Ltd.
            organizationalUnitName    = -
            commonName                = localhost, *.tomoyan.net
            emailAddress              = domain-admin@tomoyan.net
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Cert Type: 
                SSL Server
            Netscape Comment: 
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier: 
                4B:2D:69:69:2E:6C:6B:9B:33:CE:68:52:87:CE:A9:B5:42:6E:C5:AA
            X509v3 Authority Key Identifier: 
                keyid:F1:11:89:F3:AC:9E:C5:F4:01:B9:1A:96:17:A8:67:2D:13:6D:80:03

            X509v3 Subject Alternative Name: 
                DNS:localhost, DNS:*.tomoyan.net
Certificate is to be certified until Jan 23 11:33:35 2119 GMT (36500 days)
Sign the certificate? [y/n]:y # y と Enter を入力


1 out of 1 certificate requests certified, commit? [y/n]y # y と Enter を入力
Write out database with 1 new entries
Data Base Updated

カレントディレクトリにサーバー証明書が作成される。

$ ll /etc/pki/mgcCA/
-rw-r--r-- 1 root root  4890  211 00:46 servercert.crt # サーバー証明書
$ sudo openssl x509 -in /etc/pki/mgcCA/servercert.crt -text -noout
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 10 (0xa)
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = JP, ST = Hokkaido Pref., L = Sapporo City, O = "Monster's Garage Co.,Ltd.", OU = -, CN = Monster's Garage CA, emailAddress = domain-admin@monsters-g.com
        Validity
            Not Before: Feb 16 11:33:35 2019 GMT
            Not After : Jan 23 11:33:35 2119 GMT
        Subject: C = JP, ST = Hokkaido Pref., O = "Monster's Garage Co.,Ltd.", OU = -, CN = "localhost, *.tomoyan.net", emailAddress = domain-admin@tomoyan.net
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:dc:a3:7e:df:9e:aa:17:f7:0e:a0:40:4c:24:f1:
                    91:4e:ce:7f:2b:da:91:78:f9:b4:67:10:fe:63:6f:
〜省略〜
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Cert Type: 
                SSL Server
            Netscape Comment: 
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier: 
                4B:2D:69:69:2E:6C:6B:9B:33:CE:68:52:87:CE:A9:B5:42:6E:C5:AA
            X509v3 Authority Key Identifier: 
                keyid:F1:11:89:F3:AC:9E:C5:F4:01:B9:1A:96:17:A8:67:2D:13:6D:80:03

            X509v3 Subject Alternative Name: 
                DNS:localhost, DNS:*.tomoyan.net
    Signature Algorithm: sha256WithRSAEncryption
         ba:ca:e4:01:53:cc:16:08:d7:81:cd:0e:86:ec:79:ce:0f:0d:
         16:e4:b4:f0:df:6b:a8:b1:1d:bf:a2:f7:41:89:d3:18:4a:eb:
〜省略〜

 秘密キーを Web サーバーなどで利用する際にパスフレーズを聞かれないようにするには、サーバー証明書の秘密キーのパスフレーズを除去しておく。

秘密キーのパスフレーズを除去する。

$ sudo openssl rsa -in /etc/pki/mgcCA/serverkey.pem -out /etc/pki/mgcCA/serverkey-nopwd.pem
Enter pass phrase for /etc/pki/mgcCA/serverkey.pem: # 秘密キーのパスフレーズを入力
writing RSA key

カレントディレクトリにパスフレーズを除去した秘密キーが作成される。

$ ll /etc/pki/mgcCA/
-rw------- 1 root root  1675  211 01:08 serverkey-nopwd.pem # 秘密鍵(パスフレーズなし)

必要に応じて作成したサーバー CSR、証明書、秘密鍵のファイルをわかりやすいように認証局(CA)の管理下のディレクトリにバックアップしておく。

$ sudo mv /etc/pki/mgcCA/serverreq.csr /etc/pki/mgcCA/certs/www.tomoyan.net.csr
$ sudo mv /etc/pki/mgcCA/servercert.crt /etc/pki/mgcCA/certs/www.tomoyan.net.crt
$ sudo mv /etc/pki/mgcCA/serverkey.pem /etc/pki/mgcCA/certs/www.tomoyan.net.pem
$ sudo mv /etc/pki/mgcCA/serverkey-nopwd.pem /etc/pki/mgcCA/certs/www.tomoyan.net-nopwd.pem
$ sudo mv /etc/pki/mgcCA/san.ext /etc/pki/mgcCA/certs/www.tomoyan.net_san.ext
ファイル 説明
clientkey.pem クライアント秘密鍵
clientreq.csr クライアント CSR
clientcert.crt クライアント証明書
tomoyan-client.p12 個人情報交換ファイル

 クライアント CSR は、パブリック認証局(Verisignなど)やプライベート認証局に対するクライアント証明書の署名要求である。
 認証局に署名して貰うことによって、クライアント証明書として利用できるようになる。

openssl-mgc-client.cnf(クライアント用設定ファイル)を編集する。

$ sudo vi /etc/pki/mgcCA/openssl-mgc-client.cnf
[ usr_cert ]
basicConstraints=CA:FALSE # CA証明書以外
nsCertType			= client, email, objsign # クライアント、電子メール、オブジェクトサイン証明書


クライアント CSR(Certificate Signing Request) を作成する。

$ sudo openssl req -new -config /etc/pki/mgcCA/openssl-mgc-client.cnf -keyout /etc/pki/mgcCA/clientkey.pem -out /etc/pki/mgcCA/clientreq.csr

注意: 標準では Country Name, State of Province Name, Organization name は署名する CA のものと同一でなければならない。

Generating a RSA private key
...+++++
........+++++
writing new private key to '/etc/pki/mgcCA/clientkey.pem'
Enter PEM pass phrase: # パスフレーズを入力
Verifying - Enter PEM pass phrase: # 確認用パスフレーズを入力
-----
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) [JP]: # Enter を入力
State or Province Name (full name) [Hokkaido Pref.]: # Enter を入力
Locality Name (eg, city) [Sapporo City]: # Enter を入力
Organization Name (eg, company) [Monsters Garage Co.,Ltd.]:Monster's Garage Co.,Ltd. # 会社名 or ドメイン名を入力
Organizational Unit Name (eg, section) [-]: # Enter を入力
Common Name (eg, your name or your server's hostname) []:TomoYan # 利用者名を入力
Email Address [domain-admin@monsters-g.com]:tomoyan@tomoyan.net # 利用者メールアドレスを入力

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: # Enter を入力
An optional company name []: # Enter を入力


CAのカレントディレクトリにクライアント秘密鍵とクライアント CSR(証明書署名要求)が作成される。

$ ll /etc/pki/mgcCA/
-rw------- 1 root root  1854  211 01:35 clientkey.pem # クライアント秘密鍵
-rw-r--r-- 1 root root  1086  211 01:42 clientreq.csr # クライアント CSR(証明書署名要求)

※クライアント CSR は認証局に渡して署名して貰うことで証明書として利用できるようになる。
 秘密鍵は証明書をクライアントで利用する際に必要になるので大事に保管しておくこと。


クライアント CSR の内容を確認する。

$ openssl req -in /etc/pki/mgcCA/clientreq.csr -text -noout
Certificate Request:
    Data:
        Version: 1 (0x0)
        Subject: C = JP, ST = Hokkaido Pref., L = Sapporo City, O = "Monster's Garage Co.,Ltd.", OU = -, CN = TomoYan, emailAddress = tomoyan@tomoyan.net
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:cf:38:92:c9:c1:7e:68:1d:27:64:d5:9c:94:a6:
                    98:eb:b5:90:4e:eb:ee:d4:5e:6f:5d:01:79:3b:57:
                    f9:96:33:94:30:46:f4:bc:b1:5b:50:95:a0:28:eb:
                    ee:0a:4a:aa:be:7d:b9:58:8f:e5:e5:c2:0e:58:6c:
                    ec:0e:21:a9:5d:1f:34:1f:d7:e1:0a:42:8c:a0:63:
                    4a:ee:fd:94:f3:36:d6:1f:bd:4b:43:82:45:a5:ea:
                    32:09:11:0c:48:cf:1c:1d:b6:e8:5b:99:d6:30:ce:
                    77:d6:b3:2f:0c:04:ec:1d:cc:1a:27:c1:ef:07:6e:
                    3f:f4:7d:0e:c3:33:a6:db:73:6c:34:32:df:6d:57:
                    f3:27:c8:43:c3:01:d3:62:60:66:c7:4e:99:86:a5:
                    9b:96:b3:53:75:b8:58:a7:d8:9c:b5:83:80:39:0a:
                    2e:4b:b8:91:ea:b3:d7:20:45:4d:77:61:9f:e4:6d:
                    46:c6:36:12:c7:e0:54:a2:fb:60:24:57:d5:a1:e3:
                    e4:83:92:6e:46:f6:1f:68:43:e5:29:93:be:5c:c9:
                    4a:16:c3:59:b3:96:3d:e8:aa:c6:fd:33:1f:54:7a:
                    14:8c:74:0f:32:c2:31:57:56:e7:76:c4:bc:e9:f1:
                    1c:93:99:88:6a:0b:46:53:e0:34:21:ad:37:58:80:
                    e3:39
                Exponent: 65537 (0x10001)
        Attributes:
            a0:00
    Signature Algorithm: sha256WithRSAEncryption
         7b:ba:9b:c7:e4:2a:ff:89:fa:36:49:68:aa:22:9e:f6:e1:9e:
~省略~

クライアント CSR(Certificate Signing Request) に認証局で署名する。

$ sudo openssl ca -config /etc/pki/mgcCA/openssl-mgc-client.cnf -keyfile /etc/pki/mgcCA/private/cakey.pem -in /etc/pki/mgcCA/clientreq.csr -out /etc/pki/mgcCA/clientcert.crt
Using configuration from /etc/pki/mgcCA/openssl-mgc-client.cnf
Enter pass phrase for /etc/pki/mgcCA/private/cakey.pem: # プライベート認証局のパスフレーズを入力
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 3 (0x3)
        Validity
            Not Before: Feb 10 17:03:11 2019 GMT
            Not After : Jan 17 17:03:11 2119 GMT
        Subject:
            countryName               = JP
            stateOrProvinceName       = Hokkaido Pref.
            organizationName          = Monster's Garage Co.,Ltd.
            organizationalUnitName    = -
            commonName                = TomoYan
            emailAddress              = tomoyan@tomoyan.net
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Cert Type: 
                SSL Client, S/MIME, Object Signing
            Netscape Comment: 
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier: 
                D8:60:5D:77:BF:C1:DA:DE:CC:94:00:0F:F8:29:5E:B0:58:3B:B3:1D
            X509v3 Authority Key Identifier: 
                keyid:75:0E:6F:10:D2:10:CF:F2:CF:6E:20:12:C7:AE:25:70:00:F0:CD:65

Certificate is to be certified until Jan 17 17:03:11 2119 GMT (36500 days)
Sign the certificate? [y/n]:y # y と Enter を入力


1 out of 1 certificate requests certified, commit? [y/n]y # y と Enter を入力
Write out database with 1 new entries
Data Base Updated

カレントディレクトリにクライアント証明書が作成される。

$ ll /etc/pki/mgcCA/
-rw-r--r-- 1 root root  4886  211 02:03 clientcert.crt # クライアント証明書
$ sudo openssl x509 -in /etc/pki/mgcCA/clientcert.crt -text -noout
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 2 (0x2)
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = JP, ST = Hokkaido Pref., L = Sapporo City, O = "Monster's Garage Co.,Ltd.", OU = -, CN = Monster's Garage CA, emailAddress = domain-admin@monsters-g.com
        Validity
            Not Before: Feb 11 11:49:24 2019 GMT
            Not After : Jan 18 11:49:24 2119 GMT
        Subject: C = JP, ST = Hokkaido Pref., O = "Monster's Garage Co.,Ltd.", OU = -, CN = TomoYan, emailAddress = tomoyan@tomoyan.net
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:a9:41:68:6e:14:15:71:5f:87:ee:8b:1d:07:f1:
                    3b:64:64:e7:35:2f:93:4d:fe:05:1c:03:2a:1a:e5:
〜省略〜
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Cert Type: 
                SSL Client, S/MIME, Object Signing
            Netscape Comment: 
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier: 
                8A:DC:B8:F5:6D:E7:16:69:3B:0A:C7:4B:9D:BE:2D:4D:7C:F5:14:79
            X509v3 Authority Key Identifier: 
                keyid:F1:11:89:F3:AC:9E:C5:F4:01:B9:1A:96:17:A8:67:2D:13:6D:80:03

    Signature Algorithm: sha256WithRSAEncryption
         1c:d2:61:ab:26:74:cf:9f:8d:96:28:ff:6d:22:4b:33:00:46:
         e8:09:c1:75:07:a2:ec:aa:a9:31:6d:1d:63:80:da:26:87:01:
〜省略〜

PKCS #12 は Personal Information Exchange Syntax Standard という規格で定義された個人情報交換ファイルです。
クライアントでは、証明書と秘密鍵を1つのファイルにまとめた PKCS#12 フォーマットが主に用いられます。
ここでは、クライアント証明書、秘密鍵から PKCS#12 フォーマットの p12 ファイルを作成する。

$ sudo openssl pkcs12 -export -in /etc/pki/mgcCA/clientcert.crt -inkey /etc/pki/mgcCA/clientkey.pem -out /etc/pki/mgcCA/tomoyan-client.p12 -name "TomoYan PKCS#12"
Enter pass phrase for /etc/pki/mgcCA/clientkey.pem: # クライアント秘密鍵のパスフレーズ
Enter Export Password: # p12 ファイルを読み込むためのパスフレーズを入力
Verifying - Enter Export Password: # 確認用パスフレーズを入力

CAのカレントディレクトリに PKCS#12 フォーマットのファイルが作成される。

$ ll /etc/pki/mgcCA/
-rw------- 1 root root  2804  2月 11 07:48 tomoyan-client.p12 # 個人情報交換ファイル

必要に応じて作成したクライアント CSR、証明書、秘密鍵、PKCS#12 個人情報交換ファイルをわかりやすいように認証局(CA)の管理下のディレクトリにバックアップしておく。

$ sudo mkdir /etc/pki/mgcCA/client/{certs,private}
$ sudo mv /etc/pki/mgcCA/clientreq.csr /etc/pki/mgcCA/client/certs/tomoyan.csr
$ sudo mv /etc/pki/mgcCA/clientcert.crt /etc/pki/mgcCA/client/certs/tomoyan.crt
$ sudo mv /etc/pki/mgcCA/clientkey.pem /etc/pki/mgcCA/client/private/tomoyan.pem
$ sudo mv /etc/pki/mgcCA/tomoyan-client.p12 /etc/pki/mgcCA/client/private/tomoyan.p12

openssl ca のバグである可能性が高いが、-config-keyfile は分かっているはずなのに -keyfile オプションを省略すると、ファイル名: '-out'fopen しようとする。
-out オプションをファイル名と勘違いしているので仕様では無いはずである。

140354393380672:error:02001002:system library:fopen:No such file or directory:crypto/bio/bss_file.c:72:fopen('-out','r')
140354393380672:error:2006D080:BIO routines:BIO_new_file:no such file:crypto/bio/bss_file.c:79:

以下の様にきちんと -keyfile オプションで CA の秘密鍵を指定するとエラーを回避できる。

$ sudo openssl ca -config /etc/pki/mgcCA/openssl-mgc-server.cnf -keyfile /etc/pki/mgcCA/private/cakey.pem -in /etc/pki/mgcCA/serverreq.csr -out /etc/pki/mgcCA/servercert.crt

Chrome 58 以降では、Common Name を評価しなくなったようである。
X509v3 Subject Alternative Name(SAN): DNS: で判定するようである。
CSR を作成する際に openssl.cnf の [ req ] → req_extensions = v3_req → [ v3_req ] → subjectAltName = @alt_names → [ alt_names ] → DNS.1, DNS.2 … を指定する必要があるが、CSR を作成するたびに openssl.cnf を修正するのは面倒である。
OpenSSL Version 1.1.1 より CSR 作成時のコマンド openssl req-addext が指定出来るようになった。

$ sudo openssl req -new -config /etc/pki/mgcCA/openssl-mgc-server.cnf \
-addext 'subjectAltName=DNS:localhost,DNS:*.tomoyan.net' \
-keyout /etc/pki/mgcCA/serverkey.pem -out /etc/pki/mgcCA/serverreq.csr
$ openssl req -in /etc/pki/mgcCA/serverreq.csr -text -noout
Certificate Request:
    Data:
        Version: 1 (0x0)
        Subject: C = JP, ST = Hokkaido Pref., L = Sapporo City, O = "Monster's Garage Co.,Ltd.", OU = -, CN = tomoyan.net, emailAddress = domain-admin@monsters-g.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:ad:8b:53:f7:40:38:70:8b:cb:b1:12:e0:55:77:
〜省略〜
                Exponent: 65537 (0x10001)
        Attributes:
        Requested Extensions:
            X509v3 Subject Alternative Name: 
                DNS:localhost, DNS:*.tomoyan.net
    Signature Algorithm: sha256WithRSAEncryption
         89:2e:52:e2:cd:cb:d5:77:6a:05:73:32:6d:67:bf:73:09:17:
〜省略〜
        Requested Extensions:
            X509v3 Subject Alternative Name: 
                DNS:localhost, DNS:*.tomoyan.net

X509v3 Subject Alternative Name: DNS: が指定出来ている。

ERROR:There is already a certificate for /C=JP/ST=Hokkaido Pref./O=Monster's Garage Co.,Ltd./OU=-/CN=localhost, *.tomoyan.net/emailAddress=domain-admin@monsters-g.com
The matching entry has the following details
Type          :Valid
Expires on    :21190123110413Z
Serial Number :09
File name     :unknown
Subject Name  :/C=JP/ST=Hokkaido Pref./O=Monster's Garage Co.,Ltd./OU=-/CN=localhost, *.tomoyan.net/emailAddress=domain-admin@monsters-g.com

初期設定では重複して登録できないので revoke 証明書の失効をする。

$ sudo openssl ca -config /etc/pki/mgcCA/openssl-mgc-ca.cnf -revoke /etc/pki/mgcCA/newcerts/09.pem 
Using configuration from /etc/pki/mgcCA/openssl-mgc-ca.cnf
Enter pass phrase for /etc/pki/mgcCA/private/cakey.pem: # パスフレーズを入力
Revoking Certificate 09.
Data Base Updated

利用可能なコマンド一覧

$ openssl version --options ...

OpenSSL 3.0.8 7 Feb 2023 (Library: OpenSSL 3.0.8 7 Feb 2023)

標準コマンド、メッセージ ダイジェスト コマンド(非推奨)、暗号化コマンド(非推奨)の一覧。

$ openssl list {-standard-commands,-digest-commands,-cipher-commands}

asn1parse         ca                ciphers           cmp               
cms               crl               crl2pkcs7         dgst              
dhparam           dsa               dsaparam          ec                
ecparam           enc               engine            errstr            
fipsinstall       gendsa            genpkey           genrsa            
help              info              kdf               list              
mac               nseq              ocsp              passwd            
pkcs12            pkcs7             pkcs8             pkey              
pkeyparam         pkeyutl           prime             rand              
rehash            req               rsa               rsautl            
s_client          s_server          s_time            sess_id           
smime             speed             spkac             srp               
storeutl          ts                verify            version           
x509              

blake2b512        blake2s256        md5               rmd160            
sha1              sha224            sha256            sha3-224          
sha3-256          sha3-384          sha3-512          sha384            
sha512            sha512-224        sha512-256        shake128          
shake256          sm3               

aes-128-cbc       aes-128-ecb       aes-192-cbc       aes-192-ecb       
aes-256-cbc       aes-256-ecb       aria-128-cbc      aria-128-cfb      
aria-128-cfb1     aria-128-cfb8     aria-128-ctr      aria-128-ecb      
aria-128-ofb      aria-192-cbc      aria-192-cfb      aria-192-cfb1     
aria-192-cfb8     aria-192-ctr      aria-192-ecb      aria-192-ofb      
aria-256-cbc      aria-256-cfb      aria-256-cfb1     aria-256-cfb8     
aria-256-ctr      aria-256-ecb      aria-256-ofb      camellia-128-cbc  
camellia-128-ecb  camellia-192-cbc  camellia-192-ecb  camellia-256-cbc  
camellia-256-ecb  des-ede           des-ede-cbc       des-ede-cfb       
des-ede-ofb       des-ede3          des-ede3-cbc      des-ede3-cfb      
des-ede3-ofb      des3              

暗号スイートの説明の一覧表示。

$ openssl ciphers -v

TLS_AES_256_GCM_SHA384         TLSv1.3 Kx=any      Au=any   Enc=AESGCM(256)            Mac=AEAD
TLS_CHACHA20_POLY1305_SHA256   TLSv1.3 Kx=any      Au=any   Enc=CHACHA20/POLY1305(256) Mac=AEAD
TLS_AES_128_GCM_SHA256         TLSv1.3 Kx=any      Au=any   Enc=AESGCM(128)            Mac=AEAD
TLS_AES_128_CCM_SHA256         TLSv1.3 Kx=any      Au=any   Enc=AESCCM(128)            Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384  TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESGCM(256)            Mac=AEAD
ECDHE-RSA-AES256-GCM-SHA384    TLSv1.2 Kx=ECDH     Au=RSA   Enc=AESGCM(256)            Mac=AEAD
ECDHE-ECDSA-CHACHA20-POLY1305  TLSv1.2 Kx=ECDH     Au=ECDSA Enc=CHACHA20/POLY1305(256) Mac=AEAD
ECDHE-RSA-CHACHA20-POLY1305    TLSv1.2 Kx=ECDH     Au=RSA   Enc=CHACHA20/POLY1305(256) Mac=AEAD
ECDHE-ECDSA-AES256-CCM         TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESCCM(256)            Mac=AEAD
ECDHE-ECDSA-AES128-GCM-SHA256  TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESGCM(128)            Mac=AEAD
ECDHE-RSA-AES128-GCM-SHA256    TLSv1.2 Kx=ECDH     Au=RSA   Enc=AESGCM(128)            Mac=AEAD
ECDHE-ECDSA-AES128-CCM         TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESCCM(128)            Mac=AEAD
ECDHE-ECDSA-AES128-SHA256      TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AES(128)               Mac=SHA256
ECDHE-RSA-AES128-SHA256        TLSv1.2 Kx=ECDH     Au=RSA   Enc=AES(128)               Mac=SHA256
ECDHE-ECDSA-AES256-SHA         TLSv1   Kx=ECDH     Au=ECDSA Enc=AES(256)               Mac=SHA1
ECDHE-RSA-AES256-SHA           TLSv1   Kx=ECDH     Au=RSA   Enc=AES(256)               Mac=SHA1
ECDHE-ECDSA-AES128-SHA         TLSv1   Kx=ECDH     Au=ECDSA Enc=AES(128)               Mac=SHA1
ECDHE-RSA-AES128-SHA           TLSv1   Kx=ECDH     Au=RSA   Enc=AES(128)               Mac=SHA1
AES256-GCM-SHA384              TLSv1.2 Kx=RSA      Au=RSA   Enc=AESGCM(256)            Mac=AEAD
AES256-CCM                     TLSv1.2 Kx=RSA      Au=RSA   Enc=AESCCM(256)            Mac=AEAD
AES128-GCM-SHA256              TLSv1.2 Kx=RSA      Au=RSA   Enc=AESGCM(128)            Mac=AEAD
AES128-CCM                     TLSv1.2 Kx=RSA      Au=RSA   Enc=AESCCM(128)            Mac=AEAD
AES256-SHA256                  TLSv1.2 Kx=RSA      Au=RSA   Enc=AES(256)               Mac=SHA256
AES128-SHA256                  TLSv1.2 Kx=RSA      Au=RSA   Enc=AES(128)               Mac=SHA256
AES256-SHA                     SSLv3   Kx=RSA      Au=RSA   Enc=AES(256)               Mac=SHA1
AES128-SHA                     SSLv3   Kx=RSA      Au=RSA   Enc=AES(128)               Mac=SHA1
DHE-RSA-AES256-GCM-SHA384      TLSv1.2 Kx=DH       Au=RSA   Enc=AESGCM(256)            Mac=AEAD
DHE-RSA-CHACHA20-POLY1305      TLSv1.2 Kx=DH       Au=RSA   Enc=CHACHA20/POLY1305(256) Mac=AEAD
DHE-RSA-AES256-CCM             TLSv1.2 Kx=DH       Au=RSA   Enc=AESCCM(256)            Mac=AEAD
DHE-RSA-AES128-GCM-SHA256      TLSv1.2 Kx=DH       Au=RSA   Enc=AESGCM(128)            Mac=AEAD
DHE-RSA-AES128-CCM             TLSv1.2 Kx=DH       Au=RSA   Enc=AESCCM(128)            Mac=AEAD
DHE-RSA-AES256-SHA256          TLSv1.2 Kx=DH       Au=RSA   Enc=AES(256)               Mac=SHA256
DHE-RSA-AES128-SHA256          TLSv1.2 Kx=DH       Au=RSA   Enc=AES(128)               Mac=SHA256
DHE-RSA-AES256-SHA             SSLv3   Kx=DH       Au=RSA   Enc=AES(256)               Mac=SHA1
DHE-RSA-AES128-SHA             SSLv3   Kx=DH       Au=RSA   Enc=AES(128)               Mac=SHA1
PSK-AES256-GCM-SHA384          TLSv1.2 Kx=PSK      Au=PSK   Enc=AESGCM(256)            Mac=AEAD
PSK-CHACHA20-POLY1305          TLSv1.2 Kx=PSK      Au=PSK   Enc=CHACHA20/POLY1305(256) Mac=AEAD
PSK-AES256-CCM                 TLSv1.2 Kx=PSK      Au=PSK   Enc=AESCCM(256)            Mac=AEAD
PSK-AES128-GCM-SHA256          TLSv1.2 Kx=PSK      Au=PSK   Enc=AESGCM(128)            Mac=AEAD
PSK-AES128-CCM                 TLSv1.2 Kx=PSK      Au=PSK   Enc=AESCCM(128)            Mac=AEAD
PSK-AES256-CBC-SHA             SSLv3   Kx=PSK      Au=PSK   Enc=AES(256)               Mac=SHA1
PSK-AES128-CBC-SHA256          TLSv1   Kx=PSK      Au=PSK   Enc=AES(128)               Mac=SHA256
PSK-AES128-CBC-SHA             SSLv3   Kx=PSK      Au=PSK   Enc=AES(128)               Mac=SHA1
DHE-PSK-AES256-GCM-SHA384      TLSv1.2 Kx=DHEPSK   Au=PSK   Enc=AESGCM(256)            Mac=AEAD
DHE-PSK-CHACHA20-POLY1305      TLSv1.2 Kx=DHEPSK   Au=PSK   Enc=CHACHA20/POLY1305(256) Mac=AEAD
DHE-PSK-AES256-CCM             TLSv1.2 Kx=DHEPSK   Au=PSK   Enc=AESCCM(256)            Mac=AEAD
DHE-PSK-AES128-GCM-SHA256      TLSv1.2 Kx=DHEPSK   Au=PSK   Enc=AESGCM(128)            Mac=AEAD
DHE-PSK-AES128-CCM             TLSv1.2 Kx=DHEPSK   Au=PSK   Enc=AESCCM(128)            Mac=AEAD
DHE-PSK-AES256-CBC-SHA         SSLv3   Kx=DHEPSK   Au=PSK   Enc=AES(256)               Mac=SHA1
DHE-PSK-AES128-CBC-SHA256      TLSv1   Kx=DHEPSK   Au=PSK   Enc=AES(128)               Mac=SHA256
DHE-PSK-AES128-CBC-SHA         SSLv3   Kx=DHEPSK   Au=PSK   Enc=AES(128)               Mac=SHA1
ECDHE-PSK-CHACHA20-POLY1305    TLSv1.2 Kx=ECDHEPSK Au=PSK   Enc=CHACHA20/POLY1305(256) Mac=AEAD
ECDHE-PSK-AES256-CBC-SHA       TLSv1   Kx=ECDHEPSK Au=PSK   Enc=AES(256)               Mac=SHA1
ECDHE-PSK-AES128-CBC-SHA256    TLSv1   Kx=ECDHEPSK Au=PSK   Enc=AES(128)               Mac=SHA256
ECDHE-PSK-AES128-CBC-SHA       TLSv1   Kx=ECDHEPSK Au=PSK   Enc=AES(128)               Mac=SHA1
RSA-PSK-AES256-GCM-SHA384      TLSv1.2 Kx=RSAPSK   Au=RSA   Enc=AESGCM(256)            Mac=AEAD
RSA-PSK-CHACHA20-POLY1305      TLSv1.2 Kx=RSAPSK   Au=RSA   Enc=CHACHA20/POLY1305(256) Mac=AEAD
RSA-PSK-AES128-GCM-SHA256      TLSv1.2 Kx=RSAPSK   Au=RSA   Enc=AESGCM(128)            Mac=AEAD
RSA-PSK-AES256-CBC-SHA         SSLv3   Kx=RSAPSK   Au=RSA   Enc=AES(256)               Mac=SHA1
RSA-PSK-AES128-CBC-SHA256      TLSv1   Kx=RSAPSK   Au=RSA   Enc=AES(128)               Mac=SHA256
RSA-PSK-AES128-CBC-SHA         SSLv3   Kx=RSAPSK   Au=RSA   Enc=AES(128)               Mac=SHA1

  • linux/openssl_private_ca.txt
  • 最終更新: 2023/05/15 11:05
  • by ともやん