hgot07 Hotspot Blog

主に無線LANや認証連携などの技術についてまとめるブログです。ネコは見る専。

【注意喚起】FreeRADIUSの設定は気を付けないとEAP-TLSに大穴が開く (EAP-TLSを使っていなくても)

タイトルの通りなんですが、その昔これを見つけた時はヘンな汗が噴き出ましたよ。

eapol_testを使ったEAP-TLS認証

eapol_testを使ったEAP-TLS認証

SUCCESS... (;゚∀゚)

 

自分はEAP-TLSを使わないからといっても、デフォルトで穴が開くので要注意です。

 

不具合の内容

以下の条件がすべて満たされているとき、同一CAが発行・署名したクライアント証明書を用いて、第三者によるEAP-TLS認証が成功します。無線LANに不正に接続できたりします。

  1. FreeRADIUSでPEAP, EAP-TTLSなどを使っている。
  2. Public CAから発行されたサーバ証明書を使っている (Let's EncryptでもUPKIでも、何でもよい)
  3. EAP-TLSを運用していないのに、その機能が無効になっていない (FreeRADIUSのデフォルト)。
  4. FreeRADIUSの設定ファイル mods-enabled/eap の中で、EAP-TLSを設定する
     tls { } セクションに tls = tls-common が指定されている  (デフォルト) 。
  5. クライアント証明書の属性値を検証する機能が無効になっている  (デフォルト)。

企業内で使うセキュリティがガッチリ管理された無線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では結構前に注意喚起の文書を出したので、きちんと対策されてい……るといいなぁ。