2019 年度 OSS リテラシー 3 : wi-fi (WPA2 Enterprise) の設定
校内ネットワークへの接続
松江高専の無線 LAN ネットワークに接続するために, WPA2 Enterprise の設定を行う.
なお, 以下では背景が灰色な部分は terminal 上でコマンドを実行することを意味する. 先頭が "$" の場合は一般ユーザ権限でのコマンド実行, 先頭が "#" の場合は管理者権限でのコマンド実行を意味する. sudo コマンドを使って管理者権限を使っていることに注意せよ. また, 括弧内は説明であり, ファイルに書き込む必要はないことに注意せよ.
注意事項 (Raspbian buster)
Raspbian buster では, ラズパイのオンボードの wifi モジュールでは WPA2 Enterprise での接続に失敗する. Raspbian の前のバージョン (jessie, strech, ...) では問題なかったのだが. どうやら wpa_supplicant 2.7 にバグがあるらしい.
また, 手元の wifi の USB ドングル (ELECOM WDC-150SU2M) は, Raspbian buster の標準ドライバでは動かず, ドライバの入れ替えが必要になる. 本手順書の内容はラズパイのフォーラムの内容を元にしている.
- <URL:https://www.raspberrypi.org/forums/viewtopic.php?p=462982>
- <URL:https://www.raspberrypi.org/forums/viewtopic.php?t=246587#p1506297>
前準備
ELECOM WDC-150SU2M を接続した状態でラズパイを起動する. 起動後, ELECOM WDC-150SU2M がインターフェイス wlan0, オンボードの wifi がインターフェイス wlan1 として認識される.
ifconfig コマンドで wifi インターフェイスが 2 つ存在することがわかる.
$ ifconfig ...(略)... wlan0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 ether bc:5c:4c:58:36:46 txqueuelen 1000 (イーサネット) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 wlan1: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 ether b8:27:eb:cb:6c:e4 txqueuelen 1000 (イーサネット) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
オンボードの wifi を無効化して再起動する.
$ sudo iwconfig wlan1 txpower off $ sudo reboot
再起動後に再度 ifconfig コマンドを実行すると, wifi のインターフェイスが wlan0 しか表示されていないことがわかる. 何も設定をしていないので, この段階では wlan0 に IP アドレスなどのネットワークパラメタは設定されていない.
$ ifconfig ...(略)... wlan0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 ether bc:5c:4c:58:36:46 txqueuelen 1000 (イーサネット) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
インストール
必要なドライバをインストールする. カーネルのバージョンに合わせる必要があるため, まずはそれを確認する. この例では, カーネルのバージョンが 4.19.75, ビルド番号が 1270, アーキテクチャが ARM v7 であることがわかる.
$ uname -a Linux raspberrypi 4.19.75-v7+ #1270 SMP Tue Sep 24 18:45:11 BST 2019 armv7l GNU/Linux
次にドライバをダウンロードする. カーネルのバージョン, ビルド番号, アーキテクチャが一致するものを以下のディレクトリから探し出す.
<URL:http://downloads.fars-robotics.net/wifi-drivers/8188eu-drivers/>
上記のカーネルのバージョン, ビルド番号, アーキテクチャの場合には, 8188eu-4.19.75-v7-1270.tar.gz が必要なファイルであるので, それをダウンロードする.
$ mkdir src $ wget http://downloads.fars-robotics.net/wifi-drivers/8188eu-drivers/8188eu-4.19.75-v7-1270.tar.gz
ファイルを解凍してインストールする.
$ tar zxvf 8188eu-4.19.75-v7-1270.tar.gz 8188eu.ko 8188eu.conf install.sh $ sudo ./install.sh sudo install -p -m 644 8188eu.ko /lib/modules/4.19.75-v7+/kernel/drivers/net/wireless sudo depmod 4.19.75-v7+ Reboot to run the driver. If you have already configured your wifi it should start up and connect to your wireless network. If you have not configured your wifi you will need to do that to enable the wifi.
メッセージにあるように, ドライバを有効にするためにリブートする.
$ sudo reboot
再起動後に lsmod コマンドを実行することで, 先にインストールしたドライバ (8188eu) が使われていることが確認できる.
$ lsmod | grep 8188 8188eu 1486848 0 cfg80211 614400 2 brcmfmac,8188eu
設定ファイルの作成と動作確認
無線 LAN 関係の設定ファイルは /etc/wpa_supplicant/wpa_supplicant.conf である. この設定ファイルをエディター (vi, nano, leafpad 等) で編集し, アクセスポイントの情報を追加する. なお, シェルにはタブ補完という便利機能があるので使ってみると良い (例えば, /e まで打ったところでタブを押すと /etc となる. /etc/wp まで打ったところでタブを押すと /etc/wpa_supplicant となる).
個人のパスワードを平文で設定ファイルに書き込むのはセキュリティ的に問題がある. 暗号化したパスワードを設定ファイルに保存することにする. パスワードの ntpassword hash を作るためには freeradius-utils パッケージをインストールしておく必要がある. freeradius-utils パッケージがインストールされているかは dpkg -l コマンドで確認することができる.
$ dpkg -l | grep freeradius-utils ii freeradius-utils 3.0.17+dfsg-1.1 armhf FreeRADIUS client utilities
もし, 上記のような表示がない (= インストールされていない) 場合には 以下のコマンドで必要なパッケージをインストールする.
$ sudo apt-get update $ sudo apt-get install freeradius-utils
暗号化したパスワードは smbencrypt コマンドで作成するのが簡単である. 出力のうち, NT Hash (ntpassword hash) と書かれた方の文字列 (以下の例では YYYYYYYYYYYYYYYYYYYYYYYY) だけをコピーしておく. かならず一般ユーザ権限 (ターミナルのプロンプトが $) で行うこと.
$ smbencrypt XXXXX (自分のパスワード) LM Hash NT Hash ----------------------- ------------------------- XXXXXXXXXXXXXXXXXXXXXX YYYYYYYYYYYYYYYYYYYYYYYY
上記の ntpassword hash を使って無線 LAN 関係の設定ファイルを書き換える. この機会に 5 棟全部の無線 LAN アクセスポイントも追加しておくと良いだろう.
$ sudo vi /etc/wpa_supplicant/wpa_supplicant.conf ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev update_config=1 country=JP network={ ssid="H510W_pub" key_mgmt=WPA-EAP eap=PEAP identity="jXXXX" (学生番号. ダブルクォーテーションで囲む) password=hash:YYYYYYYYYYYYYYYYYYYYYYYY (ntpassword hash のコピペ. hash: という文字列を付けるのを忘れずに. ダブルクォーテーションで囲まないこと) } network={ ssid="H520W_pub" key_mgmt=WPA-EAP eap=PEAP identity="jXXXX" password=hash:YYYYYYYYYYYYYYYYYYYYYYYY } network={ ssid="H530W_pub" key_mgmt=WPA-EAP eap=PEAP identity="jXXXX" password=hash:YYYYYYYYYYYYYYYYYYYYYYYY } network={ ssid="H540W_pub" key_mgmt=WPA-EAP eap=PEAP identity="jXXXX" password=hash:YYYYYYYYYYYYYYYYYYYYYYYY } network={ ssid="H550W_pub" key_mgmt=WPA-EAP eap=PEAP identity="jXXXX" password=hash:YYYYYYYYYYYYYYYYYYYYYYYY }
注意すべきは, ターミナルで実行したコマンドの履歴が残ることである. パスワードを打った履歴が残るのはまずいので, smbencrypt のコマンド履歴を削除することにする. history コマンドを実行すると今までに打ったコマンドが通し番号付きで表示される. history コマンドに -d オプションで通し番号を与えると, 履歴を消すことができる. なお, コマンド履歴は ~/.bash_history ファイルに記録されているので, 直接ファイルを編集して該当行を削除しても良い.
$ history ...(中略)... NN smbencrypt XXXXX (NN は通し番号, XXXXX はパスワード) ...(攻略)... $ history -d NN (NN は smbencrypt の通し番号) $ histoty ...(略).... (smbencrypt のコマンド履歴が消去されたことを確認)
再起動
$ sudo reboot
正しく設定できれば, 再起動することで校内の無線 LAN ネットワーク (H520W_pub, H530W_pub, H540W_pub) のいずれかに接続できる. ifconfig でネットワークパラメタを, iwconfig で wifi 関連のパラメタを確認できる.
$ ifconfig ...(略)... wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.163.64.185 netmask 255.255.255.0 broadcast 10.163.64.255 inet6 fe80::16d8:a409:bd12:9f61 prefixlen 64 scopeid 0x20<link> ether bc:5c:4c:58:36:46 txqueuelen 1000 (イーサネット) RX packets 27 bytes 6841 (6.6 KiB) RX errors 0 dropped 1 overruns 0 frame 0 TX packets 39 bytes 6111 (5.9 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 $ iwconfig wlan0 IEEE 802.11gn ESSID:"H540W_pub" Nickname:"<WIFI@REALTEK>" Mode:Managed Frequency:2.472 GHz Access Point: 6C:DD:30:3E:83:40 Bit Rate:72.2 Mb/s Sensitivity:0/0 Retry:off RTS thr:off Fragment thr:off Power Management:off Link Quality=39/100 Signal level=31/100 Noise level=0/100 Rx invalid nwid:0 Rx invalid crypt:0 Rx invalid frag:0 Tx excessive retries:0 Invalid misc:0 Missed beacon:0
トラブルシューティング
もしも無線 LAN に接続できない場合は, 設定ファイルが間違っている可能性が高い. 間違いを探すときは, 手動で以下の順にコマンドを実行すると良い. エラーの原因となる行番号が表示される.
wpa_supplicant のプロセス番号を調べる
$ pgrep wpa_supplicant 354 405 423
もし例のようにプロセス番号が表示されたらそれを KILL する. 表示がなければ次に進んで良い.
$ sudo kill -KILL 354 405 423
wpa_supplicant コマンドを実行する.
# wpa_supplicant -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf
wi-fi の再接続用スクリプト
ラズパイを長期間運用していると, wifi のアクセスポイントに接続できなくなることがある. そこで, 以下のような 1 分おきにネットワークの導通を確認し, 問題があれば wifi のインターフェイスを再起動 & wpa_supplicant を再起動するようなシェルスクリプトを バックグラウンドで動かすことにする. ネットワークの導通確認のために, 学内の DNS サーバに ping を打っている.
$ sudo -s # cd /root # vi wifi-reset.sh (以下のように書く) #!/bin/bash router_address="10.0.0.7" while : do ping -c 1 $router_address > /dev/null 2>&1 if [ $? -ne 0 ]; then sudo ifconfig wlan0 down sudo ifconfig wlan0 up sudo killall -HUP wpa_supplicant fi sleep 60 done
スクリプトのパーミッションを適切に.
# chmod 755 wifi-reset.sh
再起動した時に自動的に起動するように crontab に登録する. 起動直後に動かすと wlan0 が落ちっぱなしになることがあるので, sleep で 5 分ほど経ってから動かすようにしている.
# crontab -e (末尾に追加) @reboot sleep 300; /root/wifi-reset.sh
再起動
# reboot
プロセスが動いているか確認する
$ ps aux | grep wifi-reset.sh root 394 0.0 0.0 1940 364 ? Ss 08:09 0:00 /bin/sh -c /root/wifi-reset.sh root 395 0.0 0.2 6172 2464 ? S 08:09 0:00 /bin/bash /root/wifi-reset.sh root 674 0.0 0.0 5992 468 pts/0 S+ 08:15 0:00 grep wifi-reset.sh
[参考] killall の挙動
killall -HUP wpa_supplicant コマンドの挙動を確認する. 現在の状況を確認するとアクセスポイント H540W_pub に接続している.
$ iwconfig wlan0 wlan0 IEEE 802.11gn ESSID:"H540W_pub" Nickname:"<WIFI@REALTEK>" Mode:Managed Frequency:2.472 GHz Access Point: 6C:DD:30:3E:83:40 Bit Rate:72.2 Mb/s Sensitivity:0/0 Retry:off RTS thr:off Fragment thr:off Encryption key:****-****-****-****-****-****-****-**** Security mode:open Power Management:off Link Quality=38/100 Signal level=30/100 Noise level=0/100 Rx invalid nwid:0 Rx invalid crypt:0 Rx invalid frag:0
Tx excessive retries:0 Invalid misc:0 Missed beacon:0
設定ファイルから H540W_pub の情報をコメントアウトしてみる.
$ sudo vi /etc/wpa_supplicant/wpa_supplicant.conf (H540W_pub をコメントアウト)
killall -HUP wpa_supplicant を実行すると, wpa_supplicant が再起動し, wifi に 再接続される. 以下の例では H550W_pub に接続していることがわかる.
$ sudo killall -HUP wpa_supplicant $ iwconfig wlan0 wlan0 IEEE 802.11bgn ESSID:"H550W_pub" Nickname:"<WIFI@REALTEK>" Mode:Managed Frequency:2.412 GHz Access Point: 6C:DD:30:3D:AE:E0 Bit Rate:72.2 Mb/s Sensitivity:0/0 Retry:off RTS thr:off Fragment thr:off Encryption key:****-****-****-****-****-****-****-**** Security mode:open Power Management:off Link Quality=96/100 Signal level=26/100 Noise level=0/100 Rx invalid nwid:0 Rx invalid crypt:0 Rx invalid frag:0 Tx excessive retries:0 Invalid misc:0 Missed beacon:0
[参考] wpa_supplicant のエラーメッセージ
オンボード wifi
オンボードの wifi モジュールで WPA2-EAP を使おうとすると, 以下のようなメッセージが出て つながらない. 設定ファイルの内容は上記のものから変えていない.
$ dmesg ...(略)... [ 56.347064] ------------[ cut here ]------------ [ 56.347261] WARNING: CPU: 0 PID: 400 at drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c:5126 brcmf_cfg80211_set_pmk+0x6c/0x80 [brcmfmac] [ 56.347285] Modules linked in: bnep hci_uart btbcm serdev bluetooth ecdh_generic 8021q garp stp llc evdev joydev brcmfmac brcmutil sha256_generic raspberrypi_hwmon cfg80211 hwmon snd_bcm2835(C) rfkill bcm2835_codec(C) snd_pcm v4l2_mem2mem bcm2835_v4l2(C) bcm2835_mmal_vchiq(C) snd_timer v4l2_common videobuf2_dma_contig videobuf2_vmalloc snd videobuf2_memops videobuf2_v4l2 videobuf2_common videodev media vc_sm_cma(C) fixed uio_pdrv_genirq uio ip_tables x_tables ipv6 [ 56.347519] CPU: 0 PID: 400 Comm: wpa_supplicant Tainted: G WC 4.19.75-v7+ #1270 [ 56.347524] Hardware name: BCM2835 [ 56.347554] [<80111fcc>] (unwind_backtrace) from [<8010d544>] (show_stack+0x20/0x24) [ 56.347572] [<8010d544>] (show_stack) from [<80819bc0>] (dump_stack+0xd4/0x118) [ 56.347591] [<80819bc0>] (dump_stack) from [<80120a88>] (__warn+0x104/0x11c) [ 56.347607] [<80120a88>] (__warn) from [<80120bd8>] (warn_slowpath_null+0x50/0x58) [ 56.347773] [<80120bd8>] (warn_slowpath_null) from [<7f534ae0>] (brcmf_cfg80211_set_pmk+0x6c/0x80 [brcmfmac]) [ 56.348158] [<7f534ae0>] (brcmf_cfg80211_set_pmk [brcmfmac]) from [<7f2b9cfc>] (nl80211_set_pmk+0x160/0x26c [cfg80211]) [ 56.348370] [<7f2b9cfc>] (nl80211_set_pmk [cfg80211]) from [<80753918>] (genl_rcv_msg+0x244/0x464) [ 56.348390] [<80753918>] (genl_rcv_msg) from [<80752910>] (netlink_rcv_skb+0x104/0x138) [ 56.348407] [<80752910>] (netlink_rcv_skb) from [<807536c4>] (genl_rcv+0x34/0x44) [ 56.348423] [<807536c4>] (genl_rcv) from [<80752030>] (netlink_unicast+0x1b0/0x234) [ 56.348439] [<80752030>] (netlink_unicast) from [<80752454>] (netlink_sendmsg+0x2dc/0x364) [ 56.348458] [<80752454>] (netlink_sendmsg) from [<806e2514>] (sock_sendmsg+0x24/0x34) [ 56.348477] [<806e2514>] (sock_sendmsg) from [<806e2d60>] (___sys_sendmsg+0x214/0x228) [ 56.348493] [<806e2d60>] (___sys_sendmsg) from [<806e3e34>] (__sys_sendmsg+0x60/0xa0) [ 56.348507] [<806e3e34>] (__sys_sendmsg) from [<806e3e90>] (sys_sendmsg+0x1c/0x20) [ 56.348522] [<806e3e90>] (sys_sendmsg) from [<80101000>] (ret_fast_syscall+0x0/0x28) [ 56.348529] Exception stack(0xb40bffa8 to 0xb40bfff0) [ 56.348541] ffa0: 0125c228 012a3048 00000004 7e8fafc0 00000000 00000000 [ 56.348554] ffc0: 0125c228 012a3048 0125c1b0 00000128 76ee9000 ffffffff 00000001 00000004 [ 56.348562] ffe0: 0000006c 7e8faf78 76ece5bc 76a32980 [ 56.348571] ---[ end trace 779b5250b7312465 ]---
ELECOM WDC-150SU2M
lsusb コマンドで Elecom の USB ドングルが接続されていることがわかる.
$ lsusb Bus 001 Device 004: ID 056e:4008 Elecom Co., Ltd Bus 001 Device 005: ID 046d:c534 Logitech, Inc. Unifying Receiver Bus 001 Device 006: ID 0424:7800 Standard Microsystems Corp. Bus 001 Device 003: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub Bus 001 Device 002: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
lsusb コマンドに -t オプションをつけると利用しているドライバがわかる. この例ではデバイス 4 (= Elecom) のドライバとして r8188eu が使われているのがわかる.
$ lsusb -t /: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=dwc_otg/1p, 480M |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M |__ Port 1: Dev 3, If 0, Class=Hub, Driver=hub/3p, 480M |__ Port 2: Dev 5, If 1, Class=Human Interface Device, Driver=usbhid, 12M |__ Port 2: Dev 5, If 0, Class=Human Interface Device, Driver=usbhid, 12M |__ Port 1: Dev 6, If 0, Class=Vendor Specific Class, Driver=lan78xx, 480M |__ Port 3: Dev 4, If 0, Class=Vendor Specific Class, Driver=r8188eu, 480M
すでに動いているプロセスを KILL して, wpa_supplicant コマンドを実行しなおす. ドライバの初期化に失敗することがわかる.
$ sudo killall wpa_supplicant $ sudo wpa_supplicant -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf Successfully initialized wpa_supplicant nl80211: Could not configure driver mode nl80211: deinit ifname=wlan0 disabled_11b_rates=0 wlan0: Failed to initialize driver interface <= ココ!