使用 setuid 进程发送终止信号导致操作不允许

使用 setuid 进程发送终止信号导致操作不允许

我希望能够从使用与 Prometheus 不同的用户运行的 CI 工具向 Prometheus 进程发送 SIGHUP 信号。假设 CI 使用gitlab-runner用户,Prometheus 使用prometheus用户。我认为我可以通过以下步骤向 Prometheus 进程发送 SIGHUP 信号:

  1. 创建一个执行命令的简单 shell 脚本kill
$ cat `which promhup`
kill -HUP $(pgrep prometheus)
  1. 更改此脚本的所有权并设置setuid此文件的位:
chown prometheus promhup
chmod +x promhup
chmod u+s promhup

然后,我期望如果我简单地运行promhup,它就可以向 Prometheus 进程发送所需的信号。但是,我收到以下错误:

/usr/bin/promhup: line 1: kill: (602) - Operation not permitted

权限现在如下所示:

$ ls -l `which promhup`
-rwsr-xr-x 1 prometheus root 51 Jan 27 19:36 /usr/bin/promhup

我做错了什么?如何在不授予sudoCI 用户访问权限的情况下实现此目的?

答案1

出于安全原因,Linux 忽略脚本/解释可执行文件(以 #! 开头的脚本)上的 setuid 位。

作为一种 hack 解决方案,您可以尝试使用以下方法从脚本中编译出一个简单的二进制文件https://github.com/neurobin/shc并将其设置为:

sudo add-apt-repository ppa:neurobin/ppa
sudo apt-get install shc

shc -f my_promhup_script -o promhup
sudo mv promhup /usr/bin/

尽管我更愿意选择 sudo 选项 - 但这就是它的设计目的。

更新:

对于 sudo 选项,您可以向 sudoers 添加类似这样的内容:

gitlab-runner ALL = (ALL) ALL
gitlab-runner ALL = (root) NOPASSWD: /usr/bin/promhup

这将使你的 sudo 不仅在为你的脚本询问密码,同时为其他脚本询问密码

来源:https://unix.stackexchange.com/questions/18830/how-to-run-a-specific-program-as-root-without-a-password-prompt

答案2

@OWGrant 的回答的第一段给出了解决这个问题的很好的观点:

出于安全原因,Linux 忽略脚本/解释可执行文件(以 #! 开头的脚本)上的 setuid 位。

它启发我用 C 语言编写了一个等效的程序,它可以工作:

#include <stdlib.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
  FILE *fp;
  char pid[10];

  fp = popen("/usr/bin/pgrep prometheus", "r");
  if (fp == NULL)
    exit(1);

  fgets(pid, sizeof(pid), fp);

  char* ptr = pid;
  while(ptr) {
    if(*ptr == '\n') {
      *ptr = '\0';
      break;
    }
    ptr++;
  }

  pclose(fp);

  char* args[] = {"/usr/bin/kill", "-HUP", pid, NULL};
  execvp(args[0], args);

  return 0;
}

用法如下:

gcc promhup.c -o promhup
chmod +x promhup
chown prometheus promhup
chmod u+s promhup
sudo mv promhup /usr/bin

然后运行一个简单的promhup命令就会SIGHUP向 Prometheus 进程发送一个信号。

相关内容