1 ポイント 投稿者 GN⁺ 2023-09-29 | 1件のコメント | WhatsAppで共有
  • Strange Loopからの帰りのSt. Louis-Oakland直行便で、8ドルのインターネット課金に失敗したことをきっかけに、機内WiFiに接続した状態でインターネットなしでもアクセスできるデータを確認した
  • Southwest WiFiポータルのネットワークリクエストの中で、繰り返し成功する current.json エンドポイントが見つかり、この応答がフライト状況ページの基盤データだとみられた
  • このエンドポイントは Cookieやヘッダーなしでも curl で呼び出せ、高度・座標・到着予定時刻・対地速度・残り距離・フライト進行率・衛星接続状態などを返した
  • 収集したデータで高度、ETA、対地速度を可視化したところ、降下区間を除けば高度はおよそ 20〜30フィート 程度しか揺れていなかった
  • 特別に実用的な発見ではなかったが、機内WiFiポータルが公開している フライト状況JSON だけでも、飛行中のデータ収集と分析を試せる

決済失敗から始まった機内WiFi探索

  • Strange Loopからの帰りのSt. Louis-Oakland直行便で、Southwestの 機内WiFiポータル を通じて8ドルのインターネット接続権を購入しようとしたが、どの支払い手段も受け付けられなかった
  • Webページは役に立つエラーメッセージを表示せず、ブラウザーの ネットワーク開発者ツール で失敗したリクエストを確認した
  • 失敗したリクエスト自体からは手がかりを見つけにくかったが、繰り返し成功する current.json リクエストが目に留まった

current.json が返したフライト状況データ

  • current.json の応答は、機内WiFiポータルの フライト状況ページ を動かしているデータだとみられる
  • 例の応答には次の値が含まれていた
    • sat_commlink_portal.status: conn_ok
    • satcomm_status.commlink: active
    • satcomm_status.linkparams: not-stale
    • pcent_flt_complete: フライト進行率を示すと思われる値
    • altVal: 現在高度
    • lat, lon: 現在座標
    • dtzone: 目的地のタイムゾーン
    • within_us: 米国内フライトかどうか
    • etad: 目的地の到着予定時刻
    • gspdVal: 現在の対地速度
    • ttgc: 残り時間と思われる値
    • dist_remain: 残り距離
    • actime24: あるタイムゾーンでの現在時刻

ブラウザーのリクエストを curl で再現

  • ブラウザーの「Copy as cURL」機能で、エンドポイント呼び出しコマンドをすばやく取得した
  • この機能はFirefoxとChromium系ブラウザーにあり、ブラウザーが送ったリクエストを同じヘッダー付きで再現するときに便利だ
  • 実験の結果、リクエストに含まれるCookieやヘッダーは必須ではなく、次のような単純な curl 呼び出しだけでデータを取得できた
curl 'https://getconnected.southwestwifi.com/current.json'
  • その後、30秒ごとにデータを取得してログファイルに積み上げるループを実行した
watch -n 30 "curl https://getconnected.southwestwifi.com/current.json | jq -c >> flight-logs"

応答フィールドに残った疑問

  • ほとんどのフィールドは直感的だったが、いくつかの値は意味がはっきりしなかった
    • sat_commlink_portal.statussatcomm_status.commlink の違い
    • pcent_flt_complete が距離基準なのか予想時間基準なのか
    • altVal, etad, gspdVal が飛行中にどれくらい揺れるのか
    • actime24ac が何を意味するのか
  • actime24 は航空機位置の現在時刻ではなく、目的地の現在時刻のように見えるため、ac を “aircraft” と解釈するのは難しい

飛行中に収集したデータの可視化

  • 収集したデータで 高度ETA対地速度 の変化を可視化した
  • 高度変化

    • まずは高度データにどれくらいノイズがあるかを確認したかった
    • 全体のレンジが大きくノイズを見づらかったため、降下区間を除くと高度の変動はおよそ 20〜30フィート 程度だった
    • この程度の安定性は予想以上だったが、正常範囲やデータ精度は分からなかった
  • ETA変化

    • ETAは妥当に安定しているだろうと予想しており、離陸直後を過ぎた滑らかな飛行では実際に安定していた
    • 天候のせいで着陸が遅れる状況なら、ETAが徐々に増えるのか、終盤で急に増えるのかはまだ疑問として残る
  • 対地速度変化

    • 対地速度も予想どおり安定していた
    • 当初は速度単位をMPHとして表示していたが、HN読者はこの値が knots である可能性が高いと指摘した
    • 飛行序盤からデータを収集できなかったため、巡航速度に近づく区間のカーブは確認できなかった

結論

  • 収集したデータに特別に有用だったり驚くような点はなかった
  • インターネット接続がなくても、機内WiFiポータルが公開している フライト状況JSON を使って飛行中のデータを収集・分析できる

1件のコメント

 
GN⁺ 2023-09-29
Hacker News のコメント
  • 息子が9〜10歳くらいの頃、飛行機の中で携帯電話でインターネットを使っていたので、インターネット料金を払った覚えがなく、どうやって使っているのか聞いてみた。
    学校の友だちに教わったと言って、Wi-Fi設定のDHCPで割り当てられたIPアドレスの数字を変えていけばいいのだと言っていた。当時のAmerican Airlinesは有料ユーザーのIPだけを許可する方式だったため、誰かが192.168帯のIPを当ててなりすませば、追加認証なしで接続を奪えたようだった。
    やめるようには言ったが、試してみる度胸は少し誇らしかった。

    • 昔の有料Wi-Fiホットスポットで、似たようなことをよくやっていた。
      まず nmap -sP でサブネット全体にpingスイープをかけ、ARPキャッシュに使えそうなIP/MACアドレスを埋めてから、IPアドレスとMACアドレスを1つずつ変えて、ファイアウォールを通過できる組み合わせを探した。
      Wayport(現在のAT&T WiFi)でNOCエンジニアとして働いていたおかげで、仕組みを理解する助けになった。
    • 飛行機とホテルで同じ方法を使っていて、ホテルのほうが成功率は高かった。
      ほかの人がその瞬間に使っている可能性が低く、切断される可能性も低かったからだ。
      子どもの頃にはもう一つ小さなハックもやっていた。航空会社が機内映画用の特殊なイヤホンを販売または貸し出していた時代、ポートは横に並んだ2つの穴で、プラグは2本のチューブだった。
      搭乗前にターミナルのファストフード店でストロー、できれば曲がるストローを何本か取ってきて、それらをつないで長いストローを作り、片方をポートに差し込み、もう片方を耳に当てると、無料で映画の音声を聞けた。
    • 数年前、Southwestの飛行機でOpenVPNを切り忘れたところ、料金を払わなくてもトンネル経由でインターネットに接続できた。
      当時は、支払っていないユーザーには一般的なポート(80、443、53など)だけをブロックしていたようで、その後その穴は塞がれた。
    • 本当に驚くべき逸話だ。
      オープンWi-Fiのセキュリティの状況は実際かなり残念で、航空会社がこれより簡単にもっとうまくやる方法もよく分からない。
      デバイスが対応していればOpportunistic Wireless Encryption [1]を使い、認証を特定のMACアドレスではなく特定のOWEセッションに紐づけることはできるだろうが、OWEセッションがどれほど安定しているのかは分からない。
      アクセスポイントが変わるたびに再ログインが必要になるなら、非常に不便だろう。
      有料Wi-Fiや無料Wi-Fiのセキュリティはまだ解決済みの問題ではないのが残念で、決済、3DS、パスワード再設定メールのような選択的トラフィックを通す必要がある、不安定なキャプティブポータルのような場当たり的なカスタム解決策が今も必要だ。
      クライアントが現在「接続済み」「制限あり」「決済/認証が必要」を判別できる標準エンドポイントとAPIもあるとよいし、認証トークンを受け取って同じセッションで自然に再接続できるとよい。
      Hotspot 2.0とWPA-EAP(WPA Enterprise)はあるにはあるが、それぞれ通信事業者が運営するホットスポット網と企業環境向けに寄っていて、「Webポータルで支払う」用途にはうまく合わない。
      [1] https://en.wikipedia.org/wiki/Opportunistic_Wireless_Encrypt...
    • 昔は、すでにインターネットに接続されているネットワーク上のIPアドレスとMACアドレスをスキャンしてくれるアプリがあった。
      設定をそのうち1つのMACアドレスに変えておくと、本来のユーザーが使い終わった後に、その接続を独り占めできた。
      出張していた頃、Wi-Fi料金を払うのを拒んでいたのだが、まだ空港やコーヒーショップで有料接続を提供していた時代にはかなり役に立った。
      今ではほとんど必要ないが、いまだに接続費用がかかる場所では役立つかもしれない。
  • 「このデータによると、飛行機の高度は20〜30フィート程度しか揺れていなかった。思ったより安定している!」
    オートパイロットは非常に優れており、気圧高度を基準にサーボ制御している
    現代の航空機に搭載されている多くの気圧高度エンコーダー、たとえばトランスポンダーがSSRレーダーやADS-Bで報告する高度を駆動する装置は、25フィートのエンコード分解能を持つ
    ここで見えているのもその25フィート分解能である可能性が高く、10フィート分解能のエンコーダーもあるが、25フィートは非常に一般的

    • 記事に出てきたAPIがどのセンサーデータを受け取っているのかは分からないが、ほとんどの旅客機は検出した位置の精度や、垂直位置/高度の精度までブロードキャストしている
      https://globe.adsbexchange.com/ の地図で航空機をクリックし、左サイドバーを一番下までスクロールすると「Accuracy」セクションが見られる
      ADS-B Exchangeは垂直位置精度であるRc/vは表示しないが、他の値は表示する
      詳細は https://mode-s.org/decode/content/ads-b/7-uncertainty.html を参照
    • 小型機なら、注意して手動操縦しているときに20〜30フィートの範囲は異常ではない
      巡航中の旅客機なら当然オートパイロットを使っているはず
      以前、フライトフォローイングを受けていたときに100フィートほど下がったら、管制官に大丈夫かと聞かれて、そこまで細かく見ていることに驚いた
      水上区間の前に救命胴衣を着るのを忘れていて、着ている間、まだ飛行訓練を受けていなかった妻に操縦を任せていた状況だった
      その後、妻も免許を取得したが、管制の追跡が介入するほど精密だという点は興味深かった
    • 携帯電話で高度を含むGPSトラックを記録して比較していたら面白かったと思う
      気圧とGPSは別物だし、気圧高度計を別のAWOS基準で再設定すると差がはっきり跳ねるのかも気になる
      大型機ではどうしているのか分からないが、小型機では地域の天気に合わせて高度計を設定する必要がある
      気象観測所が自分の高度での気圧を測定して「海面基準に補正」した値を無線で知らせ、それを高度計に入力して地域の気象変化による気圧高度の読みを補正する
      1時間飛んで同じ場所に戻ってきても、高度計設定が数ミリバールほど変わっていることがある
    • RVSM の導入で、ずっと精密になったのだと思う
      航空機間の垂直分離基準は2000フィートだったが、2000年代初頭に1000フィートへ縮小された
    • 状況によっては、過度な精密さがかえって危険になり得ると読んだことがある
      たとえばパイロットが3000フィートへ行けば正確に3000フィートになり、別のパイロットも衝突コース上で3000フィートを望めば、衝突が確定してしまう可能性がある
      高度がそれほど正確でなければ、ニアミスで済む可能性が高くなる
      解決策はおそらく、丸い数字を避けて2950フィートや3050フィートのように使うことだったと思う
      細部は間違っているかもしれないが、この問題が真剣に検討されたという点はかなり確か
  • 数か月前に同じものを見つけて、このAPIを使うCLIフライトトラッカーを作った
    いくつかの航空会社で試したが、どれも同じ機内インターネット事業者を使っていたので、ほぼ完璧に動作した
    [1]: https://github.com/NalinPlad/OuterFlightTracker

    • いいね
      似たようなものを作りたかったが、飛行中にインターネットで参照せずにTUIを作れるほど経験が十分ではなかった
      それでも、すでに作られていてうれしい
  • Delta便で同じデータを取得する方法は次のとおり

    $ curl https://wifi.delta.com/api/flight-data | jq  
    
    {  
    "timestamp": "2023-07-11T14:54:41Z",  
    "eta": "17:48",  
    "flightDuration": 278,  
    "flightNumber": "DAL786",  
    "latitude": 39.723472595214844,  
    "longitude": -97.1514205932617,  
    "noseId": "3879",  
    "paState": false,  
    "vehicleId": "N879DN",  
    "destination": "KPDX",  
    "origin": "KATL",  
    "flightId": "N879DN_SF_20230711121358",  
    "airspeed": null,  
    "airTemperature": 24,  
    "altitude": 33922,  
    "distanceToGo": 179,  
    "doorState": "Closed",  
    "groundspeed": 442,  
    "heading": -73,  
    "timeToGo": 174,  
    "wheelWeightState": "Off"  
    }  
    

    面白い小ネタもある

    $ curl -s https://wifi.delta.com/api/flight-data | jq -r '"https://maps.google.com/?q=";, .latitude, ",", .longitude' | tr -d '\n'; echo  
    https://maps.google.com/?q=40.5615234375,-101.2824478149414  
    
    • jq文字列補間機能を使えば、もっと単純にできる
      $ curl -s https://wifi.delta.com/api/flight-data | jq -r '"https://maps.google.com/?q=\(.latitude),\(.longitude)"'  
      
    • いま機内でこのURLにアクセスしてみたが、本当に動作した
      Wi-FiポータルUIでも見られる情報ではあるが、JSONの塊で見るとまた違った感覚がある
      {"timestamp":"2023-09-28T21:57:39Z","eta":"23:45","flightDuration":164,"flightNumber":"DAL992","latitude":47.4557876586914,"longitude":-111.73490905761719,"noseId":"3883","paState":false,"vehicleId":"N883DN","destination":"KMSP","origin":"KSEA","flightId":"N883DN_SF_20230928195737","airspeed":null,"airTemperature":null,"altitude":35273,"distanceToGo":13,"doorState":"Closed","groundspeed":499,"heading":95,"timeToGo":107,"wheelWeightState":"Off"}  
      
      モバイルなのでJSONの整形はご容赦を
    • 新鮮な空気が欲しいときに、POSTリクエストでドアを開けられたらよさそう
    • planeIdtailNumberではなく、より汎用的な**vehicleId**を使っている選択が興味深い
      Deltaの運航機材の中に、これと合うAPIを持つ別の種類のものがあるのか気になる
      ほかの内部システムを知っている人なら、flightIdからシステム構造をどの程度推測できるのかも気になる
      見たところ、既知のデータから作った複合キー以上のものではなさそうだが、それでも興味深い
    • "airspeed": null
      不安になって窓の外を見てしまう
  • 無料のiMessageやWhatsApp許可接続を利用して任意データを送るプロキシを誰かが作ったら見てみたい
    自宅にWhatsAppリレーを立てておき、飛行機からメッセージをやり取りするような形だ
    一番基本的には、URLを自宅のWhatsAppに送ると、自宅側でWebページをロードし、HTMLをWhatsAppの返信として送り返してレンダリングする、ということができそう
    どれだけ多くのものを動かせるのか気になる
    すでにWhatsAppでTCPリレーを作った人がいるようで、すごい

    • https://github.com/aleixrodriala/wa-tunnel
    • 利用規約は読んでいないが、普通に実際のIPルーターを置けばいいのでは、という気もする
      加入費用を払って、Wi-Fiネットワークも立てる
      機内のSSIDが「Foo」なら「Foo discounted」という名前にして、キャプティブポータルで退役軍人、高齢者、子どもなど、いくつかの「割引」を選ばせる
      どれを選んでも決済ページで2ドルを受け取る
      サービス費用を回収できたら、その後の訪問者には「すべての割引は使い切られたのでFooを使ってください」と表示する
      そうすれば私は無料インターネットを使い、ルーター/ポータルの利用者は2ドルのインターネットを使うことになる
      上り帯域は間違いなくひどいはずなので、すべてのデータを自分の接続1本に多重化するのも簡単だろう
      RPiのようなデバイスに入れるとしても、保安検査を通るには音楽プレーヤーのような完成品に見える必要があり、テーブルを上げる必要があるときやトイレに行くときにも動き続けられなければならない
      機内に不正なWi-Fi接続を切断するWIPSやWIDSがある可能性は非常に低そうだ
      そもそもLANパーティーが禁止されているわけでもないのでは
    • 1〜2年前、Apple Private Relayの最初のベータが出てから1〜2日後に飛行機に乗ったが、フライト中ずっと無料Wi-Fiを使えた
      おそらくiMessageやプッシュ通知用に許可リストへ入れていた宛先に、それまで含まれていたからだと思う
      数日後の帰りの便の前には、すでに塞がれていた
    • 「わあ、すごい」より先に、「無料メッセージングは良い特典なのに、悪用されたら閉じられてしまうだろうな」と思ってしまう
      ハッカーだった時代は過ぎたようだ
    • 航空会社のWi-FiがDNSトラフィックはブロックしていないのを見たことがある
      Iodine(https://github.com/yarrick/iodine)のようなDNSトンネルでも、似たようなことができる可能性は高い
  • Southwest は同じデータを、より見栄えのよい画面で見せている
    Wi-Fi 料金を払わなくても、フライト追跡、現在高度、到着予定時刻、地図上の位置など多くの情報を見られる
    おそらく筆者が処理プログラムを作ったデータと同じものを使っているようで、本質的には無料でアクセスできるサイトが1つあるということ

    • その通り、まさにそう
      このデータを可視化してくれる立派なステータスページを無料で見られる
      それでもスクレイピングした理由は2つあった
      まず、ステータスページは現在値しか表示しないので、フライト全体のデータを見たかった
      それに、面白かったから
    • 最近の米国便、おそらく Alaska Airlines だったと思うが、インターネット接続なしでも Wi-Fi で映画やテレビ番組を見られるローカル LAN ボックスがあった
    • 「ポータルページを開こうとすると、なぜ飛行機のデータが大量に返ってくるんだろう?」という疑問が解けた
  • この記事の精神がいい
    筆者はこの情報を Git スクレイピングすることもできたのではないかと思う
    https://simonwillison.net/2020/Oct/9/git-scraping/

  • 窓の外の写真を撮って、その JSON 出力の GPS 座標を画像に結び付けられそうだと思った
    かなり便利そう

    • カメラアプリで位置情報の権限をオンにしておけば、画像の EXIF データに座標が入る
      米国の民生用 GPS 機器は、ITAR の軍需品輸出規制により、海抜60,000フィート以上かつ1,000ノット以上では動作が禁止されている
  • 機体データと ADS-B データを比較したいなら、これが原文筆者のフライトのようだ
    https://www.flightaware.com/live/flight/SWA2340/history/2023...

    • ADS-B データソースとこの API のデータソースは、少なくとも同じ計器と飛行システムで計算されていた可能性はある
    • 該当するフライトだ
      いいアイデアなのに思いつかなかったのが残念
  • 面白い話だ
    ところで、あの time 形式が気になる人はいないのか
    奇妙な選択に見えるし、タイムゾーンオフセット付きの ISO 8601 のような、もっと標準的なものを予想していた
    "time": "Sun Sep 24 22:02:19 2023"

    • 自分も似たように感じた
      このシステムを設計した人が、サーバー側で時刻をフライト位置基準に見えるローカライズ表現へ変換しておき、クライアント側のロジックなしで Web UI にそのまま入れようとしたのだと思う
    • ctime が使うデフォルト形式のように見える
      基盤バックエンドについての手がかりかもしれない
      https://cplusplus.com/reference/ctime/ctime/