로컬 네트워크에서 GPS 브로드캐스트하기
(evertpot.com)- Mozilla의 GPS location service 종료 이후 Linux의 GeoClue 기반 위치 확인이 부정확해져,
where-am-i가 GeoIP로 Toronto 근처를 25km 정확도로 잡았음 - 고정된 홈 서버가 움직이지 않는다는 점을 이용해 집 네트워크 안에서 원하는 GPS 좌표를 로컬로 내보내도록 구성함
- GeoClue는
/etc/geoclue/geoclue.conf에서network-nmea가 기본 활성화되어 있었고,_nmea-0183._tcpmDNS 서비스를 찾아 GPS 정보를 받아옴 - nmea-static-gps-server는 초당 한 번 NMEA 0183 GPS 메시지를 TCP로 내보내고, Avahi로
_nmea-0183._tcp서비스를 등록함 - GeoClue 재시작 후 클라이언트가 서버 좌표를 바로 잡았고, 결과는
GPS GGA+RMC설명과 0 meters 정확도를 반환했으며 Gnome Maps는 즉시 올바른 위치를 표시함
GeoClue와 NMEA 설정
- Mozilla의 GPS location service 종료 이후 Linux에서 위치 정확도가 낮아졌고, 여러 Linux 시스템에서 Firefox와 Gnome Maps가 사용하는 GeoClue는
where-am-i기준 GeoIP로 Toronto 근처를 25km 정확도로 잡았음 where-am-i데모는 배포판별 패키지로 설치 가능함# Fedora sudo dnf install geoclue2-demos # Debian family sudo apt install geoclue-2-demo- 고정된 홈 서버가 움직이지 않는다는 점을 이용해, 집 네트워크 안에서는 원하는 GPS 좌표를 로컬에서 내보내도록 구성함
- 사용한 프로토콜은 NMEA 0183이며, 선박 전자장비용 명세 묶음으로 메시지를 직렬 포트나 TCP 소켓으로 보낼 수 있음
- 예시 GPS 메시지는
GPRMC와GPGGA줄로 구성됨$GPRMC,204049.000,A,5308.3999,N,00601.9266,E,0.000,0.000,030526,,*02 $GPGGA,204049.000,5308.3999,N,00601.9266,E,1,08,1.0,119.0,M,0.0,M,,*6F - GeoClue는
/etc/geoclue/geoclue.conf에서 network-nmea가 기본 활성화된 상태였음# Network NMEA source configuration options [network-nmea] # Fetch location from NMEA sources on local network? enable=true - GeoClue는
_nmea-0183._tcp라는 mDNS 서비스를 찾고, 레코드를 발견하면 해당 주소에 연결해 GPS 정보를 받아옴
서버 구현과 동작 확인
- nmea-static-gps-server는 초당 한 번 GPS 정보를 내보내는 TCP 서버이며, Avahi로
_nmea-0183._tcp서비스를 등록함 - Avahi는 Linux의 표준 mDNS 구현이며, Mac에서는 Bonjour가 같은 역할을 하고, mDNS는 로컬 네트워크의
.local주소나 프린터·TV 같은 장치 검색에도 쓰임 - 저장소에는 다음과 같은 Avahi 서비스 설정이 포함됨
<?xml version="1.0" standalone='no'?> <!DOCTYPE service-group SYSTEM "avahi-service.dtd"> <service-group> <name replace-wildcards="yes">NMEA GPS (%h)</name> <service> <type>_nmea-0183._tcp</type> <port>10110</port> </service> </service-group> - 이 파일을
/etc/avahi/services/nmea-statis-gpc.service에 복사한 뒤, 다른 머신에서avahi-browse로 서비스 검색을 확인할 수 있음$ avahi-browse _nmea-0183._tcp -r -t + wlp192s0 IPv6 NMEA GPS (node05) _nmea-0183._tcp local + wlp192s0 IPv4 NMEA GPS (node05) _nmea-0183._tcp local = wlp192s0 IPv6 NMEA GPS (node05) _nmea-0183._tcp local hostname = [node05.local] address = [fe80::a8c2:15de:9af:19b] port = [10110] txt = [] = wlp192s0 IPv4 NMEA GPS (node05) _nmea-0183._tcp local hostname = [node05.local] address = [192.168.2.205] port = [10110] txt = [] - 서비스가
node05.local에서 실행 중일 때telnet node05.local 10110으로 TCP 서버 자체도 쉽게 테스트 가능함 - 클라이언트에서 GeoClue를 재시작하자 서버의 좌표를 바로 잡았음
$ sudo systemctl restart geoclue $ /usr/libexec/geoclue-2.0/demos/where-am-i - 결과는 서버의 정확한 좌표와
GPS GGA+RMC설명을 반환했으며, 정확도는 0 meters로 표시됨Client object: /org/freedesktop/GeoClue2/Client/3 New location: Latitude: 43.645758° Longitude: -79.410510° Accuracy: 0 meters Altitude: 119.000000 meters Speed: 0.000000 meters/second Description: GPS GGA+RMC Timestamp: Sun 03 May 2026 04:58:58 PM (1777841938 seconds since the Epoch) - Gnome Maps는 올바른 위치를 즉시 표시했고, Firefox는 재시작이 필요했음
- Mac의 Apple Maps에서도 Location Services를 껐을 때 작동하는 것처럼 보였지만, 지도에서 정확한 점은 나오지 않고 대략적인 지역만 맞았음
- 이 방식은 집에 있는 동안 Linux 머신들이 느리고 부정확한 GPS 조회를 기다리지 않고 올바른 위치를 즉시 잡도록 만들며, Linux 사용 게스트나 동료에게 잘못된 위치를 스푸핑하는 용도로도 쓸 수 있음
- https://github.com/evert/nmea-static-gps-server
Lobste.rs 의견들
-
LAN에서 GNSS를 광고할 수 있는 표준 mDNS 서비스가 있다는 걸 전혀 몰랐는데, 이게 6개월쯤 간헐적으로 고민하던 문제를 바로 해결해 줌
- 뭘 만들고 있는지 공유해줄 수 있음? 내 작은 프로젝트는 특정 문제 하나를 해결하지만, 더 넓은 활용처가 있는지 궁금했음
-
GPS 위치 스푸핑은 좋은 아이디어지만, 실제로 구현하려면 상대적으로 일이 꽤 많아 보임
Android 설정이나 Firefox 확장에 “실제 위치 사용 / 사용자 지정 위치 사용” 같은 단순한 옵션이 있으면 좋겠음
다만 IP나 로캘 같은 다른 요소와 충돌할 때 GPS 위치에 얼마나 큰 가중치가 주어지는지도 궁금함
덧붙여 페이지 맨 아래에서 Jeff Geerling 사진을 보고 잠깐 놀랐는데, 작성자가 아니라 좋아요를 누른 것뿐이라는 걸 뒤늦게 알아챔
가능하면 그의 작업물은 보통 피하는 편임- “가능하면 그의 작업물은 보통 피한다”는 건 왜 그런가?
- Android에 그런 기능이 있는 것 같음. 개발자 전용 기능인 Mock Locations임
Trimble GNSS 수신기를 썼었는데 USB OTG였는지 BLE였는지는 기억나지 않지만, Trimble 앱이 Mock Locations 소스가 되어 임의의 Android 앱이 휴대폰 자체의 상대적으로 낮은 정밀도 대신 측량 막대의 고정밀 좌표, 약 2cm 수준을 받을 수 있게 해줬음
-
흥미롭지만 직접 구현하고, 홈 네트워크에 있을 때 Android 기기에서 이걸 내보내는 스크립트를 만들 수도 있겠음
아직 실제로 필요한지는 완전히 확신하지 못하겠음 :p -
NMEA 0183이 해양 전자장비용 명세 묶음이라는 건 새로웠음
NMEA가 무슨 뜻인지 찾아볼 만큼 궁금해한 적은 없지만, ModemManager와 Qualcomm 모뎀을 통해 이름 자체는 알고 있었음$ qmicli -d qrtr://0 --loc-get-nmea-types Successfully retrieved NMEA types: gga, gsv, gsa $ mmcli -m any --location-status Location | capabilities: 3gpp-lac-ci, gps-raw, gps-nmea, agps-msa, agps-msb