You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ubuntu 22.04下C程序无需system()调用执行systemctl重启服务的方法

实现SUID Root程序重启指定系统服务(Ubuntu 22.04)

核心问题原因

system()函数会启动shell进程,而Ubuntu默认shell(bash)启动时会主动重置SUID权限(安全机制),所以即便你的程序设置了SUID root,shell进程也会失去root权限,导致systemctl无法执行。解决办法是绕过shell,直接调用exec系列函数执行systemctl,这样能保留程序的SUID root权限。

方案一:SUID Root + 直接调用execvp

C代码示例(固定指定服务)

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>

int main() {
    // 验证SUID是否生效,确保有效用户ID为root
    if (geteuid() != 0) {
        fprintf(stderr, "Error: Program must be setuid root.\n");
        return 1;
    }

    // 构造systemctl的参数列表,末尾必须以NULL结尾
    char *const argv[] = {
        "systemctl",
        "restart",
        "someService",  // 替换为你需要重启的目标服务名
        NULL
    };

    // 直接调用execvp,替换当前进程为systemctl进程
    execvp(argv[0], argv);

    // 若execvp返回,说明执行失败,输出错误信息
    perror("execvp failed");
    return errno;
}

编译与权限配置

  1. 编译程序:
gcc -o restart_service restart_service.c
  1. 设置程序所有者为root并添加SUID权限:
sudo chown root:root restart_service
sudo chmod u+s restart_service
sudo chmod a+x restart_service

完成后,任何普通用户执行./restart_service即可重启指定服务。

方案二:使用Linux Capabilities(更安全的替代方案)

SUID root权限范围过大,存在安全风险。可以通过给程序添加细粒度能力,让它无需全root权限就能执行服务重启操作:

步骤

  1. 编译上述C代码(无需设置SUID)。
  2. 给程序添加CAP_SYSTEM_CONTROL能力(该能力允许管理systemd服务):
sudo setcap cap_system_control+ep restart_service
  1. 验证能力是否生效:
getcap restart_service

输出显示restart_service = cap_system_control+ep即成功,此时普通用户执行程序即可重启指定服务。

安全注意事项

  • 固定服务名:不要让程序接受外部输入的服务名称,避免被滥用重启其他系统服务。
  • 限制程序文件权限:执行chmod 755 restart_service,确保只有root能修改程序,防止恶意篡改。
  • 优先使用Capabilities:相比SUID root,Capabilities权限范围更小,能有效降低安全风险。

内容的提问来源于stack exchange,提问作者Sunny

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 20:35:18