Logjam Attack対策

HTTPSというかTLSで新しく見つかった脆弱性が話題になっている?ので対策をしてみた。

Diffie-Hellman 鍵交換に関する脆弱性に対する攻撃の様でLogjam Attackという名前だそうです。
TLS接続の暗号強度を512にビット下げられてしまうので盗聴されやすくなるとのこと。
SSL/TLSをサポートするトップ100万ドメインのうち、約18%にこの脆弱性があるということなので結構影響範囲大きそうです。

取り敢えずDHグループを2048ビット以上で作成するのとDHE_EXPORTを拒否にすれば良いようです。

ただし、Apache2.4系やNginxは素直にそれで良いようですが、Apache2.2はダメそう。
Apache2.2の場合は以下のようにDHEを無効にするという対策にしました。
SSLCipherSuite HIGH:AES128:!DHE:!3DES:!aNULL
(個別指定していたのをやめて整理しました)

Guide to Deploying Diffie-Hellman for TLSのServer Testで合格すれば目的達成。

Server Test 1
未対策のApacheはたいていこんな感じ。これまでの主な脆弱性に対応していればDHE_EXPORTはNOの筈ですがDHEが1024ビット、ブラウザ側も未対策なので不合格。

Server Test 2
某都市銀行のウェブサーバの対応状況。DHE_EXPORTはNO、DHEも使わない設定ですがブラウザ側にECDHEを使わせるようになっていないのでこのテストでは不合格という扱い。

Server Test 3
Apache2.2で対応した結果。DHEがNOでブラウザ側にECDHEを使わせるようになっているのでこのテストでは合格です。

Server Test 4
Apache2.4やNginxで対応した結果。2048ビットのDHEに対応しブラウザ側にECDHEを使わせるようになっているのでこのテストでは合格です。

関連記事の ApacheでSSL (その勘所)NginxでSSL (その勘所) も更新しています。

Webフォントの使い方 (CORSのあたり)

この「がとらぼ」でも使っていますが、Webフォント。ウェブサイトを見る側の端末に入っていないフォントをウェブサイト作成者の意図どおりに表示させられるので作る側の自己満足ではあるんだけど良いです。
日本では英数字のフォントやアイコンフォントのFont Awesomeなど何気に多く使われてはいますが、日本語Webフォントは自由に再配布できるのが殆ど無いとか漢字を含むとファイルサイズが大きいというのがネックになってそれほどは普及していません。

「がとらぼ」で使っているのはGoogleが配布している日本語WebフォントのNoto Sans。そのままだとファイルサイズが巨大すぎて表示がとんでもなく遅くなるので第一水準の漢字に丸めたサブセット版。500KBくらいでかなり小さめ。これの作り方は検索するといっぱい出てきます。

で、表示のさせ方ですが、とりあえずcssを以下のようにすると表示できます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
@font-face {
    font-family: 'Noto Sans';
    font-style: normal;
    font-weight: normal;
    src: url('/fonts/NotoSansJapanese-DemiLight.woff') format('woff'),
    url('/fonts/NotoSansJapanese-DemiLight.eot') format('embedded-opentype');
}

body {
	font-family: 'Noto Sans', sans-serif;
}

1〜7行目でフォントの読み込み指定。2行目で「Noto Sans」という名前(任意)を宣言して5,6行目でフォントの置き場所の指定。この場合は ドキュメントルートから見て/fontsフォルダ下にフォントファイルがある。
9〜11行目がbodyでfont-familyを指定。ここで指定するフォント名は2行目のものと対応させる。sans-serifはNoto Sansが読めなかった場合のため予備指定。

「がとらぼ」のような単独サイトならこんな感じで終わり。

いくつかサイトを持っているとWebフォントを1サイトで配布して他のサイトでもそれを使いたい場合がある。管理楽だし。
仮にblue.example.comを持っていてそこにWebフォントを置きred.example.comでそのWebフォントを利用したいとなったとき。
上のcssでいえば5行目をsrc: url('http://blue.example.com/fonts/NotoSansJapanese-DemiLight.woff') format('woff'),のようにしてやれば良い。(6行目も同様に)
また、httpsとhttpの両対応ということであればURLはhttp://などと決め打ちにせずにhttp: https:のどちらも無しのスラッシュ2本からで指定します。

1
src: url('//blue.example.com/fonts/NotoSansJapanese-DemiLight.woff') format('woff')

ところで、red.example.comでは指定した筈のblue.example.comに置いてあるWebフォントは多くの場合は表示されません。

最近のブラウザにはCross-Origin Resource Sharing(CORS)の仕組みが入っていて基本的には他所のサイトのリソースを混ぜて処理しないようになっているからです。(安全の為?)
これをなんとか表示させたいということであればWebフォントが置かれているblue.example.comの側に他のホスト(ドメイン)から使って良いという許可を与えてやります。

たとえばウェブサーバがnginxの場合はこんな感じ。

1
2
3
4
5
6
7
8
9
server {
    listen 80;
    server_name blue.example.com;
    root /hoge/path;

    location ~ \.(ttf|ttc|otf|eot|woff)$ {
        add_header Access-Control-Allow-Origin *;
    }
}

6行目のttf,ttc,otf,eot,woffはWebフォントの拡張子。Webフォント以外にcssなどを足すのもアリ。この拡張子のファイルがリクエストされた場合は7行目の最後のワイルドカードで何処のサイトからでも利用OK.

当然ですがこれだとred.example.comだけでなく他所のどこからでも利用できてしまうので非常によろしくありません。cssのような比較的小さなファイルならともかくWebフォントはサイズでかいので特に嫌です。利用してよいホスト/ドメインだけに制限します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
server {
    listen 80;
    server_name blue.example.com;
    root /hoge/path;

    set $cors ";";;
    if ($http_origin ~* (red\.example\.com|.*\.example\.org)) {
        set $cors "true";
    }

    location ~ \.(ttf|ttc|otf|eot|woff)$ {
        if ($cors = "true") {
            add_header Access-Control-Allow-Origin "$http_origin";
            add_header Cache-Control "max-age=2592000, public";
        }
    }
}

7行目に許可するホスト名,ドメイン名などを列記します。(A|B|C)という書き方。上の例ではred.example.comの他にexample.orgの各ホスト。
ピリオドはエスケーブしてやる必要があるのでホスト名とドメインを繋ぐピリオドなどの前にはバックスラッシュ(半角の¥)が必要。ワイルドカードの「.*」にはバックスラッシュ不要で、ピリオド無しのアスタリスクだけだとたぶんnginx起動時に構文エラーになります。
14行目はキャッシュ期間の指定です。秒指定なので2592000は30日となります。キャッシュ期間を指定し忘れるとWebフォントが使われない場合が多々発生します。

他の方法もありますがこれが一番単純で解りやすいかと。

Up