apache2で自己署名証明書ではないTLSv1.2通信環境を構築する

# 概要
* 前記事「[自己CAを構築し、自己CAで署名付けした中間証明書とサーバ証明書を作成する](https://qiita.com/thetsuthetsu/items/5292aab4ba5f61ce11ca)」により、自己署名ではない中間証明書、サーバ証明書が作成できるようになった。
* apache2に作成した証明書をインストールし、自己署名エラー(openssl: self signed certificate)が出ないTLSv1.2通信環境を構築する
* クライアント別(openssl, chrome, IE)にTLSアクセスを比較してみる。openssl, IEでは正常にTLSアクセスできたが、chromeではSAN未設定のためERR_CERT_COMMON_NAME_INVALIDが発生。

# 環境
* OS

```
# uname -a
Linux vUbuntuLTS 5.3.0-40-generic #32~18.04.1-Ubuntu SMP Mon Feb 3 14:05:59 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
```

* apache2インストール・ssl設定

```
$ sudo apt install apache2
$ sudo a2enmod ssl
$ sudo a2ensite default-ssl
```

# 既定のssl設定にアクセスしてみる
* openssl s_clientで接続する 
* 自己署名サーバ証明書のためverify error(num=18:self signed certificate)が発生

```
$ openssl s_client -connect 192.168.56.101:443
CONNECTED(00000004)
Can't use SSL_get_servername
depth=0 CN = Ubuntu.VirtualBox
verify error:num=18:self signed certificate
verify return:1
depth=0 CN = Ubuntu.VirtualBox
verify return:1
---
Certificate chain
 0 s:CN = Ubuntu.VirtualBox
   i:CN = Ubuntu.VirtualBox
---
Server certificate

    ...snip...

```

# 自己署名ではない証明書を設定
## 自己CAで作成した自己署名でない証明書をapache2に設定する。
1. 秘密キーを/etc/ssl/privateに配置

    ```
    # cd /etc/ssl/private
    # cp /home/tetsuo/self_ca/server/server_key.pem .
    # mv server_key.pem www_vubuntults_mydomain_key.pem
    # chown root:ssl-cert www_vubuntults_mydomain_key.pem 
    # chmod 640 www_vubuntults_mydomain_key.pem 
    ```

2. サーバ証明書、中間証明書を/etc/ssl/certsに配置

    ```
    # cp /home/tetsuo/self_ca/server/www_vubuntults_mydomain.crt .
    # cp /home/tetsuo/self_ca/ICA/demoCA/cacert.pem ica.vubuntults_mydomain.pem
    ```

3. /etc/apache2/sites-available/default-ssl.confを以下のように修正

    ```
    #SSLCertificateFile     /etc/ssl/certs/ssl-cert-snakeoil.pem
    SSLCertificateFile      /etc/ssl/certs/www_vubuntults_mydomain.crt
    #SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
    SSLCertificateKeyFile /etc/ssl/private/www_vubuntults_mydomain_key.pem

    #SSLCertificateChainFile /etc/apache2/ssl.crt/server-ca.crt
    SSLCertificateChainFile /etc/ssl/certs/ica.vubuntults_mydomain.pem
    ```
4. apache2を再起動

    ```
    # systemctl restart apache2
    ```

# クライアントからのTLSアクセスを試す
## opensslでアクセス
* openssl s_clientで接続する
* ホスト名は、サーバ証明書のx.509:CNに一致させる(DNS, /etc/hostsを調整する)
* ルート証明書(pem形式)を-CAfileに指定
* verify errorが出ていないか注意する

```
$ openssl s_client -connect www.vubuntults.mydomain:443 -CAfile rca_vubuntults_mydomain.pem
CONNECTED(00000004)
depth=2 C = JP, ST = Tokyo, O = my, OU = room, CN = rca.vubuntults.mydomain
verify return:1
depth=1 C = JP, ST = Tokyo, L = Shinjuku-ku, O = my, OU = room, CN = ica.vubuntults.mydomain
verify return:1
depth=0 C = JP, ST = Tokyo, O = my, OU = room, CN = www.vubuntults.mydomain
verify return:1
---
Certificate chain
 0 s:C = JP, ST = Tokyo, O = my, OU = room, CN = www.vubuntults.mydomain
   i:C = JP, ST = Tokyo, L = Shinjuku-ku, O = my, OU = room, CN = ica.vubuntults.mydomain
 1 s:C = JP, ST = Tokyo, L = Shinjuku-ku, O = my, OU = room, CN = ica.vubuntults.mydomain
   i:C = JP, ST = Tokyo, O = my, OU = room, CN = rca.vubuntults.mydomain
---
Server certificate
-----BEGIN CERTIFICATE-----
MIID1TCCAr2gAwIBAgIUGeepvmUepZNrv0CB4Qvd0gtG4EkwDQYJKoZIhvcNAQEL
BQAwcTELMAkGA1UEBhMCSlAxDjAMBgNVBAgMBVRva3lvMRQwEgYDVQQHDAtTaGlu
anVrdS1rdTELMAkGA1UECgwCbXkxDTALBgNVBAsMBHJvb20xIDAeBgNVBAMMF2lj
YS52dWJ1bnR1bHRzLm15ZG9tYWluMB4XDTIwMDIxODA5MjgzM1oXDTIzMDIxNzA5
MjgzM1owWzELMAkGA1UEBhMCSlAxDjAMBgNVBAgMBVRva3lvMQswCQYDVQQKDAJt
eTENMAsGA1UECwwEcm9vbTEgMB4GA1UEAwwXd3d3LnZ1YnVudHVsdHMubXlkb21h
aW4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDyreaskyQDuGYHjp6n
OaVF/mR+JGzQF6jxgRXYsXQcb+3ZPzrN9tbMDKtxEYhYK3GSGLatX4xrsYPNg9ET
uqhIPW1ANydHef66LsItl/g/gZdMBaFZwI9ketWrIWsJ2Gat4h7BLRwLbWB7hrBB
fHAZrONUBar21SUk3aXYKP2ILgb2zbNeYWQ851X535E3L3Gjhs3wNniKdr+N/ln6
oNTRQdWyeFOac8spkVu6l2+m0ZWjLrOCB2BpbdOzu1wlchgNlnboOJ9dW+LYvh6B
e2h86dl9GXZ6D4ysEK9IZtN4Sgq2sNWiyYG0hE4K04CYW6AdOiI+mQyhX7rB7SR/
MDHFAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wg
R2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBQn1ZFrXlBDtR46dPPQ8IRS
n+JzrTAfBgNVHSMEGDAWgBTRi097/hT6q5KAPNRj5fKpZ8rrMTANBgkqhkiG9w0B
AQsFAAOCAQEAarv5Kxqe3CwIgQ1WRDhB3QFTzRR0o7lDPJ+S3EEcu2JQtL5hYe5b
IEgeEfT93cacL7XU0a+dIr4/884zPJj+2lsbHuHt8897q6E2zROCXKIFhuXcDDZX
0rgYWZKLNknugpX1vyYm+nRsRmjsYuVWN4E6r2jWaaiHsOeVb/gxYvWXV5Mu7jen
zaG/Cyz0gKEn3HoanC3DCm8zJCQ16PjZDk4/0+9bqoDYYI3tGMBq4BwGjclk9zGA
isYFT6cmY2PfbvSOqxQtJhaJKdZ1SgixwyFnqzfWLWDpoS6gjbNa24Ljf+wYRwlV
WkUhM752n1ueqac2UurEL3JdbmVIJC0NQQ==
-----END CERTIFICATE-----
subject=C = JP, ST = Tokyo, O = my, OU = room, CN = www.vubuntults.mydomain

issuer=C = JP, ST = Tokyo, L = Shinjuku-ku, O = my, OU = room, CN = ica.vubuntults.mydomain

---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 2590 bytes and written 428 bytes
Verification: OK
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: B16EB46264398E0296DA12D7B970560ABE93791DD222031A6ECF3074AE240E41
    Session-ID-ctx:
    Master-Key: B269C531451087789659519936FDD22A482D6FDE4580EE20220470A63030D200695F43BD3F4EEDF06B377FBD65669AB8
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 300 (seconds)
    TLS session ticket:
    0000 - 4a 57 1a 1f 93 eb ce 7d-a3 57 7a 3d 0f 6d e2 a9   JW.....}.Wz=.m..
    0010 - 69 da d5 8a 6a 53 b4 4c-76 39 3c ee cc af 9e b8   i...jS.Lv9<.....
    0020 - 02 81 e7 e5 34 13 26 1c-97 b0 8d 91 f8 4a 6a 03   ....4.&......Jj.
    0030 - 8e 62 11 4e 93 77 80 e2-e8 26 0b 4d ec 3c 00 e2   .b.N.w...&.M.<..
    0040 - 87 52 47 61 0d 6d 5e b2-7d 4b 55 2b 76 14 63 f8   .RGa.m^.}KU+v.c.
    0050 - c9 ed 7f 8f 4c 45 48 45-6a 26 c1 54 9d 65 11 ca   ....LEHEj&.T.e..
    0060 - bd a8 53 6a 37 22 33 ce-1b ab 61 c1 ba ae 06 81   ..Sj7"3...a.....
    0070 - d7 d6 ce eb e3 d4 00 41-c3 63 b7 65 db 17 d9 88   .......A.c.e....
    0080 - 64 9c 74 66 ee 73 dc ef-4b e2 6c 18 bb 6a d6 c0   d.tf.s..K.l..j..
    0090 - 2d 98 b2 40 f5 75 42 d0-e2 ae aa 48 cb b5 f6 ba   -..@.uB....H....
    00a0 - d6 89 a0 66 64 a8 06 eb-f9 6e 89 5f 78 1d 42 05   ...fd....n._x.B.
    00b0 - 81 2a b0 38 5d 70 a0 f8-21 98 3a bf 46 f4 89 2f   .*.8]p..!.:.F../

    Start Time: 1582086962
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: yes
---
closed

```

## chrome and IEでアクセス

### クライアント(Windows10)へのルート証明書のインポート
1. ルート証明書をpem -> pfx12形式に変換
    * ルート証明書の秘密キー(private/cakey.pem)にアクセス可能な環境（ex.自己ルートCA環境）でopenssl pkcs12コマンドで変更する。

    ```
    $ openssl pkcs12 -export -in rca_vubuntults_mydomain.pem -inkey private/cakey.pem -out rca_ubuntults_mydomain.pfx
    Enter pass phrase for private/cakey.pem:
    Enter Export Password:
    Verifying - Enter Export Password:
    ```

2. Windows10でrca_ubuntults_mydomain.pfxをダブルクリックすると「証明書のインポートウィザード」が実行される。「信頼されたルート証明期間」を選択してインストール実行。

    |![import_root_cert.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282300/8d67874a-7d2e-380b-2665-898e7864f3ea.png)|
|:-:|


### chromeで「https://www.vubuntults.mydomain:443」にアクセス
* ERR_CERT_COMMON_NAME_INVALIDが発生する
    * chromeはx.509:CNでホスト名を参照せず、SAN(SubjectAltName)を参照するため。今回のサーバ証明書にはX.509:CNのみが定義されている。
    * SANを参照する仕様は[RFC2818](https://www.ipa.go.jp/security/rfc/RFC2818JA.html)で推奨されており、chromeはそれに準拠している。

    |![cert_common_name_invalid.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282300/3035b547-33dd-cfdf-8942-53c33fdf8b13.png)|
|:-:|


### IEで「https://www.vubuntults.mydomain:443」にアクセス
* 正常にアクセスされる
    
    |![ie_ok.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282300/3b0e759e-589d-75d7-8fb5-7e6e47cd3f46.png)|
:-:|