タイトルの通りなんですが、その昔これを見つけた時はヘンな汗が噴き出ましたよ。
SUCCESS... (;゚∀゚)
自分はEAP-TLSを使わないからといっても、デフォルトで穴が開くので要注意です。
不具合の内容
以下の条件がすべて満たされているとき、同一CAが発行・署名したクライアント証明書を用いて、第三者によるEAP-TLS認証が成功します。無線LANに不正に接続できたりします。
- FreeRADIUSでPEAP, EAP-TTLSなどを使っている。
- Public CAから発行されたサーバ証明書を使っている (Let's EncryptでもUPKIでも、何でもよい)
- EAP-TLSを運用していないのに、その機能が無効になっていない (FreeRADIUSのデフォルト)。
- FreeRADIUSの設定ファイル mods-enabled/eap の中で、EAP-TLSを設定する
tls { } セクションに tls = tls-common が指定されている (デフォルト) 。 - クライアント証明書の属性値を検証する機能が無効になっている (デフォルト)。
企業内で使うセキュリティがガッチリ管理された無線LANシステムでもなければ、今は端末にプリインストールされているCA証明書ストアを使うのが一般的でしょうから、結構アウトですよね。
検証方法 (悪用禁止)
サーバ証明書と同じパブリックCAから、クライアント証明書 (cert.pem) とその鍵 (privkey.pem) を入手しておきます。中間CA証明書をクライアント証明書の末尾にcatして、cert+.pem を作っておきます。
次のような eapol_test.conf を作成します。
network={
ssid="piyopiyo"
key_mgmt=WPA-EAP
eap=TLS
anonymous_identity="anonymous@example.com"
client_cert="cert+.pem"
private_key="privkey.pem"
private_key_passwd="<鍵のパスフレーズ>"
}
レルムは自分の環境に合わせます。
privkey.pem に鍵が付いていないなら、private_key_passwd="" とします。
いざ!
$ eapol_test -c eapol_test.conf -s testing123
eapol_test コマンドは、wpa_supplicant パッケージなどに入っています。
SUCCESS が出たら負けです。
なぜこうなるのか
FreeRADIUSの設定ファイル mods-enabled/eap の中に、tls-config tls-common { } セクションがあります。証明書類をここに設定しますが、サーバ認証ばかりではなく、EAP-TLSのクライアント認証にも、同じ設定が使われるのがデフォルトです。少し下の方に EAP-TLS の設定のための tls { } セクションがあり、そこに tls = tls-common と書かれています!
一応、tls-config tls-common { } の直前に、以下のような注意書きがあります。ちゃんと読んでいますよね?
# Note that you should NOT use a globally known CA here!
# e.g. using a Verisign cert as a "known CA" means that
# ANYONE who has a certificate signed by them can
# authenticate via EAP-TLS! This is likely not what you want.
ところで、最近のOSでは、安易にCA証明書をインストールさせない方針になっているようです。ネットで拾ってきたCA証明書を一般利用者がインストールするなんて、リスキーですからね。
というわけで、WPA2 Enterpriseを使う無線LANシステムでは、システムにプリインストールされているCA証明書ストアを使ってサーバ認証させるのが一般的になっています。上の注意書きは、この点で時代遅れで、不親切です。
一方で、EAP-TLSのクライアント認証は、クライアント証明書からルートCAにたどり着けるかという certification path validation が基本になっています。パブリックCAを使うと、第三者もログインできてしまいます。
一つの対策は、クライアント証明書の中身を検証するロジックを tls { } セクションの中で有効にすることです。でも、そもそも EAP-TLS を使う気のない管理者なら、こんなところまで見ないかもしれません。また、検証といっても、実際に何を検証すれば安全なのかという問題が残ります (証明書の意味が無くない?)。
有効な対策
そもそも、EAP-TLS を使わないなら、tls { } セクション全体をコメントアウトすればOKです。
EAP-TLS を使うなら、クライアント認証にはプライベートCAを使うでしょう。tls-common とは別に、例えば tls-auth を別途定義すればよいでしょう。
おしまい
ps
eduroam JPでは結構前に注意喚起の文書を出したので、きちんと対策されてい……るといいなぁ。