$yuzu->log();

技術ネタなど。

格安SIM(MVNO)とRaspberry Pi(ラズベリーパイ)でモバイルルータを作った 〜初期設定から完成まで〜

f:id:yuzurus:20150523195517j:plain
最近ジワジワ人気になってきた格安SIM(MVNO)とRaspberry Pi(ラズベリーパイ)。 今回はこの2つを使ってモバイルルータを作ってみたいと思います。

格安SIM(MVNO)とは?

格安SIM(MVNO)は非常に低価格でモバイル通信できます。 安いものだと月額500円以下のプランもあります。 非常に低価格なのですが、格安SIM(MVNO)を使うためには殆どの場合ドコモ端末かSIMフリー端末が必要となります。

Raspberry Pi(ラズベリーパイ)とは?

Raspberry Pi(ラズベリーパイ)とは手のひらサイズの超小型コンピュータで電子工作やプログラミング等に使えます。 価格も非常に安く、5000円ほどで手に入ります。

用意するもの

・Raspberry Pi Model B+(4266円)

Raspberry Pi Model B+ (Plus)

Raspberry Pi Model B+ (Plus)

必須です。最近Amazonでも取り扱うようになりましたね。

・L-02C (4500円)

ヤフオクで中古品(2000円ぐらい)が出回っているのでそちらでも可。

・DMM mobile (最安プラン 660円)
Alt DMM mobile
今回は手持ちの格安SIM(MVNO)のDMM mobileを使用しました。

無線LANアダプタ (713円)

BUFFALO 無線LAN子機 コンパクトモデル 11n技術・11g/b対応 WLI-UC-GNM

BUFFALO 無線LAN子機 コンパクトモデル 11n技術・11g/b対応 WLI-UC-GNM

安くて良いです。

・8GB microSDカード (824円)

OSを入れるのに使用します。
以前のRaspberry Pi(ラズベリーパイ)はSDカードでしたが最新のモデルはmicroSDカードなのでご注意を。

・軽いモバイルバッテリー

今回は私の手持ちのモバイルバッテリーで代用しましたが持ち運びを考えると軽いものが良いです。

・有線LANケーブル (583円)

セットアップに使います。

RaspberryPi(ラズベリーパイ)の初期設定

作業PCはMacを使用します。
まずmicroSDカードにOSイメージを焼きます。OSはせっかくなのでRaspbian(ラズビアン)を使います。
公式サイトからRASPBIANを選択しダウンロード、解凍します。今回は2015-05-05リリースのものを使用します。ダウンロードが終わったらSDカードをMacに接続します。

df -hでSDカードのディスク名をチェック

$ df -h                                                               
Filesystem                                                    Size   Used  Avail Capacity  iused     ifree %iused  Mounted on
/dev/disk2s1                                                  29Gi  2.3Mi   29Gi     1%        0         0  100%   /Volumes/NO NAME

ディスク名は/dev/disk2s1でした。

diskutilでアンマウント

# diskutil unmountDisk /dev/disk2s1                                         
Password:
Unmount of all volumes on disk2 was successful

成功です。

ddコマンドでSDカードにOSイメージを書き込み

# dd if=2015-05-05-raspbian-wheezy.img of=/dev/disk2s1 bs=4m                  
781+1 records in
781+1 records out
3276800000 bytes transferred in 290.594687 secs (11276187 bytes/sec)

30分ほど時間がかかりました。これでSDカードにOSイメージが書き込まれました。

RaspberryPi(ラズベリーパイ)へ接続

f:id:yuzurus:20150523195645j:plain SDカード、有線LANをRaspberryPi(ラズベリーパイ)へ接続したあと、microUSBポートに電源を差し込みます。
赤と緑のLEDが点灯し緑が点滅すれば成功です。
私は初めて接続した時、赤と緑のLEDが点灯したまま点滅しませんでした。焼きがうまく行っていなかったようで、再度焼き直したら起動できました。
使用しているルータにアクセスしてRaspberryPi(ラズベリーパイ)に割り振られているIPアドレスを確認。今回は192.168.11.13でした。

MacからSSHを使って接続してみます。usernameはpi, passwordはraspberryです。

$ ssh pi@192.168.11.13           
The authenticity of host '192.168.11.13 (192.168.11.13)' can't be established.
RSA key fingerprint is 0d:6e:e9:9d:25:28:2b:51:59:c0:34:0e:6b:78:01:82.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.11.13' (RSA) to the list of known hosts.
pi@192.168.11.13's password:
Linux raspberrypi 3.18.11+ #781 PREEMPT Tue Apr 21 18:02:18 BST 2015 armv6l

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Fri May 22 05:04:12 2015

無事接続できました。

初期設定

今後はRaspberry Pi(ラズベリーパイ)上での作業となります。

# raspi-config

上記のコマンドを実行すると下記のような画面が表示されます。
f:id:yuzurus:20150523195643p:plain

ここで日本locale設定だけにします。

  1. Expand Filesystemを選択します。
  2. Internationalisation Options > Change Locale > ja_JP.UTF-8で日本語環境にします。
  3. Internationalisation Options > Change Timezone > Asia > Tokyoで日本時間にします。

パッケージ更新

パッケージ更新
# apt-get update
# apt-get upgrade

Vimをインストール

ついでにみんな大好きVimをインストールしておきましょう。

# apt-get install vim
# update-alternatives --set editor /usr/bin/vim.tiny

これでRaspberry Pi(ラズベリーパイ)の初期設定はひとまず完了です。

WiFiアクセスポイント機能有効化

Raspberry Pi(ラズベリーパイ)に無線LANアクセスポイントであるWLI-UC-GNMを差し込んでください。 Wi-Fiアクセスポイント機能を有効にするためにhostapdを導入します。
有線LANのeth0にDHCPIPアドレスを割り当て、無線LANのwlan0に固定IPアドレスを割り当てます。

# vim /etc/network/interfaces

auto lo
 
iface lo inet loopback
iface eth0 inet dhcp
 
allow-hotplug wlan0
auto wlan0
iface wlan0 inet static
address 192.168.100.1
network 192.168.100.0
netmask 255.255.255.0
gateway 192.168.11.1

次にhostapdをインストールします。

# apt-get install hostapd

ここでhostapdの設定を行いますが、使用するアダプタ(ドライバ)によって手順が変わってきます。
今回は「用意するもの」で挙げたWLI-UC-GNMを使った設定を行います。
lsmodして、ドライバを確認します。

# /sbin/lsmod

ドライバがmac80211ベースでした。 こちらは本家のhostapdがサポートしているのですが、apt-getでインストールされるものはバージョンが古いためhostapdを入れ替える必要があります。 公式サイトから最新のソースをダウンロード、コンパイルします。

$ cd /tmp
$ wget http://w1.fi/releases/hostapd-2.0.tar.gz
$ tar xvf hostapd-2.0.tar.gz

コンパイルに必要なライブラリをインストールします。

# apt-get install libnl-genl-3-dev libssl-dev

必要な設定を加えてコンパイルします。

$ cd hostapd-2.0/hostapd
$ cp defconfig .config
$ echo "CONFIG_LIBNL32=y" >> .config
$ make
# make install

hostapdの設定ファイルを修正。 ssid, channel, wpa_passphraseは適宜変更してください。

interface=wlan0
driver=nl80211
ssid=korokkeyasan
hw_mode=g
channel=6
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=korokkeyasan
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP

hostapd起動のための設定をします。
DAEMON_CONFがコメントアウトされているので下記のように修正してください。

# vim /etc/default/hostapd
DAEMON_CONF="/etc/hostapd/hostapd.conf"

WPASupplicantを無効にしておきます。一応適当なところにバックアップしておきます。

# mv /usr/share/dbus-1/system-services/fi.epitest.hostap.WPASupplicant.service /tmp

DHCPサーバの導入

IPアドレスを自動で割り振るDHCPサーバを導入していきます。

# apt-get install isc-dhcp-server

設定ファイルを編集します。(設定した部分だけ抜粋)

# vim /etc/dhcp/dhcpd.conf

#コメントアウト
#option domain-name "example.org";
#option domain-name-servers ns1.example.org, ns2.example.org;

#アンコメント
# 正当な DHCP サーバーであることの宣言 
authoritative;

# ネットワークアドレスとサブネットマスク指定 
subnet 192.168.100.0 netmask 255.255.255.0 {

  # 貸し出すIPアドレスの範囲指定
  range 192.168.100.10 192.168.100.50;

  # ブロードキャストアドレス指定
  option broadcast-address 192.168.100.255;
  
  # デフォルト貸出期間
  default-lease-time 600;

  # 最大貸出期間
  max-lease-time 7200;

  # ゲートウェイアドレス指定
  option routers 192.168.100.1;

  # ドメイン名指定
  option domain-name "local";

  # ネームサーバーのホスト名 (Google)
  option domain-name-servers 8.8.8.8, 8.8.4.4;
}

DHCPサーバの起動設定をします。

# vim /etc/default/isc-dhcp-server
INTERFACES="wlan0"

先ほど設定したhostapdをデーモンとして起動するようにしたいので下記のように設定します。

# service hostapd start

また起動時にhostapdを起動させたいので下記のように設定します。

# update-rc.d hostapd enable 

DHCPサーバを起動します。

# service isc-dhcp-server start

また起動時にDHCPサーバを起動させたいので下記のように設定します。

#  update-rc.d isc-dhcp-server enable

これで自動でIPアドレスが割り振られるようになりました。

IPマスカレードの設定

カーネルの機能なので、ここでは特に何かインストールする必要はありません。

# vim /etc/sysctl.conf
 
# アンコメント
net.ipv4.ip_forward=1

一度再起動してこの設定を有効にします。

# reboot

再起動が終わったら再度SSH接続してください。 IPテーブルの設定でIPマスカレードを有効にします。

# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

これで有線LAN接続状態でクライアントが無線でインターネットに接続出来るようになりました!

LTEネットワーク接続

f:id:yuzurus:20150523195644j:plain いよいよ有線LANで接続ではなくLTEネットワークでの接続設定をしていきます。 予めL-02CをRaspberry Pi(ラズベリーパイ)に挿入しておいてください。

# apt-get install wvdial
# apt-get install eject

wvdialはダイアルアップ接続用ソフトなのですがejectはCD/DVD-ROMドライブをEjectするためのコマンド。 なぜか今回使用するL-02CはRaspberry Pi(ラズベリーパイ)につなぐとCD-ROMドライブとして認識され、Ejectしないと使えないという謎仕様。だから安いんですけどね。。

# eject sr0

確認します。

$ lsusb

L-02Cが一覧に出てくればOKです。
次に使用するSIMの設定を行っていきます。今回はDMM mobile(IIJmio系)を想定しています。

# vim /etc/wvdial.conf

[Dialer Defaults]
Init1 = ATZ
Init2 = AT+CGDCONT=1,"IP","iijmio.jp"
Init3 = ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
Dial Attempts = 3
Stupid Mode = 1
Modem Type = Analog Modem
Dial Command = ATD
Stupid Mode = yes
Baud = 460800
New PPPD = yes
APN = iijmio.jp
Modem = /dev/ttyUSB2
ISDN = 0
Phone = *99***1#
Password = iij
Username = mio@iij
Carrier Check = no

Phoneは"99*1#"でも"99#"でも可能です。 いよいよ接続です。

# wvdial

PPP接続できました!! IPマスカレードの設定をします。

# iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE

起動時にPPP接続できるようにします。

# vim /etc/init.d/wvdialloop.sh
 
#!/bin/bash
LOG='/var/log/wvdial'
eject /dev/sr0
(
  while : ; do
  wvdial 2>&1
  sleep 15
  done
)   2>&1 > ${LOG} < /dev/null &
# chmod +x /etc/init.d/wvdialloop.sh
# update-rc.d wvdialloop.sh defaults

rc.localにIPマスカレードの設定を追加します。

# vim /etc/rc.local
 
# exit 0 の前に追加
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE

これで電源を入れたらLTEネットワークに接続されモバイルルータとして機能するようになりました!!

その他

初期設定のままSSH接続していましたが、ちゃんと運用するのであればパスワードを変更するなり鍵を設定するなりしてセキュリティを高めてください。
また結構熱を持つのでRaspberry Pi(ラズベリーパイ)のケースを買ったほうが良いかもしれません。

まとめ

モバイルネットワークにつながると夢が広がりますね。とはいっても実はドコモ系MVNOはグローバルIPアドレスが割り振られないようで、遠隔操作やWEBサーバとして使うのは難しいようです。。ngrokを使うといけそうな気もするので次回挑戦してみたいと思います。

参考にしたサイト

http://qiita.com/makoto_kw/items/393e098f214f81449c9f
http://sideb.hatenablog.com/entry/mvno_kakuyasu_sim_raspberry_pi_lte_3g_mobile_router

マルコフ連鎖の実験のためにMeCabをCentOSにインストール

マルコフ連鎖の実験をしたいがために、 京都大学情報学研究科と日本電信電話株式会社コミュニケーション科学基礎研究所が開発しているオープンソース形態素解析エンジン「MeCab」 (和布蕪 めかぶ)をインストールするためのメモです。

本体をインストール

$ cd /tmp
$ wget https://drive.google.com/uc?export=download&id=0B4y35FiV1wh7cENtOXlicTFaRUE
$ tar zxfv mecab-X.X.tar.gz
$ cd mecab-X.X
$ ./configure --enable-utf8-only
$ make
$ make check
# make install

辞書ファイルをインストール

$ cd /tmp
$ wget https://drive.google.com/uc?export=download&id=0B4y35FiV1wh7MWVlSDBCSXZMTXM
$ tar zxfv mecab-ipadic-2.7.0-XXXX.tar.gz
$ cd mecab-ipadic-2.7.0-XXXX
$ ./configure --with-charset=utf8
$ make
# make install

試してみる

$ mecab
すもももももももものうち
すもも   名詞,一般,*,*,*,*,すもも,スモモ,スモモ
も 助詞,係助詞,*,*,*,*,も,モ,モ
もも  名詞,一般,*,*,*,*,もも,モモ,モモ
も 助詞,係助詞,*,*,*,*,も,モ,モ
もも  名詞,一般,*,*,*,*,もも,モモ,モモ
の 助詞,連体化,*,*,*,*,の,ノ,ノ
うち  名詞,非自立,副詞可能,*,*,*,うち,ウチ,ウチ
EOS

うまくいってるっぽい。 このライブラリを使って今後マルコフ連鎖の実験をしていく。

入門 自然言語処理

入門 自然言語処理

jQueryで$(form).submit()でフォームが送信されない場合の対処法

jQueryで、$(form).submit()などを使っても下記のようなボタンにするとフォームが送信されない場合があります。

<input type="submit" id="submit"  value="post" />
<input type="submit" class="submit"  value="post" />
<input type="submit" name="submit"  value="post" />

submitボタンのid,class,name属性に「submit」という名前を使用すると送信できないので、使わないようにしましょう。

jQueryを使ってフォームの二重送信を防止する方法 複数ボタンの場合編

前回1つのフォームに1つのボタンがあった場合のフォーム2重送信防止方法を記しました。 今回は1つのフォームに複数ボタンが有る場合の2重送信を防止する方法を記します。

<form class="multiBtnForm">
<input class="disableMultiBtn" type="submit" name="post" value="post">
<input class="disableMultiBtn" type="submit" name="back" value="back">
</form>
<script>
    $('.disableMultiBtn').on('click', function(){
        $('<input />').attr('type', 'hidden')
            .attr('name', $(this).attr('name'))
            .attr('value', $(this).val())
            .appendTo('.multiBtnForm');
        $(this).text('please wait...');
        $(this).attr('disabled', true);
        $(this).closest('form').submit();
    });
</script>

フォームを送信する前にsubmitボタンにある要素を使って、hiddenタグを作成。 その後ボタンをdisabledにして、送信しています。

ボタンタグにある情報を付加するとフォームが送信できなくなります。 その注意点はこちら

jQueryを使ってフォームの二重送信を防止する方法

サーバーサイド側で2重送信されないように処理するのが一般的ですが、 jQueryを使ってsubmitボタンをダブルクリックを防止するサンプルを記します。

<input type="submit" class="disableBtn" value="post">
<script>
    $('.disableBtn').on('click', function(){
        $(this).text('please wait...');
        $(this).attr('disabled', true);
        $(this).closest('form').submit();
    });
</script>

クリックするとボタンの表示が「post」から「please wait...」に変わり、ボタンがクリックできなくなっていることがわかります。

通常なら上記の方法で2重送信を防止することができますが、1つのフォームに複数ボタンがあって、name属性で処理を変更している場合、jQueryの仕様上、submitボタンのname属性が拾えず、上記の方法では対応できません。 その場合の対処法はこちら

composer install と composer update の違い

PHPの依存管理ツールにComposerついて。installとupdateの違いについてまとめます。

各ファイルの説明

composer.json

必要となるライブラリを記載します。

composer.lock

composer.jsonを元にインストールした各ライブラリのバージョンが記載されています。

コマンドについての説明

composer update

composer.jsonをもとに各ライブラリを最新版に更新します。
その際、composer.lockが生成されます。
カレントディレクトリにcomposer.lockがあっても、そこに記載されているバージョン関係なしに最新版にします。

composer install

composer.lockを元にライブラリをインストールします。
composer.lockが存在しない場合、composer updateと同じくライブラリを最新版にします。

まとめ

composer.lockをチーム内で共有してcomposer installすればライブラリのバージョンは揃いますね。

パーフェクトPHP (PERFECT SERIES 3)

パーフェクトPHP (PERFECT SERIES 3)

Apacheのmod_expiresというキャッシュモジュールを使ってWEBサイトを高速化しよう

Apacheにはmod_expiresというキャッシュモジュールがあります。 クライアント側で画像やCSSなどファイルをキャッシュさせるモジュールです。 これを利用し、転送量を減少させてWEBサイトの負荷対策します。 キャッシュを利用すると負荷対策ばかりか、表示速度も向上します。

mod_expiresが組み込まれているか確認

通常の方法でApacheをインストールしていた場合、mod_expiresはデフォルトで組み込まれています。 CentOSの場合/etc/httpd/conf/httpd.confに以下の行があることを確認してください。

LoadModule expires_module modules/mod_expires.so

mod_expiresの設定方法

httpd.confの377行目付近に以下を追加してください。

<IfModule mod_expires.c>
ExpiresActive on
ExpiresByType image/png "access plus 12 hours"
ExpiresByType image/jpeg "access plus 12 hours"
ExpiresByType image/gif "access plus 12 hours"
ExpiresByType text/css "access plus 12 hours"
ExpiresByType text/javascript "access plus 12 hours"
</IfModule>

これはpng,jpg,gif,css,javascriptを12時間という期限でキャッシュさせるという宣言です。 Apacheを再起動されば反映されます。

mod_expiresの設定が反映されているか確認

Chromeのdev toolで画像のレスポンスヘッダを確認してみましょう。

f:id:yuzurus:20150208015804p:plain

max-age=43200なので43200秒、つまり12時間にちゃんと設定されていることが確認できました。

mod_expiresの設定するにあたっての注意

もしjavascriptなどに変更があり、更新した場合、クライアント側にキャッシュが残っており表示が意図しなくなる場合があります。
その場合はhoge-v1.jsなどファイル名でバージョン管理するか、hoge.js?123456などパラメータにタイムスタンプなどを付与すれば解決します。(モダンなWEBアプリケーションフレームワークにはこのような機能が含まれていると思います。)

ハイパフォーマンスWebサイト ―高速サイトを実現する14のルール

ハイパフォーマンスWebサイト ―高速サイトを実現する14のルール