2016-02-26

OpenBlocks IoT Family で一時的な Wi-Fi クライアント接続を行う

Web ユーザーインターフェースの設定を変更せず、一時的に Wi-Fi クラアントとして OpenBlocks IoT Family を既設の Wi-Fi ネットワークへ接続する方法を紹介します。

OBDN 技術ブログによる動作検証は、該当するデバイスやソフトウェアの動作について、保証およびサポートを行うものではありません。
内容に関するご指摘などありましたら、ブログ記事の担当までご連絡下さい。

はじめに


OpenBlocks IoT Family(以下OpenBlocks)の初期設定では、Wi-Fi インターフェースはアクセスポイントとして動作するようになっています。常時 3G や LTE のモバイル回線を利用する場合にこの設定は便利ですが、メンテナンス等の目的で一時的に Wi-Fi クライアントとして既設の Wi-Fi ネットワーク環境に接続したいことがあります。

もちろん Web ユーザーインターフェース経由で設定を変更しても良いのですが、設定を戻すのを忘れて別のネットワーク環境に移った場合、Web ユーザーインターフェースへアクセスできず、設定の初期化が必要になるなど後々少々面倒くさいことになります。

そこで Web ユーザーインターフェースの設定を変更せずに、一時的に OpenBlocks を Wi-Fi クライアントとして既設ネットワークへ接続する方法を紹介します。

Wi-Fi のアクセスポイントモードとクライアントモード


はじめに Wi-Fi のアクセスポイントになっている OpenBlocks がどういう状態であるかを整理してみましょう。ネットワークインターフェース(以下I/F)としては次のような状態になっています。
  • Wi-Fi I/F はアクセスポイントモードに設定
  • Wi-Fi I/F で DHCP のサービスが稼働
したがって次の三つを行えば、アクセスポイントモードからクライアントモードへ切り替えて、既設の Wi-Fi ネットワークに接続できます。
  1. DHCP サービスを停止
  2. Wi-Fi I/F をアクセスポイントモードからクライアントモードへ変更
  3. Wi-Fi クライアントとして必要な設定の投入
これらを順に説明します。

DHCP サービスの停止


DHCP サービスを停止するにはサービスを実施しているプロセスの dhcpd を停止するだけです。dhcpd については単純にkillで問題ありません。

# killall dhcpd

Wi-Fi I/F をアクセスポイントモードからクライアントモードへ変更


Wi-Fi I/F をアクセスポイントをクライアントのモードへ切り替えるのは、少し複雑です。というのも Wi-Fi I/F のドライバーがカーネルモジュールになっていて、モジュールのロード時にモード設定を行っているからです。また Wi-Fi アクセスポイントをサービスする hostapd というプロセスも動いています。手順としては次のようになります。
  1. hostapd の停止
  2. Wi-Fi I/F の停止
  3. ドライバーのモードの切り替え
  4. Wi-Fi I/F の起動
具体的には次の各コマンドを実行します。

# killall hostapd
# ifdown wlan0
# modprobe -r bcm4334x
# modprobe bcm4334x op_mode=1
# ifup wlan0

Wi-Fi クライアントとして必要な設定


以上まで完了したら、後は一般的な Linux を Wi-Fi に接続する場合と同じ手順となります。Wi-Fi クライアントとして必要な設定を行うには、次の2つの手順を踏むことになります。
  1. 既設 Wi-Fi 環境への接続
  2. DHCP クライアントとして設定
既設 Wi-Fi 環境へ接続するためには、SSID(ESSID)とパスフレーズを用意してwpa_supplicant を設定します。wpa_supplicant の設定の詳細は省略しますが、以下の例では /var/run/wpa.conf ファイルで Wi-Fi 接続の設定を行っています。最後に dhclient プログラムを起動すれば完了です。

# cat /var/run/wpa.conf
ctrl_interface=/var/run/wpa_supplicant
network={
        ssid="WIFISSID"
        scan_ssid=1
        key_mgmt=WPA-PSK
        psk="PASSWORD"
}
# wpa_supplicant -s -B -P /var/run/wpa_supplicant.wlan0.pid ¥
        -i wlan0 -D nl80211,wext -c /var/run/wpa.conf
# dhclient -v -pf /run/dhclient.wlan0.pid ¥
        -lf /var/run/dhclient.wlan0.leases wlan0

以上で Wi-Fi クライアントへの切り替えは完了です。この作業では何ら設定を保存していないため次に OpenBlocks を再起動した場合は本来の設定が有効になり、Wi-Fi I/F はアクスセスポイントとして動作します。

Wi-Fi クライアント設定のシェルスクリプト


上記に紹介した作業を毎回手作業で実施するには手順が多すぎますので、これらを実施するシェルスクリプトを最後に紹介します。

#!/bin/sh
#
# OpenBlocks IoT familyでWebのユーザーインターフェースの設定を変更せず
# 一時的にWi-Fiをクライアント設定に変更するシェルスクリプト
#
# このスクリプト中でsleep 1を多用しているのは、立て続けにコマンドを起
# するとうまく動かないものがあるため、待ち時間を確保している

export PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# 次の2行はWi-Fi環境に合わせて設定する
SSID=WIFISSID # Wi-Fi接続先のSSID
WKEY=PASSWORD # Wi-Fi接続先のパスフレーズ

IF=wlan0 # 無線I/F名 OpenBlocksの場合wlan0
WPACONF=/var/run/wpa.conf # wpa_supplicantの設定ファイル名

# Wi-Fi I/Fのモード切り替え
killall dhcpd hostapd ; sleep 1
ifdown wlan0 ; sleep 1
modprobe -r bcm4334x ; sleep 1
modprobe bcm4334x op_mode=1 ; sleep 1
ifup wlan0 ; sleep 1

# /etc/network/interfaces の記載によって
# ifupで付加される余計なIPアドレスの削除
ip addr del 192.168.254.254/24 dev ${IF}

# wpa_supplicantの設定ファイル(ここでは/var/run/wpa.conf)の生成
#  一般的なWPAの事前共有鍵の設定を前提にしているため、
#  Wi-Fi環境の設定に応じて修正する
cat <<-EOT >$WPACONF
ctrl_interface=/var/run/wpa_supplicant
network={
   ssid="$SSID"
   scan_ssid=1
   key_mgmt=WPA-PSK
   psk="$WKEY"
}
EOT

# wpa_supplicantの起動
wpa_supplicant -s -B -P /var/run/wpa_supplicant.${IF}.pid \
-i ${IF} -D nl80211,wext -c $WPACONF
sleep 1

# dhcpクライアントサービスの起動
dhclient -v -pf /run/dhclient.${IF}.pid  \
-lf /var/run/dhclient.${IF}.leases ${IF}

# Wi-Fi経由でのssh 接続を許可する場合、
# 以下のコメントアウトを外してiptablesの行を有効にする
# iptables -A INPUT -p tcp --dport ssh -j ACCEPT