ラズベリーパイ用3G通信モジュール「3GPi」・ラズパイ本体・コンソールI/Fモジュールなどがセットになった、メカトラックス様の「anyPi」で、グローバルIPアドレス固定割当の格安SIMイプシムを使ってみます。
何ができるの?
有線LAN・無線LANが無い環境でも、外部からラズパイを制御できます。
ポイント
- ラズパイに直接グローバルIPアドレスが割り当てられます → APNを設定するだけ!
- Internet側からラズパイに接続可能です → ufwで必要な通信のみ許可します
※デフォルトの状態で使うと危険です。必ずufwやiptablesの設定を行いましょう。
準備するもの
- ラズパイIoTスタータキット「anyPi」 ※ラズパイ+3GPiだけでも大丈夫です
- Raspberry Pi 3 Model B
- ラズベリーパイ用3G通信モジュール「3GPi(Ver.2)」
- コンソールI/Fモジュール「PiConcole I/F」
- Raspbian構築済microSDカード(3gpi2-jessie-20170904)、ACアダプタ、ケーブルなど
- 固定IPアドレスMVNO「イプシム」標準SIM
- 設定用PC(またはモニタ・キーボード)
- DHCPが有効な有線LAN
開封から接続まで
セットアップ(約3分)
- anyPiを組み立て、3GPiにイプシムのSIMカードを取り付け1ます。
- PiConsole I/FのUSBシリアルをPCに接続2(またはラズパイにモニタ・キーボードを接続)します。
- 初期設定のため有線LANに接続し、起動します。
初期設定(約10分)
-
なにはともあれ、まずはufwのインストール、設定を行います。
インストールsudo apt-get install ufw
IPv6無効
sudo vi /etc/default/ufw
/etc/default/ufw#IPV6=yes IPV6=no
全てを拒否し、ローカル(192.168.0.0/24)からのssh接続のみ許可
sudo ufw default deny sudo ufw allow from 192.168.0.0/24 to any port 22 proto tcp
default denyでもpingには応答してしまうので、ppp0(SIM側)のみ拒否
sudo vi /etc/ufw/before.rules
/etc/ufw/before.rules#「# ok icmp codes」の直前 # ppp0 -A ufw-before-input -p icmp -i ppp0 --icmp-type echo-request -j DROP
ufw有効化、状態確認
sudo ufw enable sudo ufw status
-
イプシムのAPNを設定します。
イプシムはanyPi/3GPi付属のmicroSDにはプリセットされていないので、手動でAPN情報を設定sudo nmcli con add type gsm ifname "*" con-name ipsim.net apn 4gn.jp user sim@with password sim
-
いったん電源をOFF、有線LANを取り外します。
sudo shutdown -h now
接続確認(約3分)
電源をON、3GPiの青色LEDが
《点灯》→《ゆっくり点滅》→《はやい点滅》
と変化することを確認します。-
nmcliコマンド
nmcli(1)$ nmcli con NAME UUID TYPE DEVICE gsm-3gpi-iij 02cd067e-10d5-40a6-8aaf-************ gsm -- ipsim.net 136604d4-df06-4f5b-91f8-************ gsm ttyUSB3 gsm-3gpi-soracom f297495c-9991-4b21-a811-************ gsm -- ppp0 fb02a76b-4e2e-478e-bafd-************ generic ppp0
nmcli(2)$ nmcli dev status DEVICE TYPE STATE CONNECTION ttyUSB3 gsm connected ipsim.net ppp0 ppp connected ppp0 eth0 ethernet unmanaged -- lo loopback unmanaged -- wlan0 wifi unmanaged --
→
iijさんやsoracomさんが見えますが気にせずにDEVICEにttyUSB3とppp0が表示されること、STATEがconnectedになっていることを確認します。 -
ifconfigコマンド
ifconfig$ ifconfig -a eth0 Link encap:Ethernet HWaddr b8:27:eb:xx:xx:xx UP BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:128 errors:0 dropped:0 overruns:0 frame:0 TX packets:128 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1 RX bytes:10368 (10.1 KiB) TX bytes:10368 (10.1 KiB) ppp0 Link encap:Point-to-Point Protocol inet addr:XXX.XXX.XXX.XXX P-t-P:10.64.64.64 Mask:255.255.255.255 UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1 RX packets:409 errors:0 dropped:0 overruns:0 frame:0 TX packets:446 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:3 RX bytes:36906 (36.0 KiB) TX bytes:51480 (50.2 KiB) wlan0 Link encap:Ethernet HWaddr b8:27:eb:xx:xx:xx UP BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) wwan0 Link encap:Ethernet HWaddr xx:xx:xx:xx:xx:xx BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
→ppp0にグローバルIPアドレス(XXX.XXX.XXX.XXX)が割り当てられていることを確認します。
-
netstatコマンド
netstat$ netstat -nr Kernel IP routing table Destination Gateway Genmask Flags MSS Window irtt Iface 0.0.0.0 10.64.64.64 0.0.0.0 UG 0 0 0 ppp0 10.64.64.64 0.0.0.0 255.255.255.255 UH 0 0 0 ppp0
→まぁ、PPPですからね。
実際に接続してみる
ラズパイからInternetに接続
- pingなどで実際の接続や名前解決を確認します。
Internet側からラズパイに接続
-
接続元のグローバルIPアドレス(YYY.YYY.YYY.YYY)を確認し、ufwに許可設定を追加します。
sudo ufw allow from YYY.YYY.YYY.YYY to XXX.XXX.XXX.XXX port 22 proto tcp
-
ufwのstatusを確認します。
ufw$ sudo ufw status verbose Status: active Logging: on (low) Default: deny (incoming), allow (outgoing) New profiles: skip To Action From -- ------ ---- 22/tcp ALLOW IN 192.168.0.0/24 XXX.XXX.XXX.XXX 22/tcp ALLOW IN YYY.YYY.YYY.YYY
実際に手元のPCからInternet経由でラズパイに接続してみます。
3G通信のため若干のタイムラグはありますが、sshは問題なく使えました。後は、ufwに必要な許可設定を追加します。
ラズパイからラズパイに接続
- 同一構成を2つ以上用意すると、ラズパイ⇔ラズパイ間の接続も可能です。
最後に
anyPi/3GPi付属microSDのRaspbianを使うと、後はufwのインストール&設定とAPN設定だけで、Internet側からラズパイを制御可能な環境が出来上がります。まさにIoTスタータキット、とても簡単ですね。
補足:PiConsole I/Fについて
単品販売は無くanyPi同梱のみのようですが、PCのUSBポートに接続するだけでラズパイにシリアル接続ができて便利です。その他にも、16文字x2行のテキスト表示ディスプレイ、LED、タクトスイッチ、電子ブザー等が搭載されています。メカトラックスのラズパイIoTスタータキット「anyPi(エニーパイ)」のPiConsole I/Fを使ってみたに詳しくまとめられており、とても参考になります。ほとんど同記事からの抜粋になりますが、
スイッチを押す → イプシムの固定IPアドレスや3G回線の接続状況をディスプレイに表示する
といったことも簡単に実現できましたので、手順をまとめておきます。
-
I2Cの有効化
sudo raspi-config
起動後「5 Interfacing Options」→「P5 I2C」をenabledに変更
-
i2c-toolsはインストール済みだったたため、wiringpiのみ追加インストール
sudo pip3 install wiringpi
-
WiringPi-Pythonを使ってAQM0802A / ST7032i LCD表示のst7032i.pyを修正
vi st7032i.py
st7032i.py#import wiringpi2 as wp import wiringpi as wp
-
python3-dbusとpython-networkmanagerをインストール
sudo apt-get install python3-dbus sudo pip3 install python-networkmanager
-
サンプル3と6を合わせたスクリプトを作成
b36.py#!/usr/bin/env python3 # -*- coding:utf-8 -*- import wiringpi as wp PIN_SW1_WHITE = 19 PIN_SW2_BLACK = 16 PIN_LED1_RED = 20 PIN_LED2_YELLOW = 21 PIN_BUZZER = 25 import sys, socket, struct from fcntl import ioctl SIOCGIFADDR = 0x8915 from st7032i import St7032iLCD as LCD I2C_ADDR_LCD = 0x3e import NetworkManager c = NetworkManager.const def get_ip(interface): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: ifreq = struct.pack(b'16s16x', interface) ifaddr = ioctl(s.fileno(), SIOCGIFADDR, ifreq) finally: s.close() _, sa_family, port, in_addr = struct.unpack(b'16sHH4s8x', ifaddr) return (socket.inet_ntoa(in_addr)) if __name__ == '__main__': wp.wiringPiSetupGpio() wp.pinMode(20,1) wp.pinMode(21,1) wp.pinMode(25,1) lcd = LCD(I2C_ADDR_LCD) while True: sw1 = wp.digitalRead(PIN_SW1_WHITE) sw2 = wp.digitalRead(PIN_SW2_BLACK) if sw1 == 0: lcd.clear() wp.delay(250) lcd.set_cursor(0, 0) lcd.print("ppp0:") ip_addr_ppp0 = get_ip(b'ppp0') lcd.set_cursor(0, 1) lcd.print(ip_addr_ppp0) wp.delay(250) if sw2 == 0: lcd.clear() wp.delay(250) lcd.set_cursor(0, 0) lcd.print("state:") state = "{0}".format(c('state', NetworkManager.NetworkManager.State)) lcd.set_cursor(0, 1) lcd.print(state) wp.delay(250)
-
実行
sudo python3 b36.py &
スイッチ操作
白SW1を押すとイプシムの固定IPアドレスが、黒SW2を押すと3G回線の接続状況がそれぞれ表示されます。
白SW1で固定IPアドレスが表示されない場合は、黒SW2で3G回線の接続状況を確認する、といった使い方が考えられますね。
-
nano SIM+変換アダプタを使いましたが、標準SIMの利用が無難です。 ↩
-
Raspberry Pi で syslog に rsyslogd-2007: action 'action 17' suspended が出た時の対策を行いました。 ↩