あなたのサーバーは大丈夫？安全なHTTPS設定の確認方法・検証ツール

# **はじめに**

本記事では日々変わっていく安全なHTTPS(SSL/TLS)の設定に関する確認手段を紹介します。常にセキュリティ系のニュースをウォッチするのが理想なのですが、完全に追いつくのは至難の業ですよね。

## **脆弱性とは**

Wikipedia セキュリティホールより

>セキュリティホール は、脆弱性についての俗表現である。 脆弱性は、コンピュータソフトウェアの欠陥（バグ、不具合、あるいはシステム上の盲点）の一つで、本来操作できないはずの操作（権限のないユーザが権限を超えた操作を実行するなど）ができてしまったり、見えるべきでない情報が第三者に見えてしまうような不具合をいう。ハードウェアおよびそれを含めたシステム全般の欠陥を指すこともある。

製品XXXのバグにより第三者に悪用されてしまう！といったものから、先日のインテルCPUに対する[Meltdown, Spectre](http://www.daj.jp/news/180403_01/)といった、仕様に対する脆弱性まで様々です。
特にここ数年は自分の業務が変わったからか、この「仕様に対する脆弱性」をよく目にするようになった気がします。

ちなみに(多分ですけど)そういった大き目の脆弱性に対しては判定機関が番号付けして管理されていたり(CVEXXXみたいな)、報告者から"Meltdown"のような通称がつけられていたりします。
脆弱性番号については[こちらの記事](https://qiita.com/urakarin/items/576aa0816b3ce9551776)でまとめてくれています。

## **HTTPS (SSL/TLS)と脆弱性**

WikipediaよりSSL/TLS抜粋。

>Transport Layer Security（トランスポート・レイヤー・セキュリティ、TLS）は、インターネットなどのコンピュータネットワークにおいてセキュリティを要求される通信を行うためのプロトコルである。

上記のように、「セキュリティの強固な通信をしましょう！」が目的のSSL/TLSと、それを利用したHTTP通信のHTTPSですが、その特性からか特に頻繁に脆弱性が見つかっている気がします。

例えば自分でも知っている名前の付いた脆弱性だと、
[POODLE](http://moro-archive.hatenablog.com/entry/2014/11/04/042754)というSSL 3.0自体への脆弱性だったり、
[FREAK](https://ja.wikipedia.org/wiki/FREAK), [Logjam](http://www.itmedia.co.jp/enterprise/articles/1505/22/news150.html)という鍵長が起因になる脆弱性では、の問題が指摘されています。

ただ、こういった大きい脆弱性はすぐにまとめサイトが出来るのがありがたいですね。[Logjamならここ](https://weakdh.org/sysadmin.html)とか。


その他、技術の向上によりもう時代遅れとなり、それ自体が危険になった暗号化の仕組み(以降Cipher Suite)が日々出てきたり。
つまり、SSL/TLSに関わるサーバーを利用している人にとって、**安全なSSL/TLSを利用する為の設定、利用OSSバージョンがは日々変わっている**という状態です。

# **安全なHTTPS設定の確認方法**

上記のような脆弱性、日々自力で追うのは中々辛いですね。というわけで確認方法や検証ツールの紹介です。

## **確認チェックリスト: SSL/TLS暗号設定ガイドライン**

IPA(情報処理推進機構)が公式で[ガイドライン](https://www.ipa.go.jp/security/vuln/ssl_crypt_config.html)を出しています。最新は2018年5月8日公開と、常に更新されている感が見て取れます。
サイト内の**SSL/TLS暗号設定ガイドライン_チェックリスト**に、HTTPSサーバーの利用状況に合わせた設定のチェックリストが記載されています。
まずはチェックリストで自身のHTTPS設定を確認するのがよさそうですね。

また、参考資料[SSL/TLS 暗号設定 サーバ設定編](https://www.ipa.go.jp/security/ipg/documents/ssltls_server_config_20150803.pdf), [SSL/TLS暗号設定 暗号スイートの設定例](https://www.ipa.go.jp/security/ipg/documents/ssltls_cipher_suite_config_20150803.pdf)に実際の有名サーバーでの設定例が載っていました。lighttpdも記載。IPA凄い！

## **検証サイト SSL Server Test**
設定したら、テストで検証したいですよね。
[SSL Server Test](https://www.ssllabs.com/ssltest/)というサイトでは、サーバーに対しての脆弱性を1つづつ検証し、総合評価といい点悪い点を評価してくれます。
試しにqiitaをテストしてみました。結果はA判定！流石！

<img width="840" alt="qiitaの評価.png" src="https://qiita-image-store.s3.amazonaws.com/0/252277/c24b0a9f-28de-144c-43d4-813202b82b5b.png">

ちなみにqiitaを試したのは、[前にLD_PRELOADでSSL_read/writeをオーバーライドした時](https://qiita.com/developer-kikikaikai/items/f6f87b2d1d7c3e14fb52)にHTTP/2を使われているのを知り、[HTTP/2を使う暗号強度条件を満たしている](https://qiita.com/developer-kikikaikai/items/4a336420750d7b7d0483#httpstls%E3%81%A8%E3%81%AE%E9%96%A2%E4%BF%82)ならいい結果が出るでしょう！という動機だったり。(その時に試したyahoo.co.jpもAでしたが、Protocol Supportでちょっと下回っていました)

SSL Server Testの結果を見てみると、SupportしているCipher Suitesはもちろん、各ブラウザを利用した場合の接続シミュレーションや各脆弱性の対処がされているかもわかります。

外部に公開されているHTTPサーバーならこちらのサイトで申し分ない！って感じですね。ツールの詳細は[こちら](https://seven.ne.jp/qualys-ssl-labs-%E3%81%AE-ssl%E8%84%86%E5%BC%B1%E6%80%A7%E8%A8%BA%E6%96%ADssl-server-test%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/)で日本語で丁寧に説明されていますので興味のある方はご覧ください。

## **検証ツール(Python) SSLyze**

今回の個人的な本題はこちらです。lighttpdサーバー構築を決めた後に[Let's EncryptでのHTTPSサーバー構築記事](https://qiita.com/z80/items/62225e6468d823fc73c9)でSSL Server Testの存在を知り、似たようなローカルツールないかな～と思っていたのが本記事作成のきっかけです。

早速SSL Server Testで検索。開発者のコミュニティによるとSSL Server Testのoffline版はないらしいです。
と思ったら**SSL Server Test作成者本人が[他のtoolに関する情報](https://github.com/ssllabs/research/wiki/Assessment-Tools)をまとめてwikiに載せてる**とのこと。凄い！

[このwiki](https://github.com/ssllabs/research/wiki)自体、SSL/TLS、PKI関連の情報をまとめるためのもので、情報量も凄いですしSSL Server Test開発された方の情報ってだけで信頼度も増しますね。興味がある方はぜひ！

ここでは作成者おすすめの**SSLyze**を試してみます。
動作環境はUbuntu 18.04です。

### **SSLyzeのインストール**

まずはpython, pipのコマンドをインストール。pipはないのでインストールしました。
pipはpythonのパッケージ管理ツールです。そんな便利なものがあるの！？と思った、私のような方は[こちら](https://qiita.com/saitoxu/items/18e6a1c8c7840029147e)を参照ください。

```
sudo apt install python-pip
```

後は公式ページに倣いインストール

```
sudo pip install --upgrade setuptools
sudo pip install --upgrade sslyze
```

最後はpythonコマンドの-mでsslyzeを指定すればOK！

```
python -m sslyze --regular www.yahoo.com:443
```

もしくは単にこれでもOKです。(pipめっちゃ便利!)

```
sslyze --regular www.yahoo.com:443
```

### **試してみた**

早速lighttpdにHTTPS設定をして試してみました。
※1.4.48からかな？SSL処理がプラグイン化されてますのでご注意を。ソースのデフォルトビルドは無効です。(なので私も再ビルドしました。)

とりあえずシンプルな設定を。証明書は敢えての自己署名証明書でトライ。

```
server.modules += ( "mod_openssl" )

$SERVER["socket"] == "0.0.0.0:443" {
        ssl.engine  = "enable"
        ssl.pemfile = "/usr/local/www/etc/ssl/httpd.pem"
}
```

出力はこんな感じのテキストベースでした。量が多いので抜粋して紹介していきます。

```
 SCAN RESULTS FOR 192.168.100.102:443 - 192.168.100.102
 ------------------------------------------------------

 * TLSV1 Cipher Suites:
       Forward Secrecy                    OK - Supported
       RC4                                OK - Not Supported

...

 SCAN COMPLETED IN 5.18 S
 ------------------------
```

脆弱性の指摘されているSSL2.0, 3.0. TLS1.0のサポート確認をしていますね。最新のOpenSSL && lighttpdならこの辺デフォルトで無効なんですね。セーフ。

```
 * SSLV2 Cipher Suites:
      Server rejected all cipher suites.

 * TLSV1_3 Cipher Suites:
      Server rejected all cipher suites.
```

TLS1.1の確認。Cipher Suiteの確認に加え、[ダウングレード攻撃](https://asnokaze.hatenablog.com/entry/20141015/1413360514)のような脆弱性もチェックしてるんですね。問題なし。

```
 * TLSV1_1 Cipher Suites:
       Forward Secrecy                    OK - Supported
       RC4                                OK - Not Supported

     Preferred:
        None - Server followed client cipher suite preference.
     Accepted:
        TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA                ECDH-256 bits  256 bits      HTTP 200 OK
        TLS_DHE_RSA_WITH_AES_256_CBC_SHA                  DH-1024 bits   256 bits      HTTP 200 OK
        TLS_RSA_WITH_AES_256_CBC_SHA                      -              256 bits      HTTP 200 OK
        TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA                ECDH-256 bits  128 bits      HTTP 200 OK
        TLS_DHE_RSA_WITH_AES_128_CBC_SHA                  DH-1024 bits   128 bits      HTTP 200 OK
        TLS_RSA_WITH_AES_128_CBC_SHA                      -              128 bits      HTTP 200 OK

 * Downgrade Attacks:
       TLS_FALLBACK_SCSV:                 OK - Supported

 * Deflate Compression:
                                          OK - Compression disabled
```

ただ気になったこととしては、明らかにNGな暗号のチェックはしてるけど、Cipher Suite自体の優劣まではチェックしていません。[参考サイト](https://qiita.com/z80/items/62225e6468d823fc73c9)でのlighttpdの設定は、ここでSSL Server Testに評価を落とされていました。
ここは環境によって求めるものが違うので、単純にOK/NGだけでは表現が難しいからかな？
自分の環境にあった厳密なチェックをするなら、IPA等のサイトを参考にあるべき姿を検証するようパースしてあげれるのがベストですね。

　


さて、ここまではOpenSSLやlighttpd側の設定に助けられてきた自前のHTTPサーバーですが、やはり証明書周りは軒並みエラーです。
いや～、これは気持ちいい笑

```
 * Certificate Information:
     Content
...

     Trust
       Hostname Validation:               OK - Certificate matches 192.168.100.102
       Android CA Store (8.1.0_r9):       FAILED - Certificate is NOT Trusted: self signed certificate
       iOS CA Store (11):                 FAILED - Certificate is NOT Trusted: self signed certificate
       Java CA Store (jre-10.0.1):        FAILED - Certificate is NOT Trusted: self signed certificate
       macOS CA Store (High Sierra):      FAILED - Certificate is NOT Trusted: self signed certificate
       Mozilla CA Store (2018-04-12):     FAILED - Certificate is NOT Trusted: self signed certificate
       Windows CA Store (2018-04-26):     FAILED - Certificate is NOT Trusted: self signed certificate
       Symantec 2018 Deprecation:         OK - Not a Symantec-issued certificate
       Received Chain:                    192.168.100.102
       Verified Chain:                    ERROR - Could not build verified chain (certificate untrusted?)
       Received Chain Contains Anchor:    ERROR - Could not build verified chain (certificate untrusted?)
       Received Chain Order:              OK - Order is valid
       Verified Chain contains SHA1:      ERROR - Could not build verified chain (certificate untrusted?)

     Extensions
       OCSP Must-Staple:                  NOT SUPPORTED - Extension not found
       Certificate Transparency:          NOT SUPPORTED - Extension not found
```

別途lighttpd側のSSLV3.0, 2.0の設定も有効にしたり、DHの鍵長をあえて512bitにして試してみましたが、lighttpd/OpenSSLのOSS側でうまく蓋がされているようで、その辺りが結果として見えるのかは今回確認出来ませんでした。残念！


# **おわりに**

巷を騒がせる脆弱性、日々の対処や検証は本当に大変だと思います。
ただそれだけ巷が騒いでいるということは、対処方法は世の中にたくさんあるんだなと強く実感しました。自分で情報収集も大事ですが、もっと世の中のものを活用しよう！ってのが大事ですね。

また、試した結果脆弱性と直接的にかかわらなかったので省きましたが、[Gauntltによるセキュリティテスト #SWTestAdvent](https://qiita.com/hayabusa333/items/b268bb6123b6c61653f4)という記事で紹介されているrubyのGauntltは、テストシナリオを作成して一連のセキュリティテストをしよう！なんてことが出来るツールでした。検証を自動化するにはこういったテスト連動ができるツールは欠かせませんね。
pipを初めて知ったり、自分は想像していたよりもはるかに時代の後を行っていたんだなと実感(-_-;)精進します。

# **参考**

脆弱性系記事:
[Meltdown, Spectre](http://www.daj.jp/news/180403_01/)
[POODLE](http://moro-archive.hatenablog.com/entry/2014/11/04/042754)
[FREAK](https://ja.wikipedia.org/wiki/FREAK)
[Logjam](http://www.itmedia.co.jp/enterprise/articles/1505/22/news150.html)
[Logjam 各サーバーの対策方法](https://weakdh.org/sysadmin.html)
[脆弱性には番号があるらしい](https://qiita.com/urakarin/items/576aa0816b3ce9551776)
[TLSのダウングレード攻撃を防ぐSCSVとは](https://asnokaze.hatenablog.com/entry/20141015/1413360514)

IPA(情報処理推進機構)ガイドライン:
[SSL/TLS暗号設定ガイドライン～安全なウェブサイトのために（暗号設定対策編）～](https://www.ipa.go.jp/security/vuln/ssl_crypt_config.html)

検証サイト:
[本家 SSL Server Test](https://www.ssllabs.com/ssltest/)
[Qualys SSL Labs の SSL脆弱性診断(SSL Server Test)について](https://seven.ne.jp/qualys-ssl-labs-%E3%81%AE-ssl%E8%84%86%E5%BC%B1%E6%80%A7%E8%A8%BA%E6%96%ADssl-server-test%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/)


検証ツール:
[SSL Server Test作成者のまとめているツール一覧](https://github.com/ssllabs/research/wiki/Assessment-Tools)
[sslyze 公式](https://github.com/nabla-c0d3/sslyze)
[Gauntltによるセキュリティテスト #SWTestAdvent](https://qiita.com/hayabusa333/items/b268bb6123b6c61653f4)

その他:
[SSL Server Test作成者wiki](https://github.com/ssllabs/research/wiki)
WikiとSSLyzeをお勧めしていた情報元(SSL Server Test開発会社のコミュニティ)：
[SSL Labs Offline Tool?](https://community.qualys.com/thread/13536)
この記事をまとめようと思ったきっかけ：
[LighttpdをLet's Encryptでセキュアなhttpsサーバにする](https://qiita.com/z80/items/62225e6468d823fc73c9)

Python pipについて：
[Pythonを使う上で欠かせないパッケージ管理システムpipの使い方](https://qiita.com/saitoxu/items/18e6a1c8c7840029147e)
[wikipedia pip](https://ja.wikipedia.org/wiki/Pip)