Chromeに怒られないオレオレ証明書の作り方

オレオレ証明書の場合であっても、オレオレ認証局とクライアントへの証明書配布によって「この接続は安全ではありません」メッセージを回避できていたのだが、Chrome58以降で「NET::ERR_CERT_COMMON_NAME_INVALID」となりアドレスバーが赤いままとなってしまう。
Chrome58以降は、証明書を作る際のCommonNameフィールドを評価せず、「X509v3 extensions: X509v3 Subject Alternative Name」を評価するようになったらしい。<br>
ということで、CentOS7での証明証の作り方のメモ書き。
(/etc/pki/tls/…から引っ張ってくる部分以外は他OSでも同じだと思う)

### 前準備
#####ルートCAの設定

*/etc/pki/tls/openssl.cnf* を作業用のディレクトリに *rca.cnf* としてコピーしてきて編集する

1. [CA_default カテゴリ:42行目周辺] 作業パスの変更<br>
dir = /etc/pki/CA --> **dir = ./RCA**
2. [CA_default カテゴリ:73行目周辺] 証明書の有効期間の変更<br>
default_days = 365 --> **default_days = 3650**
3. [usr_cert カテゴリ:178行目周辺] コメントアウトを削除<br>
\# nsCertType = server --> **nsCertType = server**
4. [v3_ca カテゴリ:250行目周辺] コメントアウトを削除<br>
\# nsCertType = sslCA, emailCA --> **nsCertType = sslCA, emailCA**
5. [tsa_config カテゴリ:332行目周辺] 作業パスの変更<br>
dir = ./demoCA --> **dir = ./RCA**


**ここで subjectAltName の設定も行う**

1. [ req カテゴリ:126行目周辺] コメントアウトを削除<br>
\# req_extensions = v3_req --> **req_extensions = v3_req**
2. [ usr_cert カテゴリ:197行目]<br>
authorityKeyIdentifier=keyid,issuer --> **authorityKeyIdentifier=keyid,issuer:always**
3. [ usr_cert カテゴリ:204行目]<br>
\# subjectAltName=email:move --> **subjectAltName=`@`alt_names**
4. [ v3_req カテゴリ] subjectAltNameを追加<br>
**subjectAltName=`@`alt_names**<br>
5. alt_names カテゴリを v3_ca カテゴリの前に追加。alt_namesカテゴリ内に*DNS.1 = xxx.org* のようにドメイン名を書く or *IP.1 = xxx.xxx.xxx.xxx* のようにIPアドレスを書く

*/etc/pki/tls/misc/CA* を作業用のディレクトリに *rca* としてコピーしてきて31行目あたりに追記する
**CATOP=./RCA**
**SSLEAY_CONFIG="-config ./rca.cnf"**

#####中間CAの設定

*rca.cnf* をベースとして作業パスを変更した *ica.cnf* を準備する
1. [CA_default セクション:42行目周辺] 作業パスの変更
dir = /etc/pki/CA --> **dir = ./ICA**
2. [tsa_config セクション:332行目周辺] 作業パスの変更
dir = ./demoCA --> **dir = ./ICA**

*rca* をベースとして *ica* を準備する
**CATOP=./ICA**
**SSLEAY_CONFIG="-config ./ica.cnf"**

### ルートCAの作成
```shell-session
# mkdir dist
# ./rca -newca

CA certificate filename (or enter to create)
 --> ファイル名指定せず、enterのみ

Enter PEM pass phrase:
 --> 証明書のパスワードを入力
Verifying - Enter PEM pass phrase:
 --> 上記パスワードを再入力

Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:
A challenge password []:
An optional company name []:
 --> 以上は適当に
Enter pass phrase for /usr/local/ssl/RCA/private/./cakey.pem:
　--> パスワードを入力

Signature ok
（省略）
Write out database with 1 new entries
Data Base Updated

# openssl x509 -in RCA/cacert.pem -out dist/rca.crt
```
### 中間CAの作成
```shell-session
# ./ica -newreq
Enter PEM pass phrase:
 --> 証明書のパスワードを入力
Verifying - Enter PEM pass phrase:
 --> 上記パスワードを再入力

Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:
A challenge password []:
An optional company name []:
 --> 以上は適当に
Request is in newreq.pem, private key is in newkey.pem

# ./rca -signCA
 --> パスワード入力し、質問には'y'で答える

# ./ica -newca
CA certificate filename (or enter to create)
 --> newcert.pem と入力

# mv newkey.pem ICA/private/cakey.pem
# openssl x509 -in newcert.pem -out ica.crt
# openssl x509 -in ICA/cacert.pem -out dist/ica.crt
```

### サーバ証明書の作成
```shell-session
# openssl genrsa -aes256 2048 > newkey.pem
# openssl rsa -in newkey.pem -out newkey.pem
# openssl req -new -key newkey.pem -out newreq.pem

Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:
A challenge password []:
An optional company name []:
 --> いつものように入力

# ./ica -sign
# openssl x509 -in newcert.pem -out server.crt
# mv newkey.pem server.key
```

以上で下記５つのファイルが生成された

- サーバ秘密鍵 : **server.key**
- サーバ証明書 : **server.crt**
- 中間CA証明書 : **ica.crt**
- クライアントに配布するルートCA証明書 : **dist/rca.crt**
- クライアントに配布する中間CA証明書 : **dist/ica.crt**

ちなみにnginxの場合には、サーバ証明書と中間CA証明書を連結したものを使う

```shell-session
# cat server.crt ica.crt > server.nginx.crt
```


※CentOS8で/etc/pki以下が変更になり*/etc/pki/tls/misc/CA*が見当たらなくなったので引数一発で生成できるスクリプトを作成しました (https://qiita.com/masahiro-aoike/items/965bd827dc13894f6664)