VPNはUART Wi-Fiモジュールの内側ではなく外側に置く
UART Wi-FiモジュールにはTCPソケットが必要で、トンネルを持つのはゲートウェイである。そのアドレスを名指しし、戻り経路を開いたままにし、暗号化がどこから始まるかを知っておく。
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経由に限るなら、転送ポリシーは同じ宛先を別経路で許してはならない、フォールバック経路は要件を静かに無効にするからだ。再接続の挙動を制限し、切断されたモジュールがシリアルリンクや遠隔サービスを再試行で溢れさせないようにする。
四つの答えをまとめて記録する、モジュールのアドレス、ソケットの宛先、ゲートウェイの経路、暗号化が始まる場所だ。次にこの機器をデバッグする人には四つすべてが要り、どれもファームウェアだけから推測することはできない。