UART Wi-Fiモジュールを載せたマイコンは、その先にあるサービスへ届くためにVPNを実装する必要はない。モジュールはすでにTCP/IPスタックを動かしてシリアル経由でソケットを公開しており、同じLAN上のゲートウェイがその通信をトンネルへ通せる。設計が成り立つのは、アドレス、ソケット、経路、境界という四つの問いに順番に答えられる場合だけなので、チェックリストとして扱う。最初に落ちる関門で止めるべきだ、後の関門がそれを補うことはないのだから。

各層に一つの仕事を割り当てる

UARTリンクはマイコンとモジュールの間でATコマンドとペイロードを運ぶ。モジュールはWi-Fiネットワークに参加し、送信元アドレスを含むIP接続を所有する。ゲートウェイはトンネル、資格情報、転送ポリシーを所有する。これらの役割を分けておくことが、各段階で設計をデバッグ可能にする。

分離はゲートウェイのポリシーの書き方も変える。送信元ルールはモジュールのLANアドレスを名指しすべきで、シリアルリンクの先にあるマイコンの架空のアドレスではない。マイコンはこの設計では独自のIPアイデンティティを持たない、持っているふりをすれば決して一致しないルールが生まれるだけだ。

モジュールに固定アドレスを与えるには、ネットワークが対応する予約の仕組みを使うか、機器を独自のセグメントに置いてゲートウェイにインターフェースで照合させる。再起動後に変わるプールアドレスは、書いたときには正しかったポリシーをいつか壊す。

ゲートウェイはモジュールのアドレスを名指しできるか

ソケットを開く前に、モジュールが接続済みでアドレスを持ち、ゲートウェイが想定したインターフェース上でそれを見ていることを確認する。ここが最も静かに落ちる関門である、モジュールはLANを出たことのない接続試行を平然と報告するからだ。

AT+CWMODE=1
AT+CWJAP="lab-wifi","passphrase"
AT+CIPSTA?
AT+CIPMUX=0

単一接続モードはコマンド列を単純に保ち、一つのサービスと話す一つのセンサーには正しい出発点だ。複数接続モードは以降のすべてのコマンドの構文を変えるので、別のファームウェア版から例をコピーする前にどちらにいるかを決める。

モジュールからソケットを開く

アドレスとモードが決まれば、モジュールはプライベートサービスへのTCP接続を開ける。下のアドレスはドキュメント用の範囲の例であり、自分のものに置き換えて同じ形を保つ。

AT+CIPSTART="TCP","10.90.0.20",9000
AT+CIPSEND=18
{"t":21.4,"rh":48}

そのATコマンドが開くのは素のTCPソケットであり、ソケットはトンネルではない、その中でVPNが作られることもペイロードが暗号化されることもない。ファームウェアのTLSモードは別機能で、独自のコマンドと独自の証明書処理を持ち、任意のUARTモジュールがどちらも対応しているとは限らない。TCP/IPのATコマンドリファレンスを自分のファームウェアについて確認すべきで、上の構文が当てはまると決めつけてはいけない。

AT+CIPSEND のペイロード長は実際に送る量と一致していなければならない、さもないとモジュールは永遠に来ないバイトを待ち、接続は固まったように見える。その失敗はネットワーク問題に見えるが、ほぼ常に長さの一のずれである。

接続をゲートウェイ経由で通す

ゲートウェイにはプライベート宛先への経路、デバイスネットワークからトンネルへの転送許可、モジュールに届く戻り経路が必要だ。遠隔側がデバイスサブネットへ戻る経路を持たないなら、設計には意図的な変換ルールが必要で、そのルールはサービスが見る送信元アイデンティティを変える。

ip route get 10.90.0.20
sudo tcpdump -ni wg0 'host 10.90.0.20 and port 9000'
sudo conntrack -L | grep 9000

まず戻り経路を見る。転送されたパケットがサービスに届いて戻らないと、ゲートウェイには何のエラーも出ないままモジュール側でタイムアウトし、人は何時間もWi-Fiリンクを眺めることになる。conntrackのエントリは、ゲートウェイが応答をそもそも見たかを教えてくれる。

トンネルが実際にどこで終わるかを決める

トンネルはゲートウェイで始まる。それはUARTリンクを暗号化しないし、モジュールとゲートウェイの間のLANセグメントをトンネルの一部にもしない。そのセグメントで保護が必要なものは独自の仕組みが要る、この例の素のTCPはTLSではない。

トンネルが落ちたときどうなるかも決める。配信をVPN経由に限るなら、転送ポリシーは同じ宛先を別経路で許してはならない、フォールバック経路は要件を静かに無効にするからだ。再接続の挙動を制限し、切断されたモジュールがシリアルリンクや遠隔サービスを再試行で溢れさせないようにする。

四つの答えをまとめて記録する、モジュールのアドレス、ソケットの宛先、ゲートウェイの経路、暗号化が始まる場所だ。次にこの機器をデバッグする人には四つすべてが要り、どれもファームウェアだけから推測することはできない。

関連記事