我有一个启动 go-ethereum (geth) 的 systemd 服务,然后它创建一个用于提供控制台的 Unix 套接字。我的问题是我的用户无法连接到 Unix 套接字,因为虽然我的用户和服务的用户都在同一组中,并且创建的文件自动由服务用户和组所有,但 geth 进程却不会t 自动向该组授予 rw 权限。我可以通过在sudo chmod 660 /path/to/socket
使用控制台之前从终端运行来自行修复此问题,但如果可能的话,我希望自动执行此操作。
我尝试过的是将这样的规则添加到[Service]
服务文件的部分:ExecStartPost=/bin/chmod 660 /path/to/socket
。我相信这不起作用,因为服务进程启动和创建套接字之间存在延迟。然后该ExecStartPost
命令失败,进而导致服务关闭。
我可以看到解决此问题的一个选项是编写一个脚本来重复检查文件是否存在,然后在检测到文件后修改文件的权限。然后我可以将规则更改为ExecStartPost=/path/to/script
.同样,一个更简单且可能不太稳健的解决方案可能是制定规则ExecStartPost=/bin/bash -c "sleep 5 && /bin/chmod 660 /path/to/socket"
。
这种解决方案是最好的选择还是 systemd 提供了一些其他/更简单的机制可以用于我的目的?
答案1
这里的基本指导原则是绑定AF_LOCAL
套接字的任何内容都应该设置其权限。否则,希斯·罗宾逊就会摇摇欲坠。
如果守护程序服务程序创建并绑定套接字,则查找允许您指定套接字权限的配置选项。不幸的是,您可能会发现该程序的作者可能没有想到人们需要这样做。
如果守护进程服务程序没有这样的配置机制,那么就考虑制作守护进程服务程序收到它的控制套接字在启动时作为一个已经打开的文件描述符,通过该LISTEN_FDS
机制传递有关该文件描述符的信息(因为大概它是一个接受连接请求的侦听套接字)。然后是服务管理,负责创建和绑定socket并设置其权限,其中systemd做有旋钮。
然后设置一个Accept=No
描述该套接字的 systemd 套接字单元,包括适当的ListenStream
设置(假设控制接口是流套接字)和一项SocketMode=0660
设置。