SSL証明書の更新作業でドハマりした話


# はじめに
思い込みは<b><font color="FF0000">危険。</font></b>
そして自分への戒めということで備忘録として残す。
ネタ自体はさんざん既出だと思うけどｗ

## SHA2対応の証明書組み込み作業
あるあるSHA2対応のサーバー証明書組み込み。
今回は有効期限切れ前の証明書の更新作業。
SHA2対応にかかわらずオペレーションとしては一緒だけど。

今回組み込んだ環境（Apacheのバージョン）は以下の通り。

```
$ httpd -v
Server version: Apache/2.2.29 (Unix)
Server built:   Mar 12 2015 03:50:17
```

### 証明書アップロード（SCP）
証明書関連のファイルのアップロード。
アップロード方法は諸方法あるけど、当方の環境はsshでconfigに設定記載済みのため、configのホスト情報を使ってscpでアップロードを行う。

```bash:.ssh/config
### 設定はダミーなので適宜読み替え必要
Host cert_hostname
HostName 10.**.***.123
User username
IdentityFile ~/.ssh/id_rsa/host.pem
Port 22
```

[username@hostname]の省略くらいにしかならないけど。
要は[username@hostname]を.ssh/configのHostで置き換える形。

```
-> % scp certfile cert_hostname:/path/to/dstdir
    certfile   100% 1675     1.6KB/s   00:00
```



### 環境確認
SSLの設定はデフォルトでここ。
`/etc/httpd/conf.d/ssl.conf`

既存の設定は中間証明書未使用。
今回は中間証明書使用。


```    
    #   Server Certificate:
    SSLCertificateFile /path/to/certfile
    
    #   Server Private Key:
    SSLCertificateKeyFile /path/to/keyfile
    
    #   Server Certificate Chain:
    #SSLCertificateChainFile /path/to/chainfile
```


#### SSLCertificateChainFile と SSLCACertificateFile の違い

* SSLCertificateChainFileディレクティブ：サーバー証明書における中間証明書のパスを設定
* SSLCACertificateFileディレクティブ：クライアント証明書における中間証明書のパスを指定

注）これはあくまでApache2.2.x時点の設定
Apache2.4.8以降はSSLCertificateChainFileディレクティブはない。


### ファイルの設置とパーミッションの変更
新しい証明書ファイル持ってきて、既存ファイルはリネーム。 
ファイルのパーミッションもセキュリティの観点からreadonlyに。

```
# chmod 400 keyfile
# chmod 404 chainfile
# chmod 404 certfile
```

### ssl.confの設定変更
中間証明書を利用するためSSLCertificateChainFileディレクティブのコメントアウトを外す。

```
    #   Server Certificate:
    SSLCertificateFile /path/to/certfile
    
    #   Server Private Key:
    SSLCertificateKeyFile /path/to/keyfile
    
    #   Server Certificate Chain:
    SSLCertificateChainFile /path/to/chainfile
```


### configtest（シンタックスチェック。`httpd -t`と同義）
```
    # service httpd configtest
    Syntax OK
```

### プロセスの状態を確認
 
```
    # service httpd status
    httpd (pid  1210) is running...
```

### 設定を反映 

```
    # service httpd graceful
```


### 証明書の組み込み確認（s_client利用）
組み込み確認も諸方法あるけど、手っ取り早いのはサーバーの中にsshで入ってる状態であればopensslの **s_client** を利用する方法。
オプション駆使すればcipher周りの脆弱性のチェックも可能。
オプション駆使しなくても `openssl s_client -connect` だけでわりと見たい情報は見れる。便利便利。

```
$ openssl s_client -connect sub.example.com:443
CONNECTED(00000003)
depth=0 CN = sub.example.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = sub.example.com
verify error:num=27:certificate not trusted
verify return:1
depth=0 CN = sub.example.com
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain

・・・　中略　・・・

   Start Time: 1473157714
    Timeout   : 300 (sec)
    Verify return code: 21 (unable to verify the first certificate)
---
```

で、ここでエラーが出た。
chain情報とかすっ飛ばして、<b><font color="FF0000">Verify return code</font></b>のステータスである程度わかる。
要はエラーになっている。

何回設定見返してもファイルアップロードし直しても改善されない。
その原因は・・・

### まさかのSSL設定ファイルがカスタム設定になっていた
デフォルトは `/etc/httpd/conf.d/ssl.conf` なんだが
まさかのVirtualHostがきってあってSSL設定の参照先がデフォルトじゃねーよ！！！！
（※ちなみにこの更新作業において ~~事前情報として何も知らされていない~~ 

シンタックスチェックするなら `-t` より `-S` 使うほうがVirtualHostの設定も一覧で確認できるし良いと思う。

```
# httpd -S
    VirtualHost configuration:
    wildcard NameVirtualHosts and _default_ servers:
    *:443                  is a NameVirtualHost
             default server sub.example.com (/etc/httpd/conf.d/customssl.conf:22)
             port 443 namevhost sub.example.com (/etc/httpd/conf.d/customssl.conf:22)

・・・　以下略　・・・

 Syntax OK 
```

はい。これで書き換えたらちゃんと<b><font color="FF0000">Verify return code: 0 (ok)</font></b>で返ってきましたよ。

```
    $ openssl s_client -connect sub.example.com:443
    CONNECTED(00000003)
    depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
    verify return:1
    depth=1 C = US, O = GeoTrust Inc., CN = RapidSSL SHA256 CA
    verify return:1
    depth=0 CN = sub.example.com
    verify return:1
    ---
    Certificate chain
     0 s:/CN=sub.example.com
       i:/C=US/O=GeoTrust Inc./CN=RapidSSL SHA256 CA
     1 s:/C=US/O=GeoTrust Inc./CN=RapidSSL SHA256 CA
       i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
    ---
    Server certificate
    
    ・・・　中略　・・・
    
        Start Time: 1473165777
        Timeout   : 300 (sec)
        Verify return code: 0 (ok)
```
        

思い込みとは **怖いものだ。。。**
みんなも作業時はあらゆる可能性を考慮して作業しましょう。。。