こんにちは、ソラコムの松下(ニックネーム: Max)です。
IoTはモノとクラウドをネットワークでつなげて、センサーやカメラ画像を用いて現場を共有したり、機器の制御をする技術です。昨今では、試験から本格利用へ進まれる方が多くなってきており、ネットワーク通信量(トラフィック)を把握しておきたい、というお話を伺います。トラフィックが見えてくると、以下が明確になります。
- 本格利用時で必要となる、通信速度や帯域
- ビジネス検討における、従量型ネットワーク利用時の見積もり
トラフィックはセンサーや機器の仕様を基に算出できますが、実際には暗号化やシステム連携時のオーバーヘッドも発生することから、実際のトラフィックと乖離する可能性があります。実運用に近づけるには実測が一番なのですが、センサーやカメラ側にトラフィック計測の仕組みが無い場合は実測できません。
そこで本ブログでは、IoTでもよく使われる小型コンピューター Raspberry Pi (通称: ラズパイ)を Wi-Fi のアクセスポイントにして、センサーやカメラからのトラフィックを中継しつつ、ラズパイ上でトラフィック計測ができる仕組みをご紹介します。
概要
ラズパイに「hostapd」と「dnsmasq」をインストールし、ラズパイの無線LANインターフェイス(wlan0)をWi-Fiアクセスポイントとして受けられるように構成します。インターネット側への通信は有線LAN(eth0)を使用します。
ラズパイへWi-Fi接続してきたデバイスへのIPアドレス配布(DHCP)には「dnsmasq」を利用し、ラズパイを通過した通信には「nftables」によるアドレス変換(NAPT)を行うことで通信をラズパイに集約します。そして「pmacct」を使い、無線LANインターフェイスを通過したトラフィックを計測していきます。
NAPTを利用することで、無線LAN側に多数のIoTデバイスが接続されても、有線LAN側に割り当てられたIPアドレス1つで通信できることから、既存環境への影響を最小限にできる利点があります。
アクセスポイントの構築には、NAPTパターンの他にブリッジパターンがあります。構築の手間はほぼ同じですが、構成の違いやそれぞれの利点については、ブリッジパターンをご覧ください。
Wi-Fiアクセスポイントの構築手順 (NAPTパターン)
実際に構築していきましょう。時間はおよそ30分程度です。
今回利用したのは Raspberry Pi 3 model B+です。無線LANと有線LANがついているモデルであれば利用できますが、3 もしくは 4 を推奨いたします。
1. Raspberry Pi Imagerでの書き込み時設定
Raspberry Pi OSを書き込むにはRaspberry Pi Imagerが一般的です。利用方法はこちらのブログをご覧ください。ここでは Raspberry Pi OS Lite (64-bit)を書き込みました。
書き込み時の設定は以下の通りです。
項目 | 設定例 | 備考 |
---|---|---|
ホスト名 | hostapd-napt | 任意です。 |
SSH | 有効 | 認証方法は任意です。公開鍵認証はSSHキーが必要です。 準備が整っていない場合はパスワード認証を選びます。 |
ユーザー名とパスワード | ユーザー名 = hostapd パスワード = FooBar | 任意です。特にパスワードは推測不能な文字列を指定してください。 パスワード生成ツールの利用も有効です。 |
Wi-Fi | 設定しない | |
ロケール設定 | タイムゾーン = Asia/Tokyo キーボードレイアウト = us | 任意ですが、設定しておくことをおススメします。 |
2. ラズパイの有線LANからインターネット接続を確認する
ラズパイの有線LANポート(eth0)にケーブルを挿し、インターネットに接続できるようにしてください。また、ここからの作業はSSHによるリモートアクセスでも可能です。
3. 初回起動後のOS最新化
Raspberry Pi OS が起動したら、まずインストールソフトウェア・ライブラリの最新化を行います。再起動して最新化は完了です。
sudo apt update && sudo apt upgrade -y sudo systemctl reboot
4. dhcpcdによるwpa_supplicant起動の無効化と、wlan0への固定IP割り当て
wpa_supplicantは、Wi-Fiアクセスポイントに接続する際の認証(WPA)を通すためのソフトウェアです。今回は、ラズパイ自体がWi-Fiアクセスポイントになることから、このソフトウェアが動作していると競合を起こすため停止します。また同時に、無線LANインターフェイス(wlan0)に固定のIPアドレスを割り当てます。
wlan0 には 10.0.2.254
というアドレスを使用しました。基本的にはこのままでも問題ありませんが、eth0側のネットワークと競合する場合は変更してください。
# variables _MY_WLAN0_IP_=10.0.2.254 # main sudo systemctl stop wpa_supplicant.service sudo systemctl mask wpa_supplicant.service cat << _EOT_ | sudo tee -a /etc/dhcpcd.conf interface wlan0 static ip_address=${_MY_WLAN0_IP_}/24 nohook wpa_supplicant _EOT_ sudo systemctl restart dhcpcd.service
確認
以下のコマンドで、先の設定が完了しているか確認します。
sudo systemctl status wpa_supplicant.service | grep Active: #=> Active: inactive (dead) since Sun 2022-05-08 15:28:16 JST; 2min 47s ago ps h -C wpa_supplicant #=> <何も表示されないのが正解>
5. hostapdによるWi-Fiアクセスポイント化
hostapdは、Wi-Fiアクセスポイントサーバーソフトウェアです。このソフトウェアによって、ラズパイの無線LANインターフェイスをWi-Fiアクセスポイントとして動かすことができます。
ここでは SSID = TESTWLAN0
、パスワード = Aihei2oB
と設定しています。これらは変更して利用してください。
# variables _SSID_=TESTWLAN0 _WPA_KEY_=Aihei2oB # main sudo apt install -y hostapd sudo systemctl unmask hostapd.service cat << _EOT_ | sudo SYSTEMD_EDITOR=tee systemctl edit hostapd.service # Ref: /lib/systemd/system/raspberrypi-net-mods.service [Service] ExecStartPre = /bin/sh -c '/bin/rm -f /var/lib/systemd/rfkill/*.mmc*wlan' ExecStartPre = /usr/sbin/rfkill unblock wifi _EOT_ cat << _EOT_ | sudo tee /etc/hostapd/hostapd.conf interface=wlan0 driver=nl80211 ssid=${_SSID_} hw_mode=g channel=11 macaddr_acl=0 ignore_broadcast_ssid=0 auth_algs=1 ieee80211n=1 wme_enabled=1 country_code=JP wpa=2 wpa_passphrase=${_WPA_KEY_} wpa_key_mgmt=WPA-PSK wpa_pairwise=CCMP wpa_group_rekey=86400 _EOT_ sudo chmod 600 /etc/hostapd/hostapd.conf history -d -8 # erase "_WPA_KEY_" in history sudo systemctl start hostapd
確認
以下のコマンドで、先の設定が完了しているか確認します。
sudo systemctl status hostapd | grep Active: #=> Active: active (running) since Sun 2022-05-08 12:39:54 JST; 11min ago
6. dnsmasqによるDHCPサーバー
dnsmasqは軽量DNS/DHCPサーバーソフトウェアです。今回はDHCP機能を利用することで、Wi-Fiアクセスポイントへ接続してきたデバイスへのIPアドレス割り当てを行います。
配布するIPアドレスの範囲は 10.0.2.100 ~ 10.0.2.109 の10個のアドレスとしています。また、DNSサーバーは、それぞれGoogleとCloudflareが運営するパブリックDNSサーバーのアドレスを配布するようにしています。アドレス数、DNSサーバー共にこのままでも問題ないと思いますが、IPアドレス数が必要だったり、組織で利用すべきDNSサーバーアドレスがあれば変更してください。
# variables _MY_WLAN0_IP_=10.0.2.254 _LEASE_RANGE_="10.0.2.100, 10.0.2.109" _DNS_SERVERS_="8.8.8.8, 1.1.1.1" # main sudo apt install -y dnsmasq cat << _EOT_ | sudo tee /etc/dnsmasq.d/wlan0.conf interface = wlan0 dhcp-range = ${_LEASE_RANGE_}, 255.255.255.0, 24h dhcp-option = option:router, ${_MY_WLAN0_IP_} dhcp-option = option:dns-server, ${_DNS_SERVERS_} listen-address = 127.0.0.1 log-queries log-dhcp _EOT_ sudo systemctl restart dnsmasq
確認
以下のコマンドで、先の設定が完了しているか確認します。
sudo systemctl status dnsmasq | grep Active: #=> Active: active (running) since Sun 2022-05-08 12:39:55 JST; 11min ago
7. nftablesによるNAPTゲートウェイ化
nftablesはIPパケットフィルタミドルウェアで、iptables等を統合したものです。今回はwlan0とeth0間の通信に対してアドレス変換(NAPT)を適用するのに利用します。また、wlan0とeth0間で通信ができるように net.ipv4.ip_forward
を有効化もしています。
# main cat << _EOT_ | sudo tee -a /etc/nftables.conf # Ref: https://wiki.archlinux.jp/index.php/Nftables#.E3.83.9E.E3.82.B9.E3.82.AB.E3.83.AC.E3.83.BC.E3.83.89 table ip nat { chain prerouting { type nat hook prerouting priority 0; } chain postrouting { type nat hook postrouting priority 0; oifname "eth0" masquerade; } } _EOT_ sudo systemctl restart nftables.service cat << _EOT_ | sudo tee /etc/sysctl.d/10-ipforward.conf net.ipv4.ip_forward = 1 _EOT_ sudo systemctl restart systemd-sysctl
確認
以下のコマンドで、先の設定が完了しているか確認します。
sudo nft list ruleset | grep "table ip nat" #=> table ip nat { sudo sysctl net.ipv4.conf.all.forwarding #=> net.ipv4.conf.all.forwarding = 1
8. ラズパイで構築したWi-Fiアクセスポイントに接続してみる
以上でラズパイをWi-Fiアクセスポイントとして構築できました。スマートフォンやパソコンから、ラズパイで構築したWi-Fiアクセスポイントに接続してみましょう。
接続できたら https://ifconfig.io といったツールサイトが表示できるかを確認してみましょう。
pmacctによるトラフィック計測
pmacctはトラフィック計測ソフトウェアです。例えば以下のようにすると、Wi-Fiアクセスポイントとして構成されている wlan0 インターフェイスを通過したトラフィック(通信量)を計測できます。
sudo apt install -y pmacct sudo pmacctd -P print -r 10 -i wlan0 -c src_host,dst_host,dst_port
10秒毎に、以下のように画面へ出力されることでしょう。
SRC_IP DST_IP DST_PORT PACKETS BYTES 10.0.2.100 1.1.1.1 853 21 1894 10.0.2.100 8.8.8.8 853 10 936 1.1.1.1 10.0.2.100 57240 9 3774 8.8.8.8 10.0.2.100 38332 9 5897 10.0.2.100 216.58.220.131 80 5 495 216.58.220.131 10.0.2.100 56830 5 370 10.0.2.100 142.251.42.132 443 9 1362 142.251.42.132 10.0.2.100 41126 8 1485
10.0.2.100(= 確認時に利用したスマートフォン)から、DNSサーバーとして設定した 1.1.1.1 や 8.8.8.8 へ通信している様子、そしてその時の通信量がPACKETSやBYTESとして計測されています。これを利用することで、通信量の把握が可能となるわけです。
ここでは単純に画面に表示するようにしましたが、pmacctはSQLiteといったDB保存もサポートしています。詳細はトラフィック計測ツール “pmacct” の結果をSQLiteに保存するをご覧ください。
今後の運用 ~ ラズパイの安定的な運用を目指して
ラズパイをWi-Fiアクセスポイント化できましたが、こういったものは検証時にのみサクっと動かしたいものです。そこで、ラズパイを安定的に動かす1つの方法として「電源ON/OFFだけで動く仕組み」も検討してみてください。詳細はRaspberry Pi OSのrootfs ROM 化をご覧ください。
セルラー通信のトラフィック確認なら「SORACOM Peek」
ここではWi-Fiデバイスのトラフィックをラズパイ上で計測する方法を紹介しました。
IoTにおいては、Wi-Fi以外にもLTEや5Gといったセルラー通信も利用されます。その場合は、SORACOMプラットフォーム上でIPパケットをキャプチャできる「SORACOM Peek(ピーク)」をご利用ください。
SORACOM PeekはSIM(=通信回線)単位、もしくはVPG(=ネットワーク)単位でキャプチャができ、そのフォーマットはpcap形式であるため、Wiresharkといった標準的なパケットアナライザで解析できます。
詳細はオンデマンドパケットキャプチャ「SORACOM Peek」をご覧ください。
おわりに
IoTの本格利用に向けては、通信量の見積もりが不可欠です。特に昨今ではカメラの利用によって、通信量が増える傾向にあります。一度は計測しておき、必要となる通信速度や帯域を確認しておくことで、安定的なIoTシステム構築ができるのではないでしょうか。
費用も安く抑えつつ構築できますので、是非ご活用ください!
― ソラコム松下 (Max / @ma2shita)
参考資料:
- Setting up a Routed Wireless Access Point
- Raspberry PiでWiFiアクセスポイント構築 / WiFiアクセスポイントの構築手順
- systemdのUnitファイルのパスを知らなくともUnitファイルを編集する方法
- nftables – ArchWiki / マスカレード
- トラヒック計測ツール pmacct を使ってみる
ちょっと裏話
Raspberry Pi OSのベースとなっているDebian/GNU Linuxが刷新されたことで、今回の件を通じていろいろと発見がありました。
まずIPパケットフィルタです。古くからiptablesが利用されてきており、今回も当然のようにiptablesを使おうと思いきや、なんと標準状態でインストールされていませんでした。調べてみるとiptablesを置き換えるツールとしてnftablesが入っていたんです。
また、wpa_supplicantの停止にも一手間かかりました。Raspberry Pi OSを含むLinux OSのほとんどが、プロセス管理にsystemdを利用しているのは多くの方が知るところです。その定義ファイルであるUnitファイルを探してみても、wpa_supplicantに関してはwpa_supplicant.service以外に見つからず、この定義をstopやmask(無効化)しても、wpa_supplicantがなぜか起動するという現象に悩まされました。
結果は dhcpcd が管理している /lib/dhcpcd/dhcpcd-hooks/10-wpa_supplicant が起因だったのですが、これの発見には、ログの確認コマンドである journalctl が役立ちました。クラッシックな手法だと dmesg や /var/log/**.log を見るのもありなんですが、同コマンドならトータルで見ることができるため、すぐに発見できたというものです。
ツールや環境は常にアップデートされており、その目的は利便性や速度向上だったりするわけですので、知識をアップデートして、生産性向上につなげたいものです!