有効期限が100年のCA証明書/サーバー証明書/クライアント証明書の作成方法(easy-rsa3)

# 1. はじめに

- easy-rsa3を利用して有効期限が100年のCA証明書/サーバー証明書/クライアント証明書およびCRLを作成する。
- easy-rsa3のコマンドの出力結果はとても丁寧だが、それまで載せると記事として読みづらくなるので、コマンドだけ列挙。
- こうやって作成した証明書は、例えばIBM CloudのSecrets Managerに登録して、Client-to-Server VPNなどで利用することが可能である（詳細は[こちら](https://qiita.com/takason/items/3d04e4e31daae4def1d7)などを参考）

# 2. CA証明書/サーバー証明書/クライアント証明書の作成

```txt:easy-rsaのダウンロード
syasuda@MacBook ~ % git clone https://github.com/OpenVPN/easy-rsa.git
syasuda@MacBook ~ % cd easy-rsa/easyrsa3
```
```txt:環境変数ファイルの作成と編集
syasuda@MacBook easyrsa3 % cp -p vars.example vars
syasuda@MacBook easyrsa3 % echo set_var EASYRSA_CA_EXPIRE 36500 >> vars
syasuda@MacBook easyrsa3 % echo set_var EASYRSA_CERT_EXPIRE 36500 >> vars
syasuda@MacBook easyrsa3 % echo set_var EASYRSA_CRL_DAYS 36500 >> vars
syasuda@MacBook easyrsa3 % cat vars | grep -v "^#" | grep -v "^$"
if [ -z "$EASYRSA_CALLER" ]; then
	echo "You appear to be sourcing an Easy-RSA *vars* file. This is" >&2
	echo "no longer necessary and is disallowed. See the section called" >&2
	echo "*How to use this file* near the top comments for more details." >&2
	return 1
fi
set_var EASYRSA_CA_EXPIRE 36500
set_var EASYRSA_CERT_EXPIRE 36500
set_var EASYRSA_CRL_DAYS 36500
```

```txt:PKI 環境を初期化
syasuda@MacBook easyrsa3 % ./easyrsa init-pki
```
```txt:CA証明書、秘密鍵の作成（途中、Common Nameを指定する必要がある。ここでは vpn-ca と入力）
syasuda@MacBook easyrsa3 % ./easyrsa build-ca nopass
```
```txt:サーバー証明書、秘密鍵の作成（途中、確認メッセージで yes と入力）
syasuda@MacBook easyrsa3 % ./easyrsa build-server-full vpn-server nopass
```
```txt:クライアント証明書、秘密鍵の作成（途中、確認メッセージで yes と入力）
syasuda@MacBook easyrsa3 % ./easyrsa build-client-full syasuda1 nopass
```

# 3. 証明書および秘密鍵の出力先の確認

```
syasuda@MacBook easyrsa3 % find . -type f -name "*.crt" -or -name "*.key"
./pki/ca.crt
./pki/issued/vpn-server.crt
./pki/issued/syasuda1.crt
./pki/private/syasuda1.key
./pki/private/vpn-server.key
./pki/private/ca.key
```

# 4. 証明書の属性確認


```txt:CA証明書
syasuda@MacBook easyrsa3 % openssl x509 -text -in ./pki/ca.crt | grep -e "Issuer:" -e "Not Before:" -e "Not After :" -e "Subject:" -e "Public-Key:" -e "TLS Web"
        Issuer: CN=vpn-ca
            Not Before: Feb 15 13:17:21 2024 GMT
            Not After : Jan 22 13:17:21 2124 GMT
        Subject: CN=vpn-ca
                RSA Public-Key: (2048 bit)
```
```txt:サーバー証明書
syasuda@MacBook easyrsa3 % openssl x509 -text -in ./pki/issued/vpn-server.crt | grep -e "Issuer:" -e "Not Before:" -e "Not After :" -e "Subject:" -e "Public-Key:" -e "TLS Web"
        Issuer: CN=vpn-ca
            Not Before: Feb 15 13:17:40 2024 GMT
            Not After : Jan 22 13:17:40 2124 GMT
        Subject: CN=vpn-server
                RSA Public-Key: (2048 bit)
                TLS Web Server Authentication
```
```txt:クライアント証明書
syasuda@MacBook easyrsa3 % openssl x509 -text -in ./pki/issued/syasuda1.crt | grep -e "Issuer:" -e "Not Before:" -e "Not After :" -e "Subject:" -e "Public-Key:" -e "TLS Web"
        Issuer: CN=vpn-ca
            Not Before: Feb 15 13:18:01 2024 GMT
            Not After : Jan 22 13:18:01 2124 GMT
        Subject: CN=syasuda1
                RSA Public-Key: (2048 bit)
                TLS Web Client Authentication
```

easy-rsaには証明書を表示するためのコマンドが提供されているため、こちらで確認しても良い。

```txt:CA証明書
syasuda@MacBook easyrsa3 % ./easyrsa show-ca
Using Easy-RSA 'vars' configuration:
* /Users/syasuda/easy-rsa/easyrsa3/vars

Notice
------
Showing details for CA certificate, at:
* /Users/syasuda/easy-rsa/easyrsa3/pki/ca.crt


Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            c7:43:90:ba:a8:0d:95:64
    Signature Algorithm: sha256WithRSAEncryption
        Issuer:
            commonName                = vpn-ca
        Validity
            Not Before: Feb 15 13:17:21 2024 GMT
            Not After : Jan 22 13:17:21 2124 GMT
        Subject:
            commonName                = vpn-ca
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                70:A4:D2:D0:8F:A8:EB:3D:9F:A5:F8:B2:37:E9:0C:03:D3:2A:E7:23
            X509v3 Authority Key Identifier:
                keyid:70:A4:D2:D0:8F:A8:EB:3D:9F:A5:F8:B2:37:E9:0C:03:D3:2A:E7:23
                DirName:/CN=vpn-ca
                serial:C7:43:90:BA:A8:0D:95:64

            X509v3 Basic Constraints:
                CA:TRUE
            X509v3 Key Usage:
                Certificate Sign, CRL Sign
```
```txt:サーバー証明書
syasuda@MacBook easyrsa3 % ./easyrsa show-cert vpn-server
Using Easy-RSA 'vars' configuration:
* /Users/syasuda/easy-rsa/easyrsa3/vars

Notice
------
Showing 'cert' details for: 'vpn-server'

This file is stored at:
* /Users/syasuda/easy-rsa/easyrsa3/pki/issued/vpn-server.crt


Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            38:87:63:b2:ca:9b:8a:f8:04:67:11:eb:e3:cf:4f:74
    Signature Algorithm: sha256WithRSAEncryption
        Issuer:
            commonName                = vpn-ca
        Validity
            Not Before: Feb 15 13:17:40 2024 GMT
            Not After : Jan 22 13:17:40 2124 GMT
        Subject:
            commonName                = vpn-server
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            X509v3 Subject Key Identifier:
                79:08:7D:03:30:DC:03:4A:37:38:11:5F:A1:71:EE:D0:70:15:94:8B
            X509v3 Authority Key Identifier:
                keyid:70:A4:D2:D0:8F:A8:EB:3D:9F:A5:F8:B2:37:E9:0C:03:D3:2A:E7:23
                DirName:/CN=vpn-ca
                serial:C7:43:90:BA:A8:0D:95:64

            X509v3 Extended Key Usage:
                TLS Web Server Authentication
            X509v3 Key Usage:
                Digital Signature, Key Encipherment
            X509v3 Subject Alternative Name:
                DNS:vpn-server
```
```txt:クライアント証明書
syasuda@MacBook easyrsa3 % ./easyrsa show-cert syasuda1
Using Easy-RSA 'vars' configuration:
* /Users/syasuda/easy-rsa/easyrsa3/vars

Notice
------
Showing 'cert' details for: 'syasuda1'

This file is stored at:
* /Users/syasuda/easy-rsa/easyrsa3/pki/issued/syasuda1.crt


Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            f4:cf:4e:ae:e9:14:4d:61:90:1f:35:83:7f:67:9a:c8
    Signature Algorithm: sha256WithRSAEncryption
        Issuer:
            commonName                = vpn-ca
        Validity
            Not Before: Feb 15 13:18:01 2024 GMT
            Not After : Jan 22 13:18:01 2124 GMT
        Subject:
            commonName                = syasuda1
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            X509v3 Subject Key Identifier:
                A6:84:0B:82:02:8C:71:3C:6C:B7:CE:48:DB:1A:5E:E5:CF:DF:5E:51
            X509v3 Authority Key Identifier:
                keyid:70:A4:D2:D0:8F:A8:EB:3D:9F:A5:F8:B2:37:E9:0C:03:D3:2A:E7:23
                DirName:/CN=vpn-ca
                serial:C7:43:90:BA:A8:0D:95:64

            X509v3 Extended Key Usage:
                TLS Web Client Authentication
            X509v3 Key Usage:
                Digital Signature
```




:::note 
`TLS Web Client Authentication`や`TLS Web Server Authentication`は、X509v3拡張属性である。

[この記事](https://security.stackexchange.com/questions/100768/difference-between-certificates-with-extension-fields-and-non-repudiation-us)によると、間違ってクライアント証明書がサーバー証明書として使われてしまったり、逆にサーバー証明書がクライアント証明書として使われてしまうのを避けるために使われているらしい。

以前、`./easyrsa build-server-full syasuda1 nopass`のようにクライアント証明書を作成するのにサーバー証明書を生成するオプションを指定してしまった際には、証明書に`TLS Web Server Authentication`が付与されていた。結果、この証明書を使ってIBM CloudのVPN for VPC(Client to Site型）でクライアント認証をしようとすると、以下のような`TLS Error: TLS key negotiation failed to occur within 60 seconds (check your network connectivity)`というエラーで接続できなかったという経験がある。

IBM Cloud docsには[このエラー発生時の解決方法を紹介するページ](https://cloud.ibm.com/docs/vpc?topic=vpc-troubleshoot-vpn-client-hangs&locale=en)が存在するが、Security GroupやNetwork ACL以外などのファイアーウォール構成が影響している場合だけでなく、そもそも証明書の属性が正しくないといった基本的なミスでもこのエラーは発生しうる。よって、証明書確認の際には有効期限などの基本的な情報に加えて、X509v3拡張属性まで確認することが望ましい。
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/dde23f8f-9957-7806-e1eb-03d269982a76.png)