2020 年度 OSS リテラシー 3 : wi-fi (WPA2 Enterprise) の設定

校内ネットワークへの接続

松江高専の無線 LAN ネットワークに接続するために, WPA2 Enterprise の設定を行う.

なお, 以下では背景が灰色な部分は terminal 上でコマンドを実行することを意味する. 先頭が "$" の場合は一般ユーザ権限でのコマンド実行, 先頭が "#" の場合は管理者権限でのコマンド実行を意味する. sudo コマンドを使って管理者権限を使っていることに注意せよ. また, 括弧内は説明であり, ファイルに書き込む必要はないことに注意せよ.

注意事項 (Raspbian buster)

Raspbian buster では, ラズパイのオンボードの wifi モジュールでは WPA2 Enterprise での接続に失敗する. Raspbian の前のバージョン (jessie, strech, ...) では問題なかったのだが....

また, 手元の wifi の USB ドングル (ELECOM WDC-150SU2M) は, Raspbian buster の標準ドライバでは動かず, ドライバの入れ替えが必要になる. 本手順書の内容はラズパイのフォーラムの内容を元にしている.

前準備

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

インストール

必要なドライバをインストールする. カーネルのバージョンに合わせる必要があるため, まずはそれを確認する. この例では, カーネルのバージョンが 5.4.51, ビルド番号が 1333, アーキテクチャが ARM v7 であることがわかる.

$ uname -a

  Linux raspberrypi 5.4.51-v7+ #1333 SMP Tue Sep 24 18:45:11 BST 2019 armv7l GNU/Linux

次にドライバをダウンロードする. カーネルのバージョン, ビルド番号, アーキテクチャが一致するものを以下のディレクトリから探し出す.

<URL:http://downloads.fars-robotics.net/wifi-drivers/8188eu-drivers/>

上記のカーネルのバージョン, ビルド番号, アーキテクチャの場合には, 8188eu-5.4.51-v7-1333.tar.gz が必要なファイルであるので, それをダウンロードする.

$ mkdir src

$ cd src

$ wget http://downloads.fars-robotics.net/wifi-drivers/8188eu-drivers/8188eu-5.4.51-v7-1333.tar.gz

ファイルを解凍してインストールする.

$ tar zxvf 8188eu-5.4.51-v7-1333.tar.gz

  8188eu.ko
  8188eu.conf
  install.sh

$ sudo ./install.sh

  sudo install -p -m 644 8188eu.ko /lib/modules/5.4.51-v7+/kernel/drivers/net/wireless
  sudo depmod 5.4.51-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 となる).

個人のパスワードを平文で設定ファイルに書き込むのはセキュリティ的に問題がある. 暗号化したパスワードを設定ファイルに保存することにする.

$ read -s pass
  ********  (入力は見えない)

$ echo -n "$pass" | iconv -t utf16le | openssl md4

  (stdin)= YYYYYYYYYYYYYYYYYYYYYYYY

この (stdin)= の後に続く YYYYYYYYYYYYYYYYYYYYYYYY が暗号化したパスワードである. これを用いて無線 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 (上記の (stdio)= 以降の文字列のコピペ. 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
  }

再起動. 再起動の前に有線の LAN ケーブルを外しておくと良い.

$ 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 

[参考] 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               <= ココ!

[今年度はパス] 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 wpa_cli -i wlan0 reconfigure
    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