【问题标题】:access GPSD port 2947 over network通过网络访问 GPSD 端口 2947
【发布时间】:2017-07-03 14:31:09
【问题描述】:

使用来自 digitalbarbedwire.com 的帖子中的信息,使用 2017 年 1 月的最新 Jessie Lite Raspbian 和 Adafruit Ultimate GPS 帽子和 PPS 获得 RPI2。简单的设置和 PPS 以及所有 gps 命令在本地运行良好。

我试图让 gpsd 在端口 2947 上接受来自网络的传入请求以导出位置信息 (OpenCPN)。我编辑了 /etc/default/gpsd 以添加 -G 选项 GPSD_OPTIONS="-n -G" 但不允许外部请求。如果我停止 gpsd(sudo service stop gpsd),并在前台调用 gps(/usr/sbin/gpsd -N -n -G /dev/ttyAMA0 /dev/pps0,一切正常!所以我猜有一个将 gpsd 作为守护进程启动的权限问题,但我还没有弄清楚。让我发疯!

有什么建议吗?

相关文件:

$ cat /lib/systemd/system/gpsd.socket
[Unit]
Description=GPS (Global Positioning System) Daemon Sockets

[Socket]
ListenStream=/var/run/gpsd.sock
ListenStream=[::1]:2947
ListenStream=0.0.0.1:2947
SocketMode=0600

[Install]
WantedBy=socket

$ cat /etc/default/gpsd
# Default settings for the gpsd init script and the hotplug wrapper.

# Start the gpsd daemon automatically at boot time
START_DAEMON="true"

# Use USB hotplugging to add new USB devices automatically to the daemon
USBAUTO="true"


# Devices gpsd should collect to at boot time.
# They need to be read/writeable, either by user gpsd or the group dialout.
DEVICES="/dev/ttyAMA0 /dev/pps0"

# Other options you want to pass to gpsd
GPSD_OPTIONS="-n"

$ cat /lib/systemd/system/gpsd.service
[Unit]
Description=GPS (Global Positioning System) Daemon
Requires=gpsd.socket
# Needed with chrony SOCK refclock
After=chronyd.service

[Service]
EnvironmentFile=-/etc/default/gpsd
ExecStart=/usr/sbin/gpsd -N -G $GPSD_OPTIONS $DEVICES

[Install]
Also=gpsd.socket

有什么想法吗?

【问题讨论】:

    标签: systemd gpsd


    【解决方案1】:

    Linux Mint 19,我必须将 127.0.0.1 替换为 0.0.0.0,然后才能在 LAN 上共享 GPS 数据

    #/lib/systemd/system/gpsd.socket/gpsd.socket
    
    [Unit]
    Description=GPS (Global Positioning System) Daemon Sockets
    
    [Socket]
    ListenStream=/var/run/gpsd.sock
    ListenStream=[::1]:2947
    #ListenStream=127.0.0.1:2947
    ListenStream=0.0.0.0:2947
    SocketMode=0600
    
    [Install]
    WantedBy=sockets.target
    

    【讨论】:

      【解决方案2】:

      另一种方法是使用端口转发进行无终端 SSH 会话。

      例如,假设您有 PC1 运行 gpsd 服务(通过 systemd 或独立)。

      在 PC2 上,您可以这样做:

      ssh -N -L 2947:localhost:2947 user@PC1
      

      -N 标志阻止实际的终端会话(不执行任何命令)。 -L 标志表示将端口 2947 转发到 localhost 2947。

      现在,如果由于某种原因会话丢失或终止,ssh 将不会自动重新连接。解决方法是安装autossh,在大多数 linux 发行版存储库中都可用。

      然后您可以像这样使用 autossh:

      autossh -N -M 0 -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -L 2947:localhost:2947 user@PC1
      

      如果有效,添加 -f 让 autossh 进入后台模式。

      您可以轻松地从 rc.local 或 systemd 单元运行 autossh。这样做意味着您只需要在 (22) 中允许 SSH 端口,并且现在通过安全加密连接传递 gps 信息,这是单独的 gpsd 套接字会话无法做到的。显然,如果您在 PC1 和 PC2 之间设置密钥对会有所帮助,因为您不需要密码。

      您可以在 PC2 上运行任何随附的 gpsd 工具,因为它会显示为本地。来自脚本/程序的 API 调用也将像端口 2947 实际在本地运行 gpsd 一样工作。

      Look here for more detail on how to use autossh.

      【讨论】:

        【解决方案3】:

        Gpsd 实际上并没有监听 2947 端口,systemd 是。默认情况下,在 Debian 中,这只是本地的。当一个请求进入 systemd 时,如有必要,启动 gpsd,并将未来的请求重定向到守护进程。所以给 gpsd 的 -G 参数实际上不会改变任何东西。

        您需要为 systemd gpsd.socket 单元添加一个覆盖,并告诉它监听所有地址:

        # /etc/systemd/system/gpsd.socket.d/socket.conf
        [Socket]
        # First blank ListenStream clears the system defaults
        ListenStream=
        ListenStream=2947
        ListenStream=/var/run/gpsd.sock
        

        最佳做法是将此覆盖文件放在 /etc/systemd/ 中,而不是在 /lib/systemd/ 中编辑单元文件。

        有关 systemd.socket 语法的文档:https://www.freedesktop.org/software/systemd/man/systemd.socket.html

        【讨论】:

        • 我挣扎了大约 8 个小时才发现ListenStreams 的顺序很重要!反之亦然:/var/run/gpsd.sock unix 套接字应在清除后首先指定,因为它是 systemd 套接字进程的默认通信方式。正确的顺序是ListenStream= ListenStream=/var/run/gpsd.sock ListenStream=2947
        • 感谢 Dima 的最后一块拼图!
        猜你喜欢
        • 2021-09-14
        • 2014-05-14
        • 2016-12-30
        • 1970-01-01
        • 2011-12-15
        • 1970-01-01
        • 2023-03-17
        • 2018-04-02
        • 2010-09-09
        相关资源
        最近更新 更多