サーバーが設定しているSSL暗号を確認したい時

突然ですが、SSLの暗号の設定を諸事情により変更する事があると思います。

* 例えば、2015/2 [RFC7456](http://tools.ietf.org/html/rfc7465)で、RC4が禁止となった等

サーバーのSSLの暗号の設定変更を行った後、外部からの確認方法に迷っていたのを思い出したので、備忘録がてら。

* 先に設定方法も記載しておくので、確認方法のみで良い場合は、確認方法の項へ

# サーバー側の設定

設定に関しては、例として、RC4を外していく事を想定して記載しています。

## ELBを利用している場合
AWSコンソールから以下のように辿り、RC4を利用しないポリシーを選択するか、カスタムポリシーからRC4のチェックを外す

1. EC2 -> Load Balancers -> 変更したいELB -> Listenersタブ -> Cipherの項にあるChange
2. Policyの変更

### Policyの変更
* Predefined Security Policyの場合
 * ELBSecurityPolicy-2015-2以降（問題なければ、最新の日付で良い）
* Custom Security Policyの場合
 * RC4とついているもののチェックを外していく（不要なものもあればそれらも）

## apacheやnginxの場合

![スクリーンショット 2015-04-08 15.36.57.png](https://qiita-image-store.s3.amazonaws.com/0/23194/f1aa6eed-7c8d-40aa-885f-ccf1102eced0.png)
[Mozilla SSL Configuration Generator](https://mozilla.github.io/server-side-tls/ssl-config-generator/)にお願いして基本の設定を作り、必要な部分をapacheに設定し、再起動するのが良さそうですね。

```apache
<VirtualHost *:443>
    ...
    SSLEngine on
    SSLCertificateFile      /path/to/signed_certificate
    SSLCertificateChainFile /path/to/intermediate_certificate
    SSLCertificateKeyFile   /path/to/private/key
    SSLCACertificateFile    /path/to/all_ca_certs

    # modern configuration, tweak to your needs
    SSLProtocol             all -SSLv2 -SSLv3 -TLSv1
    SSLCipherSuite          ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK
    SSLHonorCipherOrder     on
    SSLCompression          off

    # OCSP Stapling, only in httpd 2.3.3 and later
    SSLUseStapling          on
    SSLStaplingResponderTimeout 5
    SSLStaplingReturnResponderErrors off

    # HSTS (mod_headers is required) (15768000 seconds = 6 months)
    Header always add Strict-Transport-Security "max-age=15768000"
    ...
</VirtualHost>
SSLStaplingCache        shmcb:/var/run/ocsp(128000)
```
* SSLCipherSuiteに"!RC4"という設定が居る事を確認します

吐き出された設定のままで良さそうですが、変更したい場合は適宜変更します。

* 例えば、TLSv1は在っても良いかなという場合は以下のようにすると良いと思います

```apache
SSLProtocol             all -SSLv2 -SSLv3
```

# 確認方法

本題です！

## 外部からのアクセスがウェルカムな場合

[SSL Server Test](https://www.ssllabs.com/ssltest/index.html)にお願いする

* 注意点としては、一覧に載りたくない場合は、「Do not show this results on the boards」のチェックを入れてから、お願いする事ですかね
![スクリーンショット 2015-04-08 14.52.47.png](https://qiita-image-store.s3.amazonaws.com/0/23194/652885e4-18af-7e70-431b-a0fe30fb63f5.png)


* しばらく(2,3分？)待つと、以下のようにランク付けや、各種アドバイスもたくさんもらえます

![スクリーンショット 2015-04-08 14.53.26.png](https://qiita-image-store.s3.amazonaws.com/0/23194/a1abf6b9-46a8-e768-4886-6da842ac63e0.png)

## 諸事情によりコマンドで確認したい場合

[OpenSSLをSSL/TLSクライアントとして使ってみる](https://siguniang.wordpress.com/2014/08/09/openssl-as-ssl-client/)
上記サイトを参考に以下のようなコマンドになりました

```bash
openssl s_client -connect example.com:443 -cipher ECDHE-RSA-AES128-GCM-SHA256 < /dev/null
```
* 入力待ちモードでなくても良いので、/dev/nullを投げています
* 指定したcipherが使えなかった場合は、「error」や「Cipher is (NONE)」等が出ていると思います
* ローカルのopensslに依存するので、ローカルのopensslが使えないcipherは試せないです

後は、cipherを変更してコマンドを実行して行けばOKです。
指定出来るものは、下記コマンドで出せます。

```bash
openssl ciphers -v
```

### スクリプトでやる

対象が2, 3個なら、手動でも良いのですが、それ以上だと面倒なので、rubyスクリプトにお任せします。

```ruby:check.rb
# RC4系列だけにしてみた
ciphers = `openssl ciphers -v RC4`

# 調査対象サーバー:ポート
connect_server = "example.com:443"

check_results = []
ciphers.each_line{|protocol_suite|
  encrypt_protocol = protocol_suite.split(/\s/)[0]
  
  cmd_result = `openssl s_client -connect #{connect_server} -cipher #{encrypt_protocol} < /dev/null`
                                           
  cmd_result =~ /^New.*Cipher is (.*)$/    
  check_results << "client cipher is #{encrypt_protocol}, session cipher is #{$1}"
}

puts "------------"
puts check_results
```

```bash:実行結果
client cipher is ECDHE-RSA-RC4-SHA, session cipher is (NONE)
client cipher is ECDHE-ECDSA-RC4-SHA, session cipher is (NONE)
```
* 利用出来ないcipherの場合は、NONEと出る

例外処理等は一切存在しないですし、利用環境によってまちまちになるかもしれないスクリプトなので、参考程度に

# まとめ
Qualysさんの[SSL Server Test](https://www.ssllabs.com/ssltest/index.html)にお任せするのが良いですね。
出来ない場合は、openssl s_clientで！

それにしてもAWSは楽で良いですね〜。