家ではなく会社や学校等の WiFi を使用する場合、WiFi が Pre-Shared Key ( PSK ) を使う方法 ( WPA2 Personal )ではなく、 ID とパスワードを使って接続する方式 ( WPA2 Enterprise や WPA2-EAP と呼ばれるもの)になっていることがあります。今日は WPA2-EAP な WiFi に Raspberry Pi 3 をつなげようとしたら意外と苦労することが分かったのでその顛末をメモ。
† 結論から述べると
今回の成果物は以下の gist に纏めておきました。
まず、追加でいろいろインストールしたりしないといけないので、有線 LAN 接続しておきましょう。
無線 LAN のために有線 LAN 接続しないといけないということでのっけから矛盾していますが、背に腹は代えられません。
あきらめてください。
Raspbian が buster の場合には、後述する wpa_supplicant のバグにより接続できないことがあるようなので、これを回避するために wpa_supplicant を 2.9 にアップグレードしておきます。その後、スクリプトによる wpa_supplicant.conf を生成するという流れになります。
これらの手順については以下のコマンドを使えば一撃で実施できるようにしておきました。
# upgrade wpa_supplicant to 2.9
curl -s https://gist.githubusercontent.com/hsur/aeb97d134b218019f9f7f3b538348f50/raw/wpa_supplicant_upgrade.sh | bash
# create wpa_supplicant.conf
curl -s https://gist.githubusercontent.com/hsur/aeb97d134b218019f9f7f3b538348f50/raw/raspi_enterprise_wifi_setup.sh | bash
後者の raspi_enterprise_wifi_setup.sh の方は SSID:
, Username:
, Password:
というプロンプトが出るので、これらの情報を入力すると /etc/wpa_supplicant/wpa_supplicant.conf
に完全な設定ファイルが生成されるようになっています。Password については入力内容はエコーバック(画面表示)されませんので入力間違いに注意してください。
加えて、生成される設定ファイルは TLSv1.0、TLSv1.1 を許容するようになっています(デフォルトで buster の場合は TLSv1.2 以上のみに制限されています)。これが嫌な場合 /etc/wpa_supplicant/wpa_supplicant.conf
の tls_disable_tlsv1_0=0 tls_disable_tlsv1_1=0
の部分を =1
に変更してから sudo systemctl restart dhcpcd
を実行してください。
† 対象とする環境
今回の対象の環境は Raspberry Pi 3B+、Raspbian buster です。
標準でインストールされている wpa_supplicant
は v2.8-devel
になっています。
$ sudo cat /etc/os-release | head -n 1
PRETTY_NAME="Raspbian GNU/Linux 10 (buster)"
$ cat /proc/cpuinfo | tail -n4
Hardware : BCM2835
Revision : a020d3
Serial : 000000000a99ed45
Model : Raspberry Pi 3 Model B Plus Rev 1.3
$ /sbin/wpa_supplicant -v
wpa_supplicant v2.8-devel
Copyright (c) 2003-2019, Jouni Malinen <j@w1.fi> and contributors
† wpa_supplicant v2.8-devel の問題
今回、一番参ったのが wpa_supplicant v2.8-devel の問題です。
国内であまり指摘している人がいないので、WiFi や RADIUS サーバのベンダー依存なのかもしれません。
Raspbian buster 上で /etc/wpa_supplicant/wpa_supplicant.conf
を正しく設定したとしても、以下のような見慣れない kernel のエラーメッセージが出力されます。
$ journalctl -xe
Oct 21 12:51:44 hostname dhcpcd[2949]: wlan0: carrier acquired
Oct 21 12:51:44 hostname kernel: ------------[ cut here ]------------
Oct 21 12:51:44 hostname kernel: WARNING: CPU: 2 PID: 2930 at drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c:5453 brcmf_cfg80211_set_pmk+0x74/0x88 [brcmfmac]
Oct 21 12:51:44 hostname kernel: Modules linked in: cmac bnep hci_uart btbcm bluetooth ecdh_generic ecc 8021q garp stp llc spidev brcmfmac brcmutil sha256_generic cfg80211 raspberrypi_hwmon bcm2835_codec(C) rfkill v4l2_mem2mem bcm2835_v4l2(C) bcm2835_isp(C) bcm2835_mmal_vchiq(C) videobuf2_vmalloc videobuf2_dma_contig videobuf2_memops videobuf2_v4l2 videobuf2_common snd_bcm2835(C) i2c_bcm2835 snd_pcm videodev mc snd_timer snd vc_sm_cma(C) spi_bcm2835 uio_pdrv_genirq uio fixed i2c_dev ip_tables x_tables ipv6
Oct 21 12:51:44 hostname kernel: CPU: 2 PID: 2930 Comm: wpa_supplicant Tainted: G WC 5.10.63-v7+ #1456
Oct 21 12:51:44 hostname kernel: Hardware name: BCM2835
Oct 21 12:51:44 hostname kernel: Backtrace:
Oct 21 12:51:44 hostname kernel: [<809f0cd8>] (dump_backtrace) from [<809f1068>] (show_stack+0x20/0x24)
Oct 21 12:51:44 hostname kernel: r7:ffffffff r6:00000000 r5:60000013 r4:80fe5e54
Oct 21 12:51:44 hostname kernel: [<809f1048>] (show_stack) from [<809f5278>] (dump_stack+0xcc/0xf8)
Oct 21 12:51:44 hostname kernel: [<809f51ac>] (dump_stack) from [<8011eca0>] (__warn+0xfc/0x114)
Oct 21 12:51:44 hostname kernel: r10:83a6dcb0 r9:00000009 r8:7f3348b8 r7:0000154d r6:00000009 r5:7f3348b8
Oct 21 12:51:44 hostname kernel: r4:7f363f14 r3:80f05050
Oct 21 12:51:44 hostname kernel: [<8011eba4>] (__warn) from [<809f16b4>] (warn_slowpath_fmt+0x70/0xd8)
Oct 21 12:51:44 hostname kernel: r7:0000154d r6:7f363f14 r5:80f05008 r4:00000000
Oct 21 12:51:44 hostname kernel: [<809f1648>] (warn_slowpath_fmt) from [<7f3348b8>] (brcmf_cfg80211_set_pmk+0x74/0x88 [brcmfmac])
Oct 21 12:51:44 hostname kernel: r9:865101c0 r8:86510000 r7:81457800 r6:83a0a02c r5:83a6dbc4 r4:81457800
Oct 21 12:51:44 hostname kernel: [<7f334844>] (brcmf_cfg80211_set_pmk [brcmfmac]) from [<7f2621a8>] (nl80211_set_pmk+0x124/0x240 [cfg80211])
Oct 21 12:51:44 hostname kernel: r5:8e68e800 r4:80f05008
Oct 21 12:51:44 hostname kernel: [<7f262084>] (nl80211_set_pmk [cfg80211]) from [<808ed05c>] (genl_rcv_msg+0x1c0/0x370)
Oct 21 12:51:44 hostname kernel: r9:81016540 r8:8e6673c0 r7:8e68e800 r6:80f05008 r5:7f2b511c r4:00000000
Oct 21 12:51:44 hostname kernel: [<808ece9c>] (genl_rcv_msg) from [<808ea940>] (netlink_rcv_skb+0xc8/0x120)
Oct 21 12:51:44 hostname kernel: r10:80f05008 r9:00000000 r8:0000004c r7:83a20800 r6:808ece9c r5:80f05008
Oct 21 12:51:44 hostname kernel: r4:8e6673c0
Oct 21 12:51:44 hostname kernel: [<808ea878>] (netlink_rcv_skb) from [<808eb1cc>] (genl_rcv+0x34/0x44)
Oct 21 12:51:44 hostname kernel: r8:8e464584 r7:8e6673c0 r6:0000004c r5:8e6673c0 r4:8101d194
Oct 21 12:51:44 hostname kernel: [<808eb198>] (genl_rcv) from [<808e9fd8>] (netlink_unicast+0x1a8/0x258)
Oct 21 12:51:44 hostname kernel: r5:8e464400 r4:816b8000
Oct 21 12:51:44 hostname kernel: [<808e9e30>] (netlink_unicast) from [<808ea29c>] (netlink_sendmsg+0x214/0x468)
Oct 21 12:51:44 hostname kernel: r10:00000000 r9:0000004c r8:8e464400 r7:8e6673c0 r6:80f05008 r5:83a6df40
Oct 21 12:51:44 hostname kernel: r4:00000008
Oct 21 12:51:44 hostname kernel: [<808ea088>] (netlink_sendmsg) from [<80862d68>] (sock_sendmsg+0x44/0x54)
Oct 21 12:51:44 hostname kernel: r10:83a6dde4 r9:00000000 r8:81f6c500 r7:80f05008 r6:00000000 r5:81f6c500
Oct 21 12:51:44 hostname kernel: r4:83a6df40
Oct 21 12:51:44 hostname kernel: [<80862d24>] (sock_sendmsg) from [<808633b0>] (____sys_sendmsg+0x200/0x22c)
Oct 21 12:51:44 hostname kernel: r5:00000000 r4:83a6df40
Oct 21 12:51:44 hostname kernel: [<808631b0>] (____sys_sendmsg) from [<80864f00>] (___sys_sendmsg+0x7c/0xa8)
Oct 21 12:51:44 hostname kernel: r10:00000128 r9:00000000 r8:00000000 r7:81f6c500 r6:00000000 r5:83a6df40
Oct 21 12:51:44 hostname kernel: r4:80f05008
Oct 21 12:51:44 hostname kernel: [<80864e84>] (___sys_sendmsg) from [<80865340>] (__sys_sendmsg+0x60/0x9c)
Oct 21 12:51:44 hostname kernel: r9:83a6c000 r8:80100204 r7:81f6c500 r6:00000000 r5:7ed1dfc0 r4:80f05008
Oct 21 12:51:44 hostname kernel: [<808652e0>] (__sys_sendmsg) from [<80865398>] (sys_sendmsg+0x1c/0x20)
Oct 21 12:51:44 hostname kernel: r7:00000128 r6:007fa1b0 r5:00826550 r4:007fa228
Oct 21 12:51:44 hostname kernel: [<8086537c>] (sys_sendmsg) from [<80100040>] (ret_fast_syscall+0x0/0x28)
Oct 21 12:51:44 hostname kernel: Exception stack(0x83a6dfa8 to 0x83a6dff0)
Oct 21 12:51:44 hostname kernel: dfa0: 007fa228 00826550 00000004 7ed1dfc0 00000000 00000000
Oct 21 12:51:44 hostname kernel: dfc0: 007fa228 00826550 007fa1b0 00000128 76ed5000 ffffffff 00000001 00000004
Oct 21 12:51:44 hostname kernel: dfe0: 0000006c 7ed1df78 76eba5bc 76a1e970
Oct 21 12:51:44 hostname kernel: ---[ end trace 77dc1bc11f46b1bc ]---
Oct 21 12:51:44 hostname dhcpcd[2949]: wlan0: IAID 00:00:00:00
Oct 21 12:51:44 hostname dhcpcd[2949]: wlan0: adding address fe80::0000:0000:0000:0000
Oct 21 12:51:44 hostname avahi-daemon[335]: Joining mDNS multicast group on interface wlan0.IPv6 with address fe80::0000:0000:0000:0000.
Oct 21 12:51:44 hostname avahi-daemon[335]: New relevant interface wlan0.IPv6 for mDNS.
Oct 21 12:51:44 hostname avahi-daemon[335]: Registering new address record for fe80::0000:0000:0000:0000 on wlan0.*.
Oct 21 12:51:45 hostname dhcpcd[2949]: wlan0: soliciting an IPv6 router
Oct 21 12:51:45 hostname dhcpcd[2949]: wlan0: soliciting a DHCP lease
Oct 21 12:51:48 hostname dhcpcd[2949]: wlan0: carrier lost
------(繰り返し)------
ちょっと衝撃的なログですが、これを元に検索したら Raspbian のトラッカーに以下の議論を発見。
もしこの情報がなかったら解決できませんでした。
以下のスクリプトは wpa_supplicant 2.9 を /usr/local/sbin
にソースからコンパイルしてインストールします。
# upgrade wpa_supplicant to 2.9
curl -s https://gist.githubusercontent.com/hsur/aeb97d134b218019f9f7f3b538348f50/raw/wpa_supplicant_upgrade.sh | bash
これが完了すると以下のように 2.9 が使えるようになっているはずです。
$ /usr/local/sbin/wpa_supplicant -v
wpa_supplicant v2.9
Copyright (c) 2003-2019, Jouni Malinen <j@w1.fi> and contributors
† TLSv1.0 の問題
2つめの難関は RADIUS サーバの TLS のバージョンの問題。
今回のサーバは少し古めなのか、TLSv1.0 にする必要がありました。
Raspbian buster の OpenSSL はデフォルトで TLSv1.2 が最小バージョンになっていますので、この場合は wpa_supplicant が以下のような感じで認証に失敗してしまいます。
$ sudo /usr/local/sbin/wpa_supplicant -c/etc/wpa_supplicant/wpa_supplicant.conf -iwlan0 -Dnl80211,wext
Successfully initialized wpa_supplicant
wlan0: Trying to associate with SSID 'AAA'
wlan0: Associated with 00:00:00:00:00:00
wlan0: CTRL-EVENT-EAP-STARTED EAP authentication started
wlan0: CTRL-EVENT-SUBNET-STATUS-UPDATE status=0
wlan0: CTRL-EVENT-REGDOM-CHANGE init=COUNTRY_IE type=COUNTRY alpha2=JP
wlan0: CTRL-EVENT-EAP-PROPOSED-METHOD vendor=0 method=25
wlan0: CTRL-EVENT-EAP-METHOD EAP vendor 0 method 25 (PEAP) selected
SSL: SSL3 alert: write (local SSL3 detected an error):fatal:protocol version
OpenSSL: openssl_handshake - SSL_connect error:1425F102:SSL routines:ssl_choose_client_version:unsupported protocol
wlan0: CTRL-EVENT-EAP-FAILURE EAP authentication failed
wlan0: Authentication with 00:00:00:00:00:00 timed out.
wlan0: CTRL-EVENT-DISCONNECTED bssid=00:00:00:00:00:00 reason=3 locally_generated=1
wlan0: CTRL-EVENT-SSID-TEMP-DISABLED id=0 ssid="AAA" auth_failures=1 duration=10 reason=AUTH_FAILED
wlan0: CTRL-EVENT-REGDOM-CHANGE init=CORE type=WORLD
wlan0: CTRL-EVENT-REGDOM-CHANGE init=USER type=COUNTRY alpha2=JP
wlan0: CTRL-EVENT-SSID-REENABLED id=0 ssid="AAA"
これについては対応バージョンを1つずつ下げて、TLSv1.0 まで有効化した場合に、以下のように接続が成功するようになりました。
$ sudo /usr/local/sbin/wpa_supplicant -c/etc/wpa_supplicant/wpa_supplicant.conf -iwlan0 -Dnl80211,wext
Successfully initialized wpa_supplicant
wlan0: Trying to associate with SSID 'AAA'
wlan0: Associated with 00:00:00:00:00:00
wlan0: CTRL-EVENT-EAP-STARTED EAP authentication started
wlan0: CTRL-EVENT-SUBNET-STATUS-UPDATE status=0
wlan0: CTRL-EVENT-REGDOM-CHANGE init=COUNTRY_IE type=COUNTRY alpha2=JP
wlan0: CTRL-EVENT-EAP-PROPOSED-METHOD vendor=0 method=25
wlan0: CTRL-EVENT-EAP-METHOD EAP vendor 0 method 25 (PEAP) selected
wlan0: CTRL-EVENT-EAP-PEER-CERT depth=0 subject='/C=JP/L=Default City/O=Default Company Ltd/CN=host.example.jp' hash=0000000000000000000000000000000000000000000000000000000000000000
wlan0: CTRL-EVENT-EAP-PEER-CERT depth=0 subject='/C=JP/L=Default City/O=Default Company Ltd/CN=host.example.jp' hash=0000000000000000000000000000000000000000000000000000000000000000
EAP-MSCHAPV2: Authentication succeeded
EAP-TLV: TLV Result - Success - EAP-TLV/Phase2 Completed
wlan0: CTRL-EVENT-EAP-SUCCESS EAP authentication completed successfully
wlan0: CTRL-EVENT-CONNECTED - Connection to 00:00:00:00:00:00 completed [id=0 id_str=]
この部分の調整については /etc/wpa_supplicant/wpa_supplicant.conf
の tls_disable_tlsv1_0=0 tls_disable_tlsv1_1=0
の部分を =1
に変更してから sudo systemctl restart dhcpcd
を実行しながら環境に合わせて調整してください。不必要に対応バージョンを下げるのはセキュリティ的に好ましくありません。
これらを考慮しながら、良い感じで wpa_supplicant.conf
を生成してれるスクリプトがなかったので今回はこれらの作業をまとめてやってくれるスクリプトを書いてみました。
# create wpa_supplicant.conf
curl -s https://gist.githubusercontent.com/hsur/aeb97d134b218019f9f7f3b538348f50/raw/raspi_enterprise_wifi_setup.sh | bash
これが頭書の後半部分のスクリプトになります。
久しぶりにちょっと頭を使いました。