1P by GN⁺ | ★ favorite | 댓글 1개
  • Strange Loop에서 돌아오는 St. Louis-Oakland 직항편에서 $8 인터넷 결제가 실패하자, 기내 WiFi에 연결된 상태로 인터넷 없이 접근 가능한 데이터를 확인함
  • Southwest WiFi 포털의 네트워크 요청에서 반복적으로 성공하는 current.json 엔드포인트가 발견됐고, 이 응답이 비행 상태 페이지의 기반 데이터로 보임
  • 해당 엔드포인트는 쿠키나 헤더 없이도 curl로 호출 가능했고, 고도·좌표·도착 예정 시각·지상 속도·남은 거리·비행 진행률·위성 연결 상태 등을 반환함
  • 수집한 데이터로 고도, ETA, 지상 속도를 시각화했으며, 하강 구간을 제외하면 고도는 약 20~30피트 수준으로만 흔들림
  • 특별히 실용적인 발견은 아니었지만, 기내 WiFi 포털이 노출하는 비행 상태 JSON만으로도 비행 중 데이터 수집과 분석을 해볼 수 있음

결제 실패에서 시작된 기내 WiFi 탐색

  • Strange Loop에서 돌아오는 St. Louis-Oakland 직항편에서 Southwest의 기내 WiFi 포털을 통해 $8 인터넷 접속권을 구매하려 했지만, 어떤 결제 수단도 받아들여지지 않음
  • 웹 페이지는 도움이 되는 오류 메시지를 보여주지 않았고, 브라우저의 네트워크 개발자 도구로 실패한 요청을 확인함
  • 실패한 요청 자체에서는 단서를 찾기 어려웠지만, 반복적으로 성공하는 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 기반 브라우저에 있으며, 브라우저가 보낸 요청을 같은 헤더와 함께 재현할 때 유용함
  • 실험 결과 요청에 포함된 쿠키나 헤더는 필수적이지 않았고, 다음처럼 단순한 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을 이용해 비행 중 데이터를 수집하고 분석할 수 있음

댓글과 토론

Hacker News 의견들
  • 아들이 9~10살쯤 비행기에서 휴대폰으로 인터넷을 쓰고 있길래, 인터넷 요금을 낸 적이 없어서 어떻게 쓰는지 물어봤음
    학교 친구가 알려줬다며 Wi-Fi 설정의 DHCP 할당 IP 주소 숫자를 바꾸다 보면 된다고 했고, 당시 American Airlines는 유료 사용자의 IP만 허가하는 식이라 다른 사람이 192.168 대역 IP를 맞혀 위장하면 추가 인증 없이 연결을 가져갈 수 있었던 듯함
    하지 말라고 말하긴 했지만, 시도해보는 배짱은 조금 자랑스러웠음

    • 예전 유료 Wi-Fi 핫스팟에서 비슷하게 자주 했음
      먼저 nmap -sP로 전체 서브넷을 핑 스윕해서 ARP 캐시에 쓸 만한 IP/MAC 주소를 채운 뒤, 하나씩 IP와 MAC 주소를 바꿔 방화벽을 통과하는 조합을 찾았음
      Wayport(현재 AT&T WiFi)에서 NOC 엔지니어로 일한 덕분에 구조를 이해하는 데 도움이 됐음
    • 비행기와 호텔에서 같은 방식을 썼고, 호텔이 더 성공률이 높았음
      다른 사람이 그 순간 쓰고 있을 가능성이 낮고 끊길 가능성도 낮았기 때문임
      어릴 때 또 다른 작은 해킹도 했는데, 항공사가 기내 영화용 특수 이어폰을 팔거나 빌려주던 시절 포트가 나란한 두 구멍이고 플러그가 두 튜브였음
      탑승 전에 터미널 패스트푸드점에서 빨대, 가능하면 꺾이는 빨대를 몇 개 챙겨서 서로 이어 긴 빨대를 만들고, 한쪽을 포트에 넣고 다른 쪽을 귀에 대면 무료 영화 오디오를 들을 수 있었음
    • 몇 년 전 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)가 있긴 하지만, 각각 통신사 운영 핫스팟망과 기업 환경에 더 맞춰져 있어서 “웹 포털로 결제” 용도에는 이야기가 잘 맞지 않음
      [1] https://en.wikipedia.org/wiki/Opportunistic_Wireless_Encrypt...
    • 예전에는 이미 인터넷에 연결된 네트워크의 IP와 MAC 주소를 스캔해주는 앱이 있었음
      설정을 그중 하나의 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 기준으로 재설정하면 차이가 뚜렷하게 튀는지도 궁금함
      대형기는 어떻게 하는지 모르지만 소형기에서는 지역 날씨에 맞춰 고도계를 설정해야 함
      기상 관측소가 자기 고도의 기압을 측정해 “해수면 기준으로 보정”한 값을 무전으로 알려주고, 이를 고도계에 넣어 지역 기상 변화에 따른 기압식 고도 판독값을 보정함
      한 시간 비행하고 같은 곳으로 돌아와도 고도계 설정이 몇 밀리바 정도 달라질 수 있음
    • 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으로 보내면 집에서 웹페이지를 로드하고 HTML을 WhatsApp 답장으로 보내줘서 렌더링하는 식이 가능할 듯함
    얼마나 많은 걸 동작시킬 수 있을지 궁금함
    이미 WhatsApp으로 TCP 릴레이를 만든 사람이 있는 것 같아 멋짐

    • https://github.com/aleixrodriala/wa-tunnel
    • 이용 약관은 읽어보지 않았지만, 그냥 실제 IP 라우터를 두면 안 될까 싶음
      가입 비용을 내고 Wi-Fi 네트워크도 띄움
      비행기 SSID가 “Foo”라면 “Foo discounted”라고 이름 붙이고, 캡티브 포털에서 참전용사, 노인, 어린이 같은 여러 “할인”을 선택하게 함
      어떤 걸 고르든 결제 페이지에서 2달러를 받음
      서비스 비용을 회수하고 나면 이후 방문자에게 “모든 할인이 소진됐으니 Foo를 이용하세요”라고 보여줌
      그러면 나는 무료 인터넷을 쓰고, 라우터/포털 사용자들은 2달러 인터넷을 쓰는 셈임
      상향 대역폭은 분명 형편없을 테니 모든 데이터를 내 연결 하나에 다중화하기도 쉬울 것임
      RPi 같은 장치에 넣되 보안 검색을 통과하려면 음악 플레이어처럼 완성품처럼 보여야 하고, 테이블을 올려야 하거나 화장실에 갈 때도 계속 동작할 수 있어야 함
      비행기에 불량 Wi-Fi 연결을 끊어내는 WIPS나 WIDS가 있을 가능성은 매우 낮아 보임
      애초에 LAN 파티가 금지된 것도 아니지 않나
    • 1~2년 전 Apple Private Relay 첫 베타가 나온 지 하루이틀 뒤 비행기를 탔는데, 비행 내내 무료 Wi-Fi를 쓸 수 있었음
      아마 iMessage나 푸시 알림용으로 허용 목록에 넣은 대상이 그것까지 포함했기 때문인 듯함
      며칠 뒤 돌아오는 항공편 전에는 이미 막혀 있었음
    • “와, 멋지다”보다 “무료 메시징은 좋은 혜택인데 남용되면 닫아버릴 텐데”가 먼저 떠오름
      해커 시절은 지나간 듯함
    • 항공사 Wi-Fi가 DNS 트래픽은 막지 않는 걸 본 적 있음
      Iodine(https://github.com/yarrick/iodine) 같은 DNS 터널로도 비슷한 걸 할 수 있을 가능성이 큼
  • Southwest는 같은 데이터를 더 예쁜 화면으로 보여줌
    Wi-Fi 요금을 내지 않아도 비행 추적, 현재 고도, 도착 예정 시각, 지도상의 위치 등 많은 정보를 볼 수 있음
    아마 글쓴이가 처리 프로그램을 만든 데이터와 같은 데이터를 쓰는 듯하고, 본질적으로 무료로 방문할 수 있는 사이트가 하나 있는 셈임

    • 맞음, 정확히 그렇음
      이 데이터를 시각화해주는 멋진 상태 페이지를 무료로 볼 수 있음
      그래도 긁어온 이유는 두 가지였음
      첫째, 상태 페이지는 현재 값만 보여주기 때문에 전체 비행 데이터를 보고 싶었음
      둘째, 재미있었음
    • 최근 미국 항공편, 아마 Alaska Airlines였던 것 같은데, 인터넷 접속 없이도 Wi-Fi로 영화와 TV 프로그램을 볼 수 있는 로컬 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"

    • 비슷하게 느꼈음
      이 시스템을 설계한 사람이 서버에서 시간을 항공편 위치 기준으로 보이는 지역화 표현으로 변환해두고, 클라이언트 쪽 로직 없이 웹 UI에 바로 넣으려 했던 것 같음
    • ctime이 쓰는 기본 형식처럼 보임
      기반 백엔드에 대한 단서일 수도 있음
      https://cplusplus.com/reference/ctime/ctime/