因此,我的一个软件必须通过 deb 包分发,它包含一个小型自定义服务器。该服务器需要能够侦听特权端口,因为向客户解释诸如“我们有非标准 RTSP 端口,因为无法正确处理权限”之类的内容听起来很糟糕。
好的,首先我尝试测试这个概念并在终端中打印以下内容:
setcap CAP_NET_BIND_SERVICE=+ep /opt/path/my_binary
一切工作正常,所以看起来相同的命令应该在我的安装后脚本中工作,让我们称之为postinst.1.server
:
...
...
printf "something" > /opt/somewhere || exit 15
setcap CAP_NET_BIND_SERVICE=+ep /opt/path/my_binary || exit 16
安装没有错误,因此该命令一定可以正常工作...但是,不,由于缺乏权限,该端口不可用于服务器(当然,手动执行该命令又可以解决问题)。
好吧...所以我要去 systemd,因为目标服务器的可执行文件被设计为由服务管理。自定义 systemd 配置如下:
[Unit]
Description=Some description
After=network.target
Requires=postgresql.service
[Service]
Type=notify
WorkingDirectory=/opt/some_path
Restart=always
RestartSec=15000ms
User=server_user
Group=server_user
Environment=XAUTHORITY=/tmp/.Xauth
Environment=DISPLAY=:0
ExecStart=/opt/path/server_executable run
TimeoutStartSec=10000ms
WatchdogSec=6666ms
TimeoutStopSec=7000ms
# My new attempt to fix capabilities
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETUID CAP_SETGID
[Install]
WantedBy=multi-user.target
乐观的希望是server_executable
启动my_binary
后子进程可以继承这些功能……但运气不佳。
目前我仍在尝试在安装后脚本中设置所需的功能,但完全不知道为什么该命令仅在手动执行后才有效。
一些“调试”让我得到了一些更奇怪的结果:
- 在安装后脚本中写入
getcap /opt/ksvd4/ksvd4_portale.exe 2>&1
会打印出正确的功能,但它们在安装结束时恰好消失了(之后手动检查) - 在 setter 命令调用之后立即使用
-v
选项(验证)也会导致“好的”,证明能力消失。
如果有人能指出我实现这一技巧的正确方法,或者至少找到破坏当前解决方案尝试的隐藏问题,我将不胜感激。
操作系统是 Ubuntu 16.04(如果有的话)。
答案1
不是完整的答案,但可能有帮助。
如果可执行文件具有此功能,那么您应该使其只能由特定组执行(以防止随机用户抢占端口)。
如果您正在创建一个新程序,那么您应该使其能够感知功能(使用功能系统调用,将功能移入和移出有效集)。因此不需要在文件功能中设置有效位。
文件功能(和 setuid/setgid )仅适用于静态链接的二进制文件。
功能在新进程中持续存在 ( fork
),但在新的可执行文件/程序中不存在 ( exec
)。您可以使用环境功能来持久化exec
(您必须让调用者(执行程序)了解功能(在编写代码时牢记功能)。