ラズベリーパイ用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
- anyPiを組み立て、3GPiにイプシムのSIMカードを取り付け1ます。
- PiConsole I/FのUSBシリアルをPCに接続2(またはラズパイにモニタ・キーボードを接続)します。
- 初期設定のため有線LANに接続し、起動します。
##初期設定(約10分)
-
なにはともあれ、まずはufwのインストール、設定を行います。
インストール
sudo apt-get install ufw
IPv6無効
```
sudo vi /etc/default/ufw
```text:/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
```text:/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
1. イプシムのAPNを設定します。
イプシムはanyPi/3GPi付属のmicroSDにはプリセットされていないので、手動で[APN情報](https://ipsim.net/support.html)を設定
```
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分)
![3GPi_LED.JPG](https://qiita-image-store.s3.amazonaws.com/0/211762/dbe9ad5d-554f-b17c-a8cd-4eacbe76c118.jpeg)
1. 電源をON、3GPiの青色LEDが
`《点灯》→《ゆっくり点滅》→《はやい点滅》`
と変化することを確認します。
1. nmcliコマンド
```text: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
```text: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になっていることを確認します。
1. ifconfigコマンド
```text: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)が割り当てられていることを確認します。
1. netstatコマンド
```text: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
1. ufwのstatusを確認します。
```text: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
```
1. 実際に手元のPCからInternet経由でラズパイに接続してみます。
3G通信のため若干のタイムラグはありますが、sshは問題なく使えました。
1. 後は、ufwに必要な許可設定を追加します。
##ラズパイからラズパイに接続
- 同一構成を2つ以上用意すると、ラズパイ⇔ラズパイ間の接続も可能です。
#最後に
anyPi/3GPi付属microSDのRaspbianを使うと、後はufwのインストール&設定とAPN設定だけで、Internet側からラズパイを制御可能な環境が出来上がります。まさにIoTスタータキット、とても簡単ですね。
###補足:PiConsole I/Fについて
単品販売は無くanyPi同梱のみのようですが、PCのUSBポートに接続するだけでラズパイにシリアル接続ができて便利です。その他にも、16文字x2行のテキスト表示ディスプレイ、LED、タクトスイッチ、電子ブザー等が搭載されています。[メカトラックスのラズパイIoTスタータキット「anyPi(エニーパイ)」のPiConsole I/Fを使ってみた](https://qiita.com/syasuda/items/5e1da8f3315e3031684a)に詳しくまとめられており、とても参考になります。ほとんど同記事からの抜粋になりますが、
>スイッチを押す → イプシムの固定IPアドレスや3G回線の接続状況をディスプレイに表示する
といったことも簡単に実現できましたので、手順をまとめておきます。
- I2Cの有効化
```
sudo raspi-config
起動後「5 Interfacing Options」→「P5 I2C」をenabledに変更
-
i2c-toolsはインストール済みだったたため、wiringpiのみ追加インストール
sudo pip3 install wiringpi
- [WiringPi-Pythonを使ってAQM0802A / ST7032i LCD表示](https://qiita.com/f_nishio/items/b1b99b4763993a9239c6)のst7032i.pyを修正
```
vi st7032i.py
```python: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を合わせたスクリプトを作成
```python: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 が出た時の対策を行いました。 ↩