もくじ
1. はじめに
いや〜、今年は脆弱性対策が当たり年ですね〜〜(トホホ)。 bash ShellShockの対策も継続して観察しているなか、 新しいPOODLEというSSLv3プロトコルに関する脆弱性が出てしまいました。 子犬のプードルだって!可愛くないっつ〜〜の!! SSLv3プロトコルのパディングの問題点を突いて、効率的に暗号文を 復号できしまうので、例えばセッションクッキーを復号して通信を盗聴することが できるのだそうです。 POODLEはPadding Oracle On Downgraded Legacy Encryptionの略だそうで、 パディングオラクルとはパディングを含む暗号文を入力として送りつけると、 そのパティングが正しいかどうかを返してくれるブラックボックスのような 計算機のこと。 SSLv3みたいなできて15年にもなる弱い暗号通信プロトコルに、 強制的にダウングレードさせて、 オラクルに対して何回もいろいろ入力を変えて試行して、 エラーメッセージなどどう反応するかを見る事で、 暗号文の解読が効率良く行えるという攻撃です。
気がついたまでの経緯は当日どんな感じだったかというと、日本時間で10月14日の23:30頃、 The Registerの「NASTY SSL 3.0 vuln to be revealed soon」の記事を見つけていまい、こりゃ、やばげだなと。知り合いに明日ヤバイのがまた来そうと連絡しました。TLS 1.0とSSL 3.0とバージョン番号が違うだけだと言い張る人も多い中、Macとか、パディングとかそのちょっとの違いが仇になるんじゃないかと、ずっと気になってたんですが、とうとう来たかと。詳細情報は夜が明けないとわからないので、半分 wktk しながら寝て待ってたんですが、朝になって、Googleのブログ 「This POODLE bites: exploiting the SSL 3.0 fallback」が出てきたものの、わかったことはプードルという可愛らしい攻撃の名前と、GoogleサイトとChromeはとっくにTLS_FALLBACK_SCSVに対応しているぜ!みたいな。 自慢かっ?技術詳細なく自慢だけなのかっ!と憤りつつ、しばらく待ってると、 やっと安定のImperialVioletで 「POODLE attacks on SSLv3 (14 Oct 2014)」 技術解説が出たのを見て、こりゃマジやべ〜〜な、と・・・ その後、情報のとりまとめにいそしんでおりました。
この記事では、様々なHTTPSサーバーに対するPOODLE脆弱性対策の 方法について、まとめておきたいと思います。
2. SSLv3を無効化できる場合のサーバー対策
古いガラケーや、一部のゲーム機や、古い環境でのAPI利用などを除いて、 一般のブラウザであればSSLv3でしか通信できないという事は無いので、 SSLv3を無効化するというのが、一番正当なPOODLE対策であると思います。 この章では、SSLv3を無効にするために、 サーバーのソフトウェア毎にどのように設定すればよいかをまとめます。
2.1. Apache HTTPD Server + mod_ssl
httpd.confやssl.confに
SSLProtocol All -SSLv2 -SSLv3と記載しサーバーを再起動 (※Apache 2.4以降はSSLv2は無効)
2.2. Apache HTTPD Server + mod_nss
nss.confもしくはhttpd.confで
NSSProtocol TLSv1.0,TLSv1.1と記載しサーバーを再起動
2.3. nginx
ssl_protocols TLSv1 TLSv1.1 TLSv1.2と記載しサーバーを再起動
2.4. lighttpd
lighttpd 1.4.28 以降を使用。それ以前ではSSLv3を無効化できません。
ssl.use-sslv2 = "disable"と記載しサーバーを再起動
ssl.use-sslv3 = "disable"
2.5. Microsoft IIS
コマンドラインで以下を実行することで、レジストリ設定により無効化します。
(参考
[1]
[2]
[3])
reg add "HKLM\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server" /v Enabled /t REG_DWORD /d 0 /f
reg add "HKLM\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server" /v Enabled /t REG_DWORD /d 0 /f
2.6. Apache Tomcat (Java JSSE)
Tomcatの設定ファイル "server.xml"の"Connector"要素において、 Tomcatのバージョンに依存して、 sslEnabledProtocols属性もしくはprotocols属性に 使用するプロトコルをSSLv3を除いたTLSv1、TLSv1.1、TLSv1.2 を設定することにより、 SSLv3での接続を無効化することができます。 (参考 [4])
Tomcatバージョン | 設定例 |
---|---|
5.0.x、5.5.x、6.0.0〜6.0.37 |
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="false" keystoreFile="/etc/tomcat/server.jks" keystorePass="password" sslProtocol="TLS" protocols="TLSv1,TLSv1.1,TLSv1.2"/> |
6.0.39〜、7.0.x、8.0.x |
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="false" keystoreFile="/etc/tomcat/server.jks" keystorePass="password" sslProtocol="TLS" sslEnabledProtocols="TLSv1,TLSv1.1,TLSv1.2"/> |
2.7. Node.js
Tomcat同様これもインターネット直出ししている事はないと思いますが
以下の実装例のようにsecureOptionsでSSLv2,SSLv3を使用しないよう設定が可能です。
(参考
[6])
var constants = require('constants')
, https = require('https')
, path = require('path')
, tls = require('tls')
, fs = require('fs');
https.createServer({
secureProtocol: 'SSLv23_method',
secureOptions: (constants.SSL_OP_NO_SSLv3 | constants.SSL_OP_NO_SSLv2),
cert: fs.readFileSync(path.join(__dirname, 'ssl', 'server.crt')),
key: fs.readFileSync(path.join(__dirname, 'ssl', 'server.key')),
}, function (req, res) {
res.end('works');
}).listen(443);
2.8. (追記)IBM HTTP Server
アドバイザリ
が公開されています。httpd.confで以下のように設定し、サーバーを再起動します。
<VirtualHost *:443>
SSLEnable
SSLProtocolDisable SSLv2 SSLv3
その他の設定
</VirtualHost>
2.9. (追記)Amazon Web Services
AWSから セキュリティアドバイザリが公開されており何度もアップデートされています。 利用するサービスによってそれぞれ対策が必要です。
サービス | 対応策 |
---|---|
Linux AMI | 2014年10月16日7時にOpenSSL関連の全てのパッケージにPOODLE対応済の ものにアップアップデートしています。ウェブサーバー等の設定は、 それぞれ実施する必要があります。 |
ELB | 2014年10月15日9時以降に生成であればデフォルトSSLv3無効。 それ以前に生成であれば以下を実施します。 ELB Manegement Console>EC2>Load Balancers> Change>Predefined Security Policyの選択を確認> ELBSecurityPolicy-2014-10を選択>Save>個々のリスナで設定を繰り返す |
CloudFront |
Management Console>Distribution Settings>
Edit>General Tab>Custom SSL Client Support>
>Only Client that Suppot SNI>Yes Edit>SSLv3無効化
TLS_FALLBACK_SCSVオプションについては10月20日の週にサポート予定。 |
2.10. その他のサーバー
その他のサーバーについては、以下を参考にしてみてください。
- ask ubuntu: How do I patch/workaround SSLv3 POODLE vulnerability (CVE--2014--3566)? - とても参考になります。Postfix SMTP, Sendmail, Dovecot, Courier-imap, HAProxy Server, OpenVPN, Puppetなど、特にメール関連サーバーはこちらを参考にしてみて下さい。
2.11. SSLv3 を無効化するリスク
現在サポートされているPCやスマートフォンのブラウザではTLSv1.0以降 がサポートされているので問題にならないと思いますが、 例えば、2007年秋以前のdocomoのガラケーやSONY PS3では、SSLv3しかサポート していないことを実機で確認しています。 古いガラケー、ゲーム機、組込み機器に対応するウェブサーバーを 運用する場合には、接続できずクレームになる可能性もありますので、 クライアント側の対応環境を確認すると良いと思います。
また、ウェブサーバーをAPIで利用する場合にも、どのような環境、 言語実装を使うかで問題があるケースがありますので、 確認しておくと良いと思います。TwitterやFacebookも API利用されているためにトラブルになったそうです。
2.12. (追記)OpenLDAP
OpenLDAPについてはslapd.confを以下のように設定します。 (参考 [?])
バージョン 2.4.36以降の場合上記以前のバージョンの場合にはアップデートの必要があります。
TLSProtocolMin 3.1
バージョン 2.4.14〜2.4.35の場合
TLSProtocolMin 769
3. 諸般の事情で SSLv3 を有効にせざるを得ない場合
一般的なブラウザに関してはSSLv3を無効化する方向で進んでおり、 ウェブサイトでもSSLv3を無効化するのが、正しい対応だと思いますが、 古い環境をサポートしなければならないために、SSLv3を有効に しておかなければならないケースもあると思います。 3章では、SSLv3をサポートしなければならないケースでの、 脆弱性の緩和策について説明したいと思います。
3.1. 暗号スイート設定で対処する方法
POODLE脆弱性はSSLv3とブロック暗号のCBCブロックモードを使用した 場合に影響があるので、暗号スイートとして以下を選択することで 問題を緩和することができます。
- 認証付暗号化方式(AEAD)であるGCMブロックモードの暗号スイートを使用する
- ストリーム暗号(RC4,ChaChaなど)を使用する
RC4ストリーム暗号は、現実的な時間内に部分的に解読することが 可能な危殆化した暗号で使用すべきでないとされていますが、 POODLE脆弱性は適用条件や解読にかかる手間が極端に少ないので、 Triple DESをCBCモードで使うよりもRC4の方が、まだ安全であると 言えます。
従って、- TLS_RSA_WITH_3DES_EDE_CBC_SHA を含む全ての暗号スイートを無効化
- その上で、TLS_RSA_WITH_RC4_128_SHA のみを有効化
- 同時に新しめのクライアントも環境もサポートしたいならGCMの暗号スイートを有効にする
ただし、マイクロソフト製品では2014年8月のアップデート以降、RC4は無効になっていますので、 Windows系のサーバー機を使用する場合には、Apacheなど他のサーバーを使う必要があるでしょう。
3.2. TLS_FALLBACK_SCSVを使う方法(現時点で極めて限定的)
SSL/TLSで通信を開始した直後はTLSv1.0以上で問題ない接続であったとしても、 ある種の攻撃により脆弱なSSLv3.0以下にダウングレードさせる攻撃があります。
これを、防ぐための新しく提案されている仕組みが TLS_FALLBACK_SCSV オプションを使う方法です。これをサーバーとクライアントの双方が サポートする場合、TLSからSSLv3.0以下に強制ダウングレードさせることは できなくなります。
ただ、これをサポートしている環境は現時点(2014.10.18)では非常に限定的です。
- クライアント
- Google Chromeのみ
- サーバー
- 最新の2014.10.15リリースのOpenSSL 1.0.1j/1.0.0o/0.9.8zcを利用するApache,Nginx,Lighttpdなどのサーバー
- Google提供のサービス(2014年2月頃からサポートしていたらしい)
- CBCブロック暗号モードをどうしても使う必要があり、
- TLSで最初接続できた利用者にはSSLv3ダウングレードせず安全に使用して欲しい。
- SSLv3で接続してきた利用者にはリスクを承知でCBCモードで接続してもらってもよい。
4. (追記)対応策(案)の整理
自分なりにケース毎の対応策(案)を整理してみました。よかったら参考にしてください。
ケース | 対応策(案) | |
---|---|---|
(ケース1) 利用者が古い環境や古い言語のAPIを使っておらず、 SSLv3.0の停止が可能な場合 | (対策1)2章に従いサーバーは全てSSLv3無効化する。 | |
(ケース2) 利用者環境の判断がつかない場合や、 TLSとSSLv3.0の双方をサポートしなければならない場合や、 幅広い環境をサポートしなければならない場合 | (ケース2-1) 追加の開発/構築/リソースが認められる場合 | (対策2-1) レガシー向けのSSLv3専用(RC4)とモダン用(SSLv3無効)にサーバー/コンテンツを分ける。 結局対策は(対策1)(対策3)の別建て併用のようになる。 |
(ケース2-2) 追加リソースが認められず、ある程度リスク受容しても サーバーば1台で設定を工夫して提供する必要がある場合、 かつ認証暗号(GCM等)が使えるサーバーの場合 | (対策2-2) プロトコル設定でSSLv3とTLSv1.xの双方を有効とし、 暗号スイートでCBCブロックモードを全て取りやめ、 暗号スイート設定でGCMとRC4のみを有効にする。 RC4の解読リスクは受容する。 | |
(ケース2-3) SSLv3ダウングレード攻撃のみ対策する | (対策2-3) OpenSSL系であればTLS_FALLBACK_SCSVオプションをサポートする最新のOpenSSL(10/15に公開された1.0.1j/v1.0.0o/v0.9.8zcで対応)にアップデートし、必要に応じウェブサーバーもリビルドする。 TLSからSSLv3にダウングレードされる攻撃からのみ利用者を保護し、最初からSSLv3で接続してくる利用者は保護せずリスク受容して頂く。 | |
(ケース2-4) POODLE攻撃は、例えばRC4ストリーム暗号アルゴリズムの危殆化に比べて、 軽微な攻撃と捉える場合や、何も対策が打てない場合 | (対策2-4) 対策として何もしない。 サーバー管理側も利用者も双方リスク受容する。 可能なら利用者に対してクライアントの設定でSSLv3を無効にしてもらうように啓蒙する。 | |
(ケース3) レガシーな、 古い環境や古い言語のAPIを使っており、SSLv3.0のみサポートすればよい場合で、かつ サーバーやクライアントが認証暗号を使えない場合 | (対策3) SSLv3のみを有効とし、暗号スイートはRC4のものを使う。 RC4の解読リスクは受容する。 |
表について、少し補足したいと思います。対策としては、SSLv3を無効にするのが基本的な対策となりますが、SSLv3を残しておく必要がある場合に、幾つかのケースに分類してみました。
一番良いのは、やはり(ケース2-1)のようにTLSv1.xのサーバーと、SSLv3のサーバーとを分ける事であるように思います。最近のウェブアプリケーションではHTML5、JavaScript、CSSなどリッチコンテンツが増えて、そうしたモダンなブラウザ向けのサービスと、SSLv3しかサポートしないサービスとを分けることで、互いに安全に利用することができます。
どうしても1台のサーバーでモダンなブラウザのユーザと、SSLv3のみにしか対応しないユーザに 対応する必要がある場合には、(ケース2-2)のように、CBCモードを使うことをあきらめ、モダンなブラウザユーザは TLSv1.xをGCMモードで接続することになり、GCMモードに対応できないユーザは、弱い暗号であるRC4のリスクを 受容して利用してもらうことになります。例えば、以下の順序で暗号スイートを設定するのが良いでしょう。
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA
- TLS_RSA_WITH_AES_128_GCM_SHA256
- TLS_RSA_WITH_AES_256_GCM_SHA384
- TLS_RSA_WITH_AES_128_GCM_SHA
- TLS_RSA_WITH_AES_256_GCM_SHA
- TLS_RSA_WITH_RC4_128_SHA
5. おわりに
以上、SSLサーバーでPOODLE脆弱性対応をする方法について、いろいろなサーバー 毎にまとめてみました。参考になればうれしいです。今日は、こんなとこで。
SSLv3のパディングについては、いろいろ勉強したので、近いうちに記事にできるといいなと思っています。
追記・修正
- 2014.10.19 IBM HTTP Server, AWS, 対応策(案)の整理について追記しました。
- 2014.10.22 OpenLDAP ついて追記しました。
- 2014.10.28 Apache Tomcatの設定についてコメント頂きましたので、 実際に調査をし、 記述を修正しました。コメント頂きましたuraさん、takeshiさん、Youngdong.lee さん、ありがとうございました。
Courier-imapのマニュアルや設定サンプルにはtypoがあって、
TLS_PROTOCOL=TLS1
TLS_STARTTLS_PROTOCOL=TLS1
という記述は実際は、
TLS_PROTOCOL=TLSv1
TLS_STARTTLS_PROTOCOL=TLSv1
とする必要があります。さらに判別できない文字列が指定された場合は"SSL23"扱いになるため、上記を"TLS1"と記述するとSSLv3でも接続できてしまいます。
公式サイトからダウンロードしたcourier-imap 4.15のソースとopensslコマンドで確認しました。
リンク先のコメント欄が閉じられてしまっているようなので、こちらにコメントさせていただきました。