Linux 安全最佳实践:CAP_SETFCAP 与 sudoer 文件

Linux 安全最佳实践:CAP_SETFCAP 与 sudoer 文件

我是 Linux 证券新手,并试图了解 Linux 功能的最佳实践是什么。这是我的场景:

我有一个可执行文件(我们称之为foo),它需要授予CAP_SYS_NICE其他一些可执行文件的权限。基本上我有两种方法可以做到这一点:

  1. foo在 sudoer 文件中添加一条规则,允许开始调用binary 的用户setcapgrant CAP_SYS_NICE。例如类似这样的东西user ALL=(root) NOPASSWD: /usr/sbin/setcap cap_sys_nice+epi /path/to/target/directory/*,然后使用system函数启动一个新的 shell 来运行/user/sbin/setcap.
  2. 授予CAP_SETFCAP可执行文件foo,以便在可执行文件中foo我可以调用一些linux系统函数,即cap_set_file https://linux.die.net/man/3/cap_set_file

有人可以告诉我每种方法的优点/缺点是什么,以及这种情况的最佳实践是什么?

答案1

最佳实践是编写一个专用程序,CAP_SYS_NICE以您需要的方式授予目标二进制文件。

如果目标二进制文件必须具有某些文件名模式、所有权或其他属性,请在应用该功能之前检查专用程序的代码中的详细信息。一个简单的例子:

/* make_nice.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/capability.h>

#ifndef base
#define base "/only/allowed/base/directory/"
#endif

int main(int argc, char **argv) {
    static cap_value_t c_sys_nice = CAP_SYS_NICE;
    static cap_value_t c_setfcap = CAP_SETFCAP;

    if (argc != 2) {
        fprintf(stderr, "usage: make_nice <path>\n");
        exit(1);
    }
    if (strncmp(argv[1], base, sizeof(base)-1)) {
        fprintf(stderr, "<path> must have prefix: %s\n", base);
        exit(1);
    }
    if (strstr(argv[1], "/../") != NULL) {
        fprintf(stderr, "<path> must not contain /../\n");
        exit(1);
    }
    /* should probably confirm no symlinks in argv[1] too... */
    cap_t fc = cap_init();
    if (fc == NULL) {
        perror("no memory for cap_t");
        exit(1);
    }
    cap_t pc = cap_get_proc();
    if (pc == NULL) {
        perror("serious problem");
        exit(1);
    }
    cap_set_flag(pc, CAP_EFFECTIVE, 1, &c_setfcap, CAP_SET);
    if (cap_set_proc(pc)) {
        perror("failed to raise CAP_SETFCAP");
        exit(1);
    }
    cap_set_flag(fc, CAP_PERMITTED, 1, &c_sys_nice, CAP_SET);
    if (cap_set_file(argv[1], fc)) {
        perror("failed to set CAP_SYS_NICE");
        exit(1);
    }
    exit(0);
}

为了测试目的,像这样编译并运行它:

$ gcc -Dbase=\"$(pwd)/\" make_nice.c -o make_nice -lcap
$ sudo setcap cap_setfcap=p ./make_nice
$ touch test_target
$ ./make_nice $(pwd)/test_target
$ getcap -r .
./test_target cap_sys_nice=p
./make_nice cap_setfcap=p

最佳实践部分是:

  1. 代码make_nice有责任确保它仅将CAP_SYS_NICE功能应用于应该具有该功能的文件。
    • 在某些情况下,您甚至可以编译二进制文件--static以避免glibc升级时出现任何意外...
  2. 您可以make_nice使用 ACL 来扩充二进制文件。例如,使程序团体可执行,但不是其他可执行 ( chmod o-rwx ./make_nice) 且仅允许该成员团体( sudo chgrp nicefolk ./make_nice) 来运行它。

相关内容