1 puntos por GN⁺ 2 시간 전 | 1 comentarios | Compartir por WhatsApp
  • Tras el cierre del servicio de ubicación GPS de Mozilla, la detección de ubicación basada en GeoClue en Linux se volvió imprecisa, y where-am-i ubicaba la posición cerca de Toronto con una precisión de 25 km mediante GeoIP
  • Aprovechando que un servidor doméstico fijo no se mueve, se configuró para emitir localmente las coordenadas GPS deseadas dentro de la red de casa
  • GeoClue tenía network-nmea activado por defecto en /etc/geoclue/geoclue.conf, y obtenía la información GPS buscando el servicio mDNS _nmea-0183._tcp
  • nmea-static-gps-server emite mensajes GPS NMEA 0183 por TCP una vez por segundo y registra el servicio _nmea-0183._tcp con Avahi
  • Tras reiniciar GeoClue, el cliente detectó de inmediato las coordenadas del servidor, y el resultado devolvió la descripción GPS GGA+RMC y una precisión de 0 meters; Gnome Maps mostró enseguida la ubicación correcta

Configuración de GeoClue y NMEA

  • Tras el cierre del servicio de ubicación GPS de Mozilla, la precisión de ubicación en Linux bajó, y GeoClue, que usan Firefox y Gnome Maps en varios sistemas Linux, ubicaba la posición cerca de Toronto mediante GeoIP con una precisión de 25 km, según where-am-i
  • La demo where-am-i puede instalarse desde los paquetes de cada distribución
    # Fedora  
      sudo dnf install geoclue2-demos  
    
    # Debian family  
      sudo apt install geoclue-2-demo  
    
  • Aprovechando que un servidor doméstico fijo no se mueve, se configuró para emitir localmente las coordenadas GPS deseadas dentro de la red de casa
  • El protocolo utilizado fue NMEA 0183, un conjunto de especificaciones para electrónica marina, cuyos mensajes pueden enviarse por puerto serie o por socket TCP
  • Un ejemplo de mensaje GPS está compuesto por líneas GPRMC y 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  
    
  • En /etc/geoclue/geoclue.conf, GeoClue tenía network-nmea activado por defecto
    # Network NMEA source configuration options  
      [network-nmea]  
    # Fetch location from NMEA sources on local network?  
      enable=true  
    
  • GeoClue busca un servicio mDNS llamado _nmea-0183._tcp, y cuando encuentra el registro se conecta a esa dirección para obtener la información GPS

Implementación del servidor y verificación de funcionamiento

  • nmea-static-gps-server es un servidor TCP que emite información GPS una vez por segundo y registra el servicio _nmea-0183._tcp con Avahi
  • Avahi es la implementación estándar de mDNS en Linux; en Mac, Bonjour cumple la misma función, y mDNS también se usa para direcciones .local o para descubrir dispositivos como impresoras y TVs en la red local
  • El repositorio incluye una configuración de servicio de Avahi como la siguiente
    <?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>  
    
  • Después de copiar este archivo en /etc/avahi/services/nmea-statis-gpc.service, es posible comprobar el descubrimiento del servicio desde otra máquina con 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 = []  
    
  • Cuando el servicio estaba ejecutándose en node05.local, también se podía probar fácilmente el propio servidor TCP con telnet node05.local 10110
  • Al reiniciar GeoClue en el cliente, detectó de inmediato las coordenadas del servidor
    $ sudo systemctl restart geoclue  
    $ /usr/libexec/geoclue-2.0/demos/where-am-i  
    
  • El resultado devolvió las coordenadas exactas del servidor y la descripción GPS GGA+RMC, y la precisión aparecía como 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 mostró enseguida la ubicación correcta, mientras que Firefox necesitó reiniciarse
  • En Apple Maps de Mac también parecía funcionar al desactivar Location Services, pero en el mapa no aparecía un punto exacto, sino solo la región aproximada correcta
  • Este método hace que las máquinas Linux en casa obtengan de inmediato la ubicación correcta sin esperar consultas GPS lentas e imprecisas, y también puede usarse para falsear una ubicación incorrecta a invitados o colegas que usen Linux
  • https://github.com/evert/nmea-static-gps-server

1 comentarios

 
GN⁺ 2 시간 전
Comentarios de Lobste.rs
  • No tenía idea de que existiera un servicio mDNS estándar para anunciar GNSS en una LAN, y esto me resolvió de inmediato un problema al que le había estado dando vueltas de forma intermitente durante unos 6 meses

    • ¿Puedes compartir qué estás construyendo? Mi pequeño proyecto resuelve un problema específico, pero tenía curiosidad por saber si hay usos más amplios
  • La suplantación de ubicación por GPS es una buena idea, pero parece que en la práctica implica bastante trabajo implementarla
    Estaría bien que hubiera una opción simple en la configuración de Android o en una extensión de Firefox, algo como “usar ubicación real / usar ubicación personalizada”
    Aunque también me pregunto qué tanto peso se le da a la ubicación GPS cuando entra en conflicto con otros factores como la IP o la configuración regional
    Además, por un momento me saqué de onda al ver una foto de Jeff Geerling al final de la página, y solo después me di cuenta de que no era el autor, sino que simplemente le había dado like
    Si puedo evitarlo, por lo general prefiero no usar sus cosas

    • ¿Por qué dices “por lo general prefiero no usar sus cosas si puedo evitarlo”?
    • Creo que Android sí tiene algo así. Es una función solo para desarrolladores llamada Mock Locations
      Usé un receptor GNSS de Trimble; no recuerdo si era por USB OTG o BLE, pero la app de Trimble actuaba como fuente de Mock Locations para que cualquier app de Android pudiera recibir las coordenadas de alta precisión del bastón topográfico, de alrededor de 2 cm, en lugar de la precisión relativamente baja del propio teléfono
  • Interesante, aunque también podría implementarlo yo mismo y hacer un script para que lo emita desde mi dispositivo Android cuando esté en la red de mi casa
    Todavía no estoy totalmente seguro de necesitarlo de verdad :p

  • No sabía que NMEA 0183 era un conjunto de especificaciones para equipos electrónicos marinos
    Nunca había tenido tanta curiosidad como para buscar qué significaba NMEA, pero sí conocía el nombre por ModemManager y los módems de 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