12
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Cisco WLC と FreeRADIUS を利用した EAP-TLS認証

Last updated at Posted at 2019-01-03

はじめに

このエントリはCiscoWLCとFreeRADIUSを利用した、EAP-TLS認証の手順について記載します。

更新履歴

2020/1/29 パラメータの表記を一部修正しました。

対象機器および環境

  • Cisco Virtual Wireless LAN Controller (Ver.8.2.x)
  • CentOS7(7.6.1810)
  • OpenSSL(1.0.2k)
  • FreeRADIUS(3.0.13)

このエントリを読むとできること

  • OpenSSLで構築したルートCAと中間CAを利用して
  • サーバ証明書とクライアント証明書を発行して
  • WLCとFreeRADIUSを利用した
  • EAP-TLS認証ができるようになる

はず。

関連するエントリ

OpenSSLでプライベート認証局の構築(ルートCA、中間CA)
Cisco WLCにSSIDを作成する(802.1X/PSK) コマンド編+よくつかうコマンド
CentOS7で各種ネットワークサービスを基本設定したメモ(dhcp/radius/proxy/tftp/syslog)

前提条件

サーバ証明書はルートCAから発行
クライアント証明書は中間CAから発行
という構成にしています。

クライアントの増減のたびにルートCAのお世話になるのはどうも違うと思います。中間CAにクライアント証明書の発行の権限を持たせるイメージです。

手順

Cisco WLCの設定

WLCでは以下で作成したような802.1X認証用のSSID作成などが必要です。
Cisco WLCにSSIDを作成する(802.1X/PSK) コマンド編+よくつかうコマンド
Cisco WLCにSSIDを作成する(802.1X/PSK)

チェーン証明書の作成

FreeRADIUSでの証明書配置や、WindowsクライアントのためのPKCS#12作成時に利用するための、チェーン証明書(ルートCA+中間CA)を先に作成しておく。

cd /opt/pki/
openssl x509 -in RootCA/RootCA_crt.pem -out chainCA_crt.pem
openssl x509 -in InterCA/InterCA_crt.pem >> chainCA_crt.pem

FreeRADIUSサーバ

VMnetserv01 というホスト名に対して発行しています。

サーバ証明書発行

RootCAの秘密鍵のパスワードは、 前回構築 した文字列をそのまま利用しています。

(VMnetserv01というサーバに対して発行するので、新規ディレクトリを作成する)
mkdir -p /opt/pki/Server/VMnetserv01
cd /opt/pki/Server/VMnetserv01

(パスワード無し秘密鍵とCSRを同時に発行しています)
openssl req  -new \
 -out VMnetserv01_csr.pem \
 -newkey rsa:2048 \
 -nodes \
 -keyout VMnetserv01_key.pem \
 -subj "/C=JP/ST=Tokyo/O=EXAMPLE/CN=VMnetserv01.example.net"

(RootCAで署名します)
cd /opt/pki/RootCA
openssl ca -config ../configs/openssl_sign.cnf -batch -extensions v3_server \
 -out ../Server/VMnetserv01/VMnetserv01_crt.pem \
 -in  ../Server/VMnetserv01/VMnetserv01_csr.pem \
 -cert RootCA_crt.pem \
 -keyfile RootCA_key.pem \
 -passin pass:rootcaprivkeypass

(余計な文字列を取り除きます)
cd /opt/pki/Server/VMnetserv01
openssl x509 -in VMnetserv01_crt.pem -out VMnetserv01_crt.pem

FreeRADIUS設定

(証明書を収容するディレクトリを新規に作成します)
mkdir -p /etc/raddb/p2certs

(DHファイルの作成)
openssl dhparam -5 -out /etc/raddb/p2certs/dh 1024

(各証明書を配置していきます)
cp /opt/pki/Server/VMnetserv01/VMnetserv01_key.pem /etc/raddb/p2certs
cp /opt/pki/Server/VMnetserv01/VMnetserv01_crt.pem /etc/raddb/p2certs
cp /opt/pki/chainCA_crt.pem /etc/raddb/p2certs

 
証明書ディレクトリの設定を変更

/etc/raddb/radiusd.conf
-----8<-----snip-----8<-----
certdir = ${confdir}/p2certs
cadir   = ${confdir}/p2certs
-----8<-----snip-----8<-----

 
eapセクション中の default_eap_type が md5となっていても、tlsとなっていても、デフォルトのEAPが通らない場合はNAKレスポンス中にステーション側のEAP方式を返すらしいので、RADIUSサーバ側で適切なEAP方式を試行するっぽい。

/etc/raddb/mods-available/eap
-----8<-----snip-----8<-----
eap {
        #default_eap_type = md5
        default_eap_type = tls

        tls-config tls-common {
                #private_key_password = whatever
                #private_key_file = ${certdir}/server.pem
                #certificate_file = ${certdir}/server.pem
                #ca_file = ${cadir}/ca.pem
                private_key_file = ${certdir}/VMnetserv01_key.pem
                certificate_file = ${certdir}/VMnetserv01_crt.pem
                ca_file = ${cadir}/chainCA_crt.pem
	}
}
-----8<-----snip-----8<-----

クライアント

クライアント証明書発行

InterCAの秘密鍵のパスワードは、 前回構築 した文字列をそのまま利用しています。

(Client01というクライアントに対して発行するので、新規ディレクトリを作成する)
mkdir -p /opt/pki/Client/Client01
cd /opt/pki/Client/Client01

(パスワード無し秘密鍵とCSRを同時に発行しています)
openssl req -new \
 -out Client01_csr.pem \
 -newkey rsa:2048 \
 -nodes \
 -keyout Client01_key.pem \
 -subj "/C=JP/ST=Tokyo/O=EXAMPLE/CN=Client01.example.net"

(InterCAで署名します)
cd /opt/pki/InterCA
openssl ca -config ../configs/openssl_sign.cnf  -batch -extensions v3_client \
 -out ../Client/Client01/Client01_crt.pem \
 -in  ../Client/Client01/Client01_csr.pem \
 -cert InterCA_crt.pem \
 -keyfile InterCA_key.pem \
 -passin pass:intercaprivkeypass

(余計な文字列を取り除きます)
cd /opt/pki/Client/Client01
openssl x509 -in Client01_crt.pem -out Client01_crt.pem

(Windowsで利用するため、PKCS#12:秘密鍵と証明書をまとめたファイルを作成します)
(-passoutでエクスポート用パスワード "exportpass" を与えています)
openssl pkcs12 -export \
 -inkey Client01_key.pem \
 -in Client01_crt.pem \
 -certfile ../../chainCA_crt.pem \
 -out Client01_crt.p12 \
 -passout pass:exportpass

Windowsクライアント設定

作成したp12ファイルをWindowsクライアントへ転送する。
(画面ではWinSCPを利用)
image.png
 

転送したp12ファイルをダブルクリック
image.png
 

そのまま「次へ」をクリック
image.png

 
p12エクスポート時に設定した-passout の文字列を入力する。
(先ほどの例では "exportpass" という文字列)
image.png

 
そのまま「次へ」をクリック
image.png

 
そのまま「完了」をクリック
image.png

 
問題なくインポートできれば、以下のメッセージが表示される。
image.png

 
Ctrl+Rキーで「mmc」と入力して「OK」をクリック
image.png

 
「ファイル」→「スナップインの追加と削除」をクリック
image.png

 
最下段の「証明書」をダブルクリックして「コンピュータアカウント」を選択し、「次へ」をクリック
image.png

 
「ローカルコンピュータ」を選択し「完了」をクリック
image.png

 
選択されたスナップインに 証明書(ローカルコンピュータ)があることを確認して「OK」をクリック
image.png

 
左側メニューの「証明書」→「個人」→「証明書」をクリックし、作成したクライアント証明書が存在するか確認。
証明書をダブルクリックして、「証明書パス」のタブをクリック
証明書パスの画面で「×」印がついておらず、証明書の状態が「この証明書は問題ありません」となっているれば問題なく導入されている。
「OK」をクリックして、閉じる。
image.png

 
Ctrl+Rをクリックして、 control.exe /name Microsoft.NetworkAndSharingCenter と入力して、「OK」をクリック
image.png

 
中央付近の「新しい接続またはネットワークのセットアップ」をクリック
image.png

 
「ワイヤレスネットワークに手動で接続します」を選択して「次へ」をクリック
image.png

 
「ネットワーク名」にSSIDを入力(例ではIntraGeneral)
自動的に開始するかどうかはお好みで。
SSIDをステルス化していれば「ネットワークがブロードキャストを行っていない~~」にチェックを入れ「次へ」をクリック
image.png

 
「接続の設定を変更します」をクリック
image.png

 
表示される画面で「セキュリティ」タブをクリック
ネットワークの認証方法の選択を「Microsoft: スマートカードまたはその他の証明書」を選択し、隣の「設定」をクリック
image.png

信頼されたルート証明機関にルートCAのチェックを入れる(例ではexample Root CA)
「新しいサーバまたは信頼された証明機関を~~」にチェックを入れ「OK」をクリック
image.png

 
もとの画面に戻るので、「詳細設定」をクリックすると、下記の画面が表示される。
「802.1Xの設定」タブで、認証モードを指定するにチェックを入れ、プルダウンメニュから「コンピュータの認証」を選択し、「OK」をクリック
image.png

その後、ほかの設定画面も「OK」「閉じる」ですべて閉じる。
ここまででWindowsの無線設定が完了しました。

動作確認

最初にRADIUSサーバをデバッグモードで起動させてみて、問題なく認証されるかを確認する。

(radiusサービスが停止していることを確認する)
# systemctl status radiusd
● radiusd.service - FreeRADIUS high performance RADIUS server.
   Loaded: loaded (/usr/lib/systemd/system/radiusd.service; enabled; vendor preset: disabled)
   Active: inactive (dead) since 木 2019-01-03 19:38:23 JST; 3h 39min ago
 Main PID: 6132 (code=exited, status=0/SUCCESS)

 1月 03 19:38:23 VMnetserv01.example.net systemd[1]: Stopping FreeRADIUS high performance RADIUS server....
 1月 03 19:38:23 VMnetserv01.example.net systemd[1]: Stopped FreeRADIUS high performance RADIUS server..
Warning: Journal has been rotated since unit was started. Log output is incomplete or unavailable.
#

(radiusサーバをデバックモードで起動しておく)
# radiusd -X
(ばばばー、って表示されるあ、そのまま流しておく)

 
タスクトレイから先ほど作成したSSIDを選択し、接続する。
image.png

デバッグモードで起動したradiusのログの最後のほうに、
Login OK: [host/Client01.example.net] (なんちゃら~~)
と表示されていれば、認証できている。

 
認証後は、設定したSSIDに接続されているはず
image.png

 
認証成功時のradiusログは以下のようなもの

(20) Received Access-Request Id 53 from 10.254.10.201:50312 to 10.254.10.251:1812 length 302
(20)   User-Name = "host/Client01.example.net"
(20)   Chargeable-User-Identity = 0xc9
(20)   Location-Capable = Civic-Location
(20)   Calling-Station-Id = "40-e2-30-af-55-79"
(20)   Called-Station-Id = "d4-a0-2a-11-d5-a0:IntraGeneral"
(20)   NAS-Port = 1
(20)   Cisco-AVPair = "audit-session-id=c90afe0a00000078b3192e5c"
(20)   Acct-Session-Id = "5c2e19b3/40:e2:30:af:55:79/168"
(20)   NAS-IP-Address = 10.254.10.201
(20)   NAS-Identifier = "VMwlc01"
(20)   Airespace-Wlan-Id = 1
(20)   Service-Type = Framed-User
(20)   Framed-MTU = 1300
(20)   NAS-Port-Type = Wireless-802.11
(20)   Tunnel-Type:0 = VLAN
(20)   Tunnel-Medium-Type:0 = IEEE-802
(20)   Tunnel-Private-Group-Id:0 = "4001"
(20)   EAP-Message = 0x020700060d00
(20)   State = 0x47ff5d6b42f8509cdd59458a7ab664e0
(20)   Message-Authenticator = 0x4e520e371412faf3d280e4d28edc2686
(20) session-state: No cached attributes
(20) # Executing section authorize from file /etc/raddb/sites-enabled/default
(20)   authorize {
(20)     policy filter_username {
(20)       if (&User-Name) {
(20)       if (&User-Name)  -> TRUE
(20)       if (&User-Name)  {
(20)         if (&User-Name =~ / /) {
(20)         if (&User-Name =~ / /)  -> FALSE
(20)         if (&User-Name =~ /@[^@]*@/ ) {
(20)         if (&User-Name =~ /@[^@]*@/ )  -> FALSE
(20)         if (&User-Name =~ /\.\./ ) {
(20)         if (&User-Name =~ /\.\./ )  -> FALSE
(20)         if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+)\.(.+)$/))  {
(20)         if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+)\.(.+)$/))   -> FALSE
(20)         if (&User-Name =~ /\.$/)  {
(20)         if (&User-Name =~ /\.$/)   -> FALSE
(20)         if (&User-Name =~ /@\./)  {
(20)         if (&User-Name =~ /@\./)   -> FALSE
(20)       } # if (&User-Name)  = notfound
(20)     } # policy filter_username = notfound
(20)     [preprocess] = ok
(20)     [chap] = noop
(20)     [mschap] = noop
(20)     [digest] = noop
(20) suffix: Checking for suffix after "@"
(20) suffix: No '@' in User-Name = "host/Client01.example.net", looking up realm NULL
(20) suffix: No such realm "NULL"
(20)     [suffix] = noop
(20) eap: Peer sent EAP Response (code 2) ID 7 length 6
(20) eap: No EAP Start, assuming it's an on-going EAP conversation
(20)     [eap] = updated
(20) files: users: Matched entry DEFAULT at line 1
(20) files: users: Matched entry DEFAULT at line 1
(20) files: users: Matched entry DEFAULT at line 1
(20)     [files] = ok
(20)     [expiration] = noop
(20)     [logintime] = noop
(20)     [pap] = noop
(20)   } # authorize = updated
(20) Found Auth-Type = eap
(20) # Executing group from file /etc/raddb/sites-enabled/default
(20)   authenticate {
(20) eap: Expiring EAP session with state 0x47ff5d6b42f8509c
(20) eap: Finished EAP session with state 0x47ff5d6b42f8509c
(20) eap: Previous EAP request found for state 0x47ff5d6b42f8509c, released from the list
(20) eap: Peer sent packet with method EAP TLS (13)
(20) eap: Calling submodule eap_tls to process data
(20) eap_tls: Continuing EAP-TLS
(20) eap_tls: Peer ACKed our handshake fragment.  handshake is finished
(20) eap_tls: [eaptls verify] = success
(20) eap_tls: [eaptls process] = success
(20) eap: Sending EAP Success (code 3) ID 7 length 4
(20) eap: Freeing handler
(20)     [eap] = ok
(20)   } # authenticate = ok
(20) # Executing section post-auth from file /etc/raddb/sites-enabled/default
(20)   post-auth {
(20)     update {
(20)       No attributes updated
(20)     } # update = noop
(20)     [exec] = noop
(20)     policy remove_reply_message_if_eap {
(20)       if (&reply:EAP-Message && &reply:Reply-Message) {
(20)       if (&reply:EAP-Message && &reply:Reply-Message)  -> FALSE
(20)       else {
(20)         [noop] = noop
(20)       } # else = noop
(20)     } # policy remove_reply_message_if_eap = noop
(20)   } # post-auth = noop
(20) Login OK: [host/Client01.example.net] (from client example.net port 1 cli 40-e2-30-af-55-79)
(20) Sent Access-Accept Id 53 from 10.254.10.251:1812 to 10.254.10.201:50312 length 0
(20)   Tunnel-Type = VLAN
(20)   Tunnel-Medium-Type = IEEE-802
(20)   Tunnel-Private-Group-Id = "1"
(20)   MS-MPPE-Recv-Key = 0x2fffb3dd4351fa83c019ab3eaa5451386a3deb0c2cebbda985094dd7818f0e13
(20)   MS-MPPE-Send-Key = 0x1ed298b804eecfe8303731cc5a186df7bd56b678170d6f475b77acbca86cc57e
(20)   EAP-Message = 0x03070004
(20)   Message-Authenticator = 0x00000000000000000000000000000000
(20)   User-Name = "host/Client01.example.net"
(20) Finished request

ここまでできたら、radiusサーバを ctrl+C で停止させる。

# systemctl enable radiusd
# systemctl start radiusd
# systemctl status radiusd
● radiusd.service - FreeRADIUS high performance RADIUS server.
   Loaded: loaded (/usr/lib/systemd/system/radiusd.service; enabled; vendor preset: disabled)
   Active: active (running) since 木 2019-01-03 23:48:58 JST; 11s ago
  Process: 28658 ExecStart=/usr/sbin/radiusd -d /etc/raddb (code=exited, status=0/SUCCESS)
  Process: 28654 ExecStartPre=/usr/sbin/radiusd -C (code=exited, status=0/SUCCESS)
  Process: 28653 ExecStartPre=/bin/chown -R radiusd.radiusd /var/run/radiusd (code=exited, status=0/SUCCESS)
 Main PID: 28661 (radiusd)
   CGroup: /system.slice/radiusd.service
           mq28661 /usr/sbin/radiusd -d /etc/raddb

 1月 03 23:48:58 VMnetserv01.example.net systemd[1]: Starting FreeRADIUS high performance RADIUS server....
 1月 03 23:48:58 VMnetserv01.example.net systemd[1]: Started FreeRADIUS high performance RADIUS server..

WLCからは以下のように見えます

(Cisco Controller) >show client summary ssid ip username


Number of Clients................................ 3

MAC Address       AP Name          Status        SSID                 IP Address                       Username
----------------- ---------------- ------------- -------------------- -------------------------------- ------------------

40:e2:30:af:55:79 APbranch01-01F01  Associated   IntraGeneral         10.101.19.1                       host/Client01.example.net
50:dc:e7:b3:bf:34 APhq01-01F01      Associated   IntraStrict          10.1.19.2                         N/A
ac:63:be:92:9d:f9 APhq01-01F01      Associated   IntraStrict          10.1.19.5                         N/A

(Cisco Controller) >

さいごに

感想

証明書失効時の動作検証などできていないため、後日整理したいと思います。

おまけ

チェーン証明書、サーバ証明書、クライアント証明は、以下の一連のテキストコピペで発行できます。

前回作成のルートCAと中間CA のあとに発行すると、その環境のままサーバ証明書とクライアント証明書が発行できます。

cd /opt/pki/
openssl x509 -in RootCA/RootCA_crt.pem -out chainCA_crt.pem
openssl x509 -in InterCA/InterCA_crt.pem >> chainCA_crt.pem

mkdir -p /opt/pki/Server/VMnetserv01
cd /opt/pki/Server/VMnetserv01
openssl req  -new -out VMnetserv01_csr.pem -newkey rsa:2048 -nodes -keyout VMnetserv01_key.pem -subj "/C=JP/ST=Tokyo/O=EXAMPLE/CN=VMnetserv01.example.net"
cd /opt/pki/RootCA
openssl ca -config ../configs/openssl_sign.cnf -out ../Server/VMnetserv01/VMnetserv01_crt.pem -in ../Server/VMnetserv01/VMnetserv01_csr.pem -cert RootCA_crt.pem -keyfile RootCA_key.pem -passin pass:rootcaprivkeypass -batch -extensions v3_server
cd /opt/pki/Server/VMnetserv01
openssl x509 -in VMnetserv01_crt.pem -out VMnetserv01_crt.pem

mkdir -p /opt/pki/Client/Client01
cd /opt/pki/Client/Client01
openssl req -new -out Client01_csr.pem -newkey rsa:2048 -nodes -keyout Client01_key.pem -subj "/C=JP/ST=Tokyo/O=EXAMPLE/CN=Client01.example.net"
cd /opt/pki/InterCA
openssl ca -config ../configs/openssl_sign.cnf -out ../Client/Client01/Client01_crt.pem -in ../Client/Client01/Client01_csr.pem -cert InterCA_crt.pem -keyfile InterCA_key.pem -passin pass:intercaprivkeypass -batch -extensions v3_client
cd /opt/pki/Client/Client01
openssl x509 -in Client01_crt.pem -out Client01_crt.pem
openssl pkcs12 -export -inkey Client01_key.pem -in Client01_crt.pem -certfile ../../chainCA_crt.pem -out Client01_crt.p12 -passout pass:exportpass

12
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?