ほかの点では社内 VPN 経由で問題なく閲覧できる端末に、通知が届かなくなる。Web ページは読み込まれ、アプリは開くが、メッセージは自宅にいるとき、またはトンネルを切った後にしか現れない。Firebase Cloud Messaging を使うアプリでは、プッシュ チャネルは独立した長寿命の外向き接続であり、ブラウザがたった今証明した HTTPS の経路とは別物である。以下の確認を順番に行い、最初に失敗した項目で止める。

アプリが実際に FCM を使っているか確認する

すべての通知がプッシュとは限らない。アプリが端末内でスケジュールするもの、HTTPS でポーリングするもの、Firebase と無関係なベンダー チャネルで届くものもある。アプリのマニフェストと依存関係に Firebase Messaging が含まれていれば、通知は通常 FCM 接続を通り、クライアント ライブラリは登録を予測可能なタグの下に記録する。

adb logcat -s FirebaseMessaging:V
adb shell dumpsys package <package> | grep -i firebase

ログに登録トークンがあれば、その転送経路が確認できる。なければ、アプリ層の通知パイプラインを調べていることになり、ファイアウォールの変更は役に立たない。この区別が重要なのは、配信されたのに表示されないメッセージと、そもそも届かないメッセージが、利用者には同じに見えるからだ。

外向きのポートを確認する。Web サイトではない

FCM の端末接続は端末発の TCP で、ポート 5228 を使い、5229 と 5230 が代替、443 が最後の手段である。閲覧用に 443 を許可するファイアウォールでもプッシュは壊れうるし、アプリの API ドメインを許可する規則は、別サービスであるメッセージングのエンドポイントを覆わない。

これらは端末からの外向き接続である。端末や VPN ゲートウェイで受信ポートを公開するものではないので、ポート転送を提案する人がいたら、設計はすでに間違っている。一つのポートをインターネット上の全アドレスに開く規則も同じで、文書化された宛先に限定すべきだ。

PortRoleWhat to verify
5228Primary FCM connectionOutbound allowed and session state kept
5229, 5230Fallback portsOften missing from hand-written allowlists
443Last-resort fallbackWorks only if the client actually falls back
HTTP proxyNot a supported FCM transportProxy exclusion or bypass, not a port rule

Firebase のネットワーク ガイダンス も、FCM の配信プロトコルは通常の HTTP プロキシでは運べないと述べている。したがって、ブラウザが社内 Web プロキシ経由で動くことは、プッシュのソケットについて何も証明しない。両者は経路の異なる別のクライアントである。

ソケットを切ってしまうアイドル タイムアウトを確認する

FCM 接続はメッセージの間も開いたままで、そのため NAT やステートフル インスペクションのタイムアウトに敏感である。Firebase のガイダンスは、そうしたポリシーが適用される場所では少なくとも 30 分のアイドル許容を求めている。五分のセッション タイムアウトはマッピングを静かに削除し、端末は何かに起こされるまで再接続しないため、メッセージはまとめて届くか、まったく届かない。

ファイアウォールや VPN ゲートウェイのセッション テーブルを読み、端末の 5228-5230 への接続を探す。残りの寿命を文書化された値と比較する。短ければ、端末のすべてのポリシーを変えるのではなく、そのポートのタイムアウトを延ばす。全体のタイムアウト変更は正当化しにくく、元に戻すのはさらに難しい。

プッシュ配信は、Wi-Fi と携帯網の間を移動してもエンドポイントのマッピングが生き残るかどうかにも左右される。一つのインターフェースに紐づいたマッピングは、両方のネットワークがポートを許可していても、切り替えで破棄されうる。

VPN バイパスを許容できるか決める

Android の VPN クライアントはトンネルを迂回する通信を許可でき、そのバイパスが許されている場合、FCM は下位のネットワークを使うことがある。その場合プッシュ チャネルは暗号化されたままだが、トンネルのアドレスを運ばなくなるため、VPN の IP マスキングは適用されない。これはポリシー上の妥協であり、不具合ではない。

ポリシーがバイパスを禁じているなら、トンネルの経路が接続を運ぶ必要がある。ポートを開き、タイムアウトを十分に長くし、プロキシを邪魔にならない場所に置く。管理対象サービスを黙って除外したり、管理されていないネットワークで通知が動くからといってロックダウンを緩めたりしてはいけない。VPN アイコンは、どのサービスがどの経路を選んだかを示しません

配信と表示を分けて考え、一度だけ試験する

権限、チャネル設定、サイレント モード、アプリごとの切り替えが、配信されたメッセージを表示するかどうかを決める。Android 13 以降では通知権限は実行時の付与であり、拒否されると、ポートが塞がれたときとまったく同じ静けさになる。届いたのに表示されないメッセージは表示側の問題であり、別に扱う。

メッセージをその場で送るのではなく、統制された試験を一度行う。端末、アカウント、アプリを固定し、既知のタイムスタンプで一通だけ送り、VPN ありの状態を承認済みの VPN なしネットワークと比較する。各実行で logcat の受信時刻と表示時刻を記録する。配信は違うが表示は同じなら、ネットワーク経路が変数である。両方が同じなら、アプリを引き続き調べる。

ネットワークの担当者に、ポート、プロキシの制約、実測したタイムアウト、バイパスの判断を一つのメモにまとめて渡す。「VPN を切る」は所見ではなく、Google の通信をすべて許可することは範囲を定めた修正ではない。

関連記事