1773065480
2026-03-09 12:38:00
数年前、私は小規模な UniFi ホスティング サービスを運営していました。独自のクラウド コントローラーを運用したくない MSP や IT ショップ向けのマネージド クラウド コントローラー。すべての顧客は、専用のコントローラーを実行する独自の VPS を取得しました。
製品は機能しました。人々がホスト型コントローラーを望んでいたのは、主にハードウェア、ポート転送、バックアップを扱う必要がないためでした。問題は経済面でした。
各顧客は独自の VPS を必要としていました。 DigitalOcean ドロップレットの料金は月額 4 ~ 6 ドルでした。 7〜8ドル請求していました。これは顧客あたり 1 ~ 2 ドルのマージンに相当し、サポート リクエストがあった場合にはそのマージンはすべて消えてしまいます。基本的にはボランティア活動をしていました。
明らかな解決策はマルチテナンシーです。すべての顧客に独自の VM を提供するのではなく、共有インフラストラクチャ上に複数のコントローラーを配置します。ただし、UniFi コントローラーはマルチテナントではありません。それぞれは、独自のデータベースとポート バインディングを持つ独自の分離インスタンスです。ルーティング層が必要です。これは、受信トラフィックを調べて、それがどの顧客に属しているかを把握できる前面のものです。
ポート 8443 の Web UI の場合、それは簡単です。リバース プロキシの背後にある顧客ごとのサブドメイン。特別なことは何もありません。しかし、ポート 8080 の通知プロトコルが興味深いところです。
何を知らせるのか
すべての UniFi デバイス (アクセス ポイント、スイッチ、ゲートウェイ) は、そのコントローラーに電話をかけます。 10 秒ごとにポート 8080 への HTTP POST。このようにして、コントローラーはデバイスの統計情報、構成の同期、ファームウェアのバージョン、クライアント数などすべてを追跡します。
ペイロードは AES-128-CBC で暗号化されます。そのため、トラフィックを処理するにはデバイスごとの暗号化キーが必要になると考えました。つまり、コントローラーのデータベースが必要になり、顧客ごとに 1 つのインスタンスに戻ることになります。
次に、生のバイトを調べました。
パケット
すべての通知パケットの最初の 40 バイトは暗号化されていません。
Offset Size Field
────── ───── ──────────────────────────
0 4B Magic: "TNBU" (0x544E4255)
4 4B Packet version (currently 0)
8 6B Device MAC address
14 2B Flags (encrypted, compressed, etc.)
16 2B AES IV length
18 16B AES IV
34 4B Data version
38 4B Payload length
42+ var Encrypted payload (AES-128-CBC)
バイト オフセット 8 は、完全に暗号化されていないデバイスの MAC アドレスです。
ワイヤー上では次のようになります。
54 4E 42 55 # Magic: "TNBU"
00 00 00 00 # Version: 0
FC EC DA A1 # MAC: fc:ec:da:a1:b2:c3
B2 C3
01 00 # Flags
...
(「TNBU」は「UNBT」を逆にしたもので、おそらく UniFi Broadcast Technology のことです。)
コントローラーはデバイスを識別する必要があるため、MAC はヘッダーにあります。 前に 復号化中。暗号化キーはデバイスごとに適用され、導入中に割り当てられるため、コントローラは正しいキーを検索する前に、どのデバイスが通信しているかを知る必要があります。セキュリティ上の見落としではなく、単なる実際的な要件です。ただし、暗号化にまったく触れずにインフォーム トラフィックをルーティングできることを意味します。
MACの読み取り
それを抽出することはほとんど何もありません:
header := make([]byte, 40)
if _, err := io.ReadFull(conn, header); err != nil {
return err
}
if string(header[0:4]) != "TNBU" {
return fmt.Errorf("not an inform packet")
}
mac := fmt.Sprintf("%02x:%02x:%02x:%02x:%02x:%02x",
header[8], header[9], header[10],
header[11], header[12], header[13])
14 バイトを読み取ると、どのデバイスが通信しているかがわかります。復号化は必要ありません。
プロキシの構築
MAC を使用すると、ルーティングが簡単になります。どの MAC がどのテナントに属するかのテーブルを保持し、パケット全体 (ヘッダーと暗号化されたペイロード、そのまま) を適切なバックエンドに転送します。
Device (MAC: aa:bb:cc:dd:ee:ff)
|
v
+-----------------------------------+
| |
| Inform Proxy |
| |
| Read MAC from bytes 8-13 |
| |
| Lookup: |
| aa:bb:cc:... -> tenant-7 |
| 11:22:33:... -> tenant-3 |
| fe:dc:ba:... -> tenant-12 |
| |
| Forward to correct backend |
| |
+-----------------------------------+
| | |
v v v
Tenant 7 Tenant 3 Tenant 12
プロキシ全体は、メモリ内 MAC からテナントへのルックアップ テーブルを備えたおそらく 200 行の Go です。
実際には、プロキシはほとんどがフォールバックです。デバイスが採用されたら、そのデバイスをそのテナントのサブドメイン (set-inform http://acme.tamarack.cloud:8080/inform)その後は、標準のホスト ヘッダー ルーティングが通常の入力を通じて処理します。 MAC ベースのルーティングは、まだ再構成されていないデバイスや工場出荷時にリセットされたデバイスの再採用などのエッジ ケースを捕捉します。
他のポート
知らせるのは難しいことだ。コントローラーの残りのポートはより単純です。
| ポート | プロトコル | 目的 |
|---|---|---|
| 8080 | TCP/HTTP | 通知(デバイスのフォンホーム) |
| 8443 | TCP/HTTPS | ウェブUIとAPI |
| 3478 | UDP | 気絶させる |
| 6789 | TCP | スピードテスト(内部) |
| 27117 | TCP | MongoDB (内部) |
| 10001 | UDP | L2 ディスカバリー (ローカルのみ) |
情報を理解したら、残りはほとんど予期せぬものでした。 8443 は Web UI なので、標準の HTTPS イングレスを使用したテナントごとのサブドメインにすぎません。 3478 (STUN) はステートレスであるため、単一の共有 coturn インスタンスがすべてのテナントをカバーします。残りはコンテナの内部または L2 のみにあるため、ホストから離れることはありません。
暗号化されたペイロード内
興味深いことに、バイト 42 以降のペイロードは AES-128-CBC です。新しく採用されたデバイスはデフォルトのキーを使用します (ba86f2bbe107c7c57eb5f2690775c712) これは Ubiquiti によって公的に文書化されており、コントローラーのソース コードとして同梱されています。導入後、コントローラーはデバイスごとに一意のキーを割り当てます。
復号化されたペイロードには、デバイスの統計情報と構成データが含まれています。コントローラー ソフトウェアを構築している場合は興味深いですが、ルーティングには関係ありません。
それで、これで何が得られますか
すべてのテナントは引き続き独自の専用コントローラーを取得しますが、顧客ごとに VM 全体の料金を支払う必要はもうありません。利益率 1 ~ 2 ドルのボランティア活動が、実際にお金を稼げるものになります。
MAC が暗号化されたペイロード内にある場合は、どれも機能しません。プロキシ層ではデバイスごとのキーが必要になります。つまり、すべてのコントローラーのデータベースにアクセスする必要があり、顧客ごとに 1 つのインスタンスに戻ることになります。パケット ヘッダー内の 6 つのプレーンテキスト バイトによって、すべてのことが可能になります。
Ubiquiti がサードパーティが構築できるようにこのように設計したとは思えません。 MAC が存在するのは、コントローラが復号化の前に本当に必要とするためです。しかし、嬉しい副作用は、TCP 接続から 14 バイトを読み取ることができる人なら誰でも、inform プロトコルをルーティングできることです。
あなたが自分でインフォーム・プロトコルを調べたことがあるなら、それについて聞きたいです。 [email protected]
#UniFi #Inform #プロトコルのリバースエンジニアリング #Tamarack