Linuxセキュリティのベストプラクティス:CAP_SETFCAPおよびsudoerファイル

Linuxセキュリティのベストプラクティス:CAP_SETFCAPおよびsudoerファイル

私はLinux証券に最初に触れ、Linux機能のベストプラクティスが何であるかを理解しようとしています。私のシナリオは次のとおりです。

他の実行可能ファイルに付与された権限を必要とするfoo実行可能ファイル(と呼びます)があります。CAP_SYS_NICEデフォルトでは、これを行う方法は2つあります。

  1. fooユーザーsetcapGrantがBinary呼び出しを開始できるように、sudoerファイルにルールを追加しますCAP_SYS_NICE。たとえば、この機能をuser ALL=(root) NOPASSWD: /usr/sbin/setcap cap_sys_nice+epi /path/to/target/directory/*使用してsystem新しいシェルを起動して実行します/user/sbin/setcap
  2. 実行可能ファイルからいくつかのLinuxシステム機能を呼び出すために実行可能CAP_SETFCAPファイルが付与されました。foofoocap_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_niceACLを使用してバイナリファイルを拡張できます。たとえば、プログラムを作成します。グループ実行可能だがそうではないその他実行可能ファイル(chmod o-rwx ./make_nice)とこのメンバーのみが許可されます。グループsudo chgrp nicefolk ./make_nice)を実行します。

関連情報