The SSL certificate has expiredとなった時の対応方法

# 事象 : Payaraのserver.logを見たらいっぱいなんか出てた

```log:server.log
[2020-04-22T17:36:57.020+0900] [Payara 5.194] [?x??] [NCLS-SECURITY-05054] [javax.enterprise.system.security.ssl] [tid: _ThreadID=54 _ThreadName=admin-thread-pool::admin-listener(1)] [timeMillis: 1587544617020] [levelValue: 900] [[
  The SSL certificate has expired: [
[
  Version: V3
  Subject: CN=Staat der Nederlanden Root CA - G2, O=Staat der Nederlanden, C=NL
  Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11

  Key:  Sun RSA public key, 4096 bits
  modulus: 8051226021100838930438588........
  public exponent: 65537
  Validity: [From: Wed Mar 26 20:18:17 JST 2008,
               To: Wed Mar 25 20:03:10 JST 2020]
  Issuer: CN=Staat der Nederlanden Root CA - G2, O=Staat der Nederlanden, C=NL
  SerialNumber: [    98968c]

Certificate Extensions: 4
[1]: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
  CA:true
  PathLen:2147483647
]

[2]: ObjectId: 2.5.29.32 Criticality=false
CertificatePolicies [
  [CertificatePolicyId: [2.5.29.32.0]
[PolicyQualifierInfo: [
  qualifierID: 1.3.6.1.5.5.7.2.1
  qualifier: 0000: 16 31 68 74 74 70 3A 2F   2F 77 77 77 2E 70 6B 69  .1http://www.pki
0010: 6F 76 65 72 68 65 69 64   2E 6E 6C 2F 70 6F 6C 69  overheid.nl/poli
0020: 63 69 65 73 2F 72 6F 6F   74 2D 70 6F 6C 69 63 79  cies/root-policy
0030: 2D 47 32                                           -G2

]]  ]
]
...省略...
```

## 原因 : SSL証明書の有効期限が切れているから
[Java EE GlassFish でSEC5054: Certificate has expiredが出たときの対応方法 - Qiita](https://qiita.com/MANO_fukuoka/items/baf66c25a09335590aab)

### cacerts.jks？
> トラストストア (「信頼」ストア) には、クライアントに信頼されている証明書のみが格納されます。これらの証明書は CA ルート証明書、つまり自己署名付き証明書です。論理ホストをインストールすると、次の場所に cacerts.jks という名前のトラストストアファイルが格納されます。
> <c:\JavaCAPS>\appserver\domains\<MyDomain>\config
> [キーストアとトラストストア (SSL をサポートする Java CAPS の構成) ](https://docs.oracle.com/cd/E19416-01/820-5959/ggffo/index.html)

cacerts.jksをエディタで開いても読めない・・・ので`keytool`ユーティリティーというものを使う。

### 使うシェル環境にJavaのPATHが設定されているか確認する
> 始める前に
> keytool ユーティリティーを実行するには、シェル環境を設定して、J2SE の /bin ディレクトリがパスに含まれるようにする必要があります。そうでない場合は、ユーティリティーのフルパスをコマンド行に指定する必要があります。
> [keytool による証明書の生成 (Sun GlassFish Enterprise Server v3 管理ガイド)](https://docs.oracle.com/cd/E19226-01/821-1299/ghlgv/index.html)

1. いろんなバージョンを使っているとPATHを設定していなかったりするので確認する
1. PATHが設定されていなければ設定する

```bash
$ java -version
java version "1.8.0_231"
Java(TM) SE Runtime Environment (build 1.8.0_231-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.231-b11, mixed mode)
```

### 有効期限切れの情報の確認方法
`keytool -list -v -keystore cacerts.jks`で情報を表示できるらしい。

> -list コマンドでは、デフォルトで証明書の MD5 フィンガープリントが出力されます。-v オプションを指定すると、人間が読むことのできる形式で証明書が出力されます。 一方、-rfc オプションを指定すると、出力可能符号化方式で証明書が出力されます。
> -storepass storepass
> キーストアの完全性を保護するために使うパスワードを指定します。
> [keytool - 鍵と証明書の管理ツール](https://docs.oracle.com/javase/jp/1.5.0/tooldocs/solaris/keytool.html)

そして、パスワードの情報は以下のサイトで紹介されていた
> マスターパスワードは「changeit」
> [Java EE GlassFish でSEC5054: Certificate has expiredが出たときの対応方法 - Qiita](https://qiita.com/MANO_fukuoka/items/baf66c25a09335590aab)


```bash:有効期限切れの証明書をグレップする流れ
# 1. 証明書1つにつきこんな感じの出力がされる(大量に出るのでファイル等に出力するのがおすすめ)
$ keytool -list -v -keystore cacerts.jks -storepass changeit
別名: cert_92_ca_disig_root_r192
作成日: 2018/01/23
エントリ・タイプ: trustedCertEntry

所有者: CN=CA Disig Root R1, O=Disig a.s., L=Bratislava, C=SK
発行者: CN=CA Disig Root R1, O=Disig a.s., L=Bratislava, C=SK
シリアル番号: c3039aee50906e28
有効期間の開始日: Thu Jul 19 18:06:56 JST 2012終了日: Sat Jul 19 18:06:56 JST 2042
...省略...

# 2. 有効期限を確認するには「別名」「有効期間」の行をグレップする
$ keytool -list -v -keystore cacerts.jks -storepass changeit | grep -e 別名 -e 有効期間
別名: cert_115_staat_der_nederlanden_root_ca___g3115
有効期間の開始日: Thu Nov 14 20:28:42 JST 2013終了日: Tue Nov 14 08:00:00 JST 2028
...省略...

# 3. グレップした「別名」「有効期間」から更に年で情報をグレップする
% keytool -list -v -keystore cacerts.jks -storepass changeit | grep -e 別名 -e 有効期間 | grep -B 1 -e 201[0-9]$ -e 2020$
```

たまに`別名: addtrustclass1ca [jdk]`みたいに別名に`[jdk]`みたいにくっついているのがある。
そんな時に証明書を削除するコマンドでは、`-alias 'addtrustclass1ca [jdk]'`とシングルクォーテーションで囲ったらうまくいった。

```bash:証明書を削除する場合のコマンド
$ keytool -delete -keystore cacerts.jks -storepass changeit -alias '{別名}'
```

## 対応 : cacerts.jksから有効期限切れの情報を削除する
### macOSの時の記録
- 環境
    - macOS Big Sur バージョン11.0.1
    - Payara Server  5.2020.7

```bash
# keytoolのディレクトリへ移動
% cd /usr/local/opt/payara5/glassfish/domains/domain1/config

# バックアップを取る
% cp cacerts.jks cacerts.jks.bak
% ls -la cacerts.jks*
-rw-r--r--  1 ponsuke  admin  423574  5 29  2019 cacerts.jks
-rw-r--r--  1 ponsuke  admin  423574 12 21 22:26 cacerts.jks.bak

# 2020年以前で期限の切れるものをグレップ
% keytool -list -v -keystore cacerts.jks -storepass changeit | grep -e 別名 -e 有効期間 | grep -B 1 -e 201[0-9]$ -e 2020$
別名: cert_91_pscprocert91
有効期間の開始日: Wed Dec 29 01:51:00 JST 2010終了日: Sat Dec 26 08:59:59 JST 2020

# グレップした結果をエディタなどで置換してコマンドを作って一気に実行する
% keytool -delete -keystore cacerts.jks -storepass changeit -alias 'cert_91_pscprocert91'
```


### Windowsの時の記録
- 環境
    - Windows 10 Pro 64bit バージョン1903
    - GitBash(mintty 2.7.3)
    - Payara Server 5.2020.7

```bash
# cacerts.jksのあるディレクトリへ移動する
$ cd /c/app/payara5/glassfish/domains/domain1/config

# cacerts.jksのバックアップを取る
$ cp cacerts.jks cacerts.jks.bak
$ ls -la cacerts.jks*
-rw-r--r-- 1 m-uki 197609 390428 12月  7 06:58 cacerts.jks
-rw-r--r-- 1 m-uki 197609 390428 12月 31 22:21 cacerts.jks.bak

# 文字化けするので
$ keytool -list -v -keystore cacerts.jks -storepass changeit
...省略...
▒ʖ▒: ttelesecglobalrootclass2ca [jdk]
▒쐬▒▒: 2020/12/07
▒G▒▒▒g▒▒▒E▒^▒C▒v: trustedCertEntry
...省略...

# 文字化けしないようにailiasを設定して
$ vi ~/.bash_profile
$ cat ~/.bash_profile
...省略...
# Windowsコマンドの文字化け対策
function wincmd() {
    CMD=$1
    shift
    $CMD $* 2>&1 | iconv -f cp932 -t utf-8
}
alias keytool='wincmd keytool'

# 反映させる
$ source ~/.bash_profile

# 2020年以前に有効期限が切れているものの別名をグレップする
$ keytool -list -v -keystore cacerts.jks -storepass changeit | grep -e 別名 -e 有効期間 | grep -B 1 -e 201[0-9]$ -e 2020$
別名: cert_91_pscprocert91
有効期間の開始日: Wed Dec 29 01:51:00 JST 2010終了日: Sat Dec 26 08:59:59 JST 2020

# 有効期限が切れているものを削除する
$ keytool -delete -keystore cacerts.jks -storepass changeit -alias 'cert_91_pscprocert91'
```