근본적인

근본적인

근본적인

사용자 네임스페이스(CLONE_NEWUSER)은 유용한 보안 기능이지만 커널의 공격 표면을 증가시킵니다. 예를 들어, iptables에 액세스할 수 있습니다.

$ iptables -S
iptables v1.4.21: can't initialize iptables table `filter': Permission denied (you must be root)
Perhaps iptables or your kernel needs to be upgraded.
$ unshare -rn
# iptables -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT

이 네트워크 네임스페이스는 일반적인 실제 네트워크에 영향을 미치지 않지만 로컬 루트 공격에 도움이 될 수 있습니다.

또한 사용자 네임스페이스가 재정의되는 것으로 나타납니다.PR_SET_NO_NEW_PRIVS, 공격 표면을 줄이는 효과가 감소합니다.

$ ping 127.0.0.1
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.067 ms
^C
$ setpriv --no-new-privs bash
$ ping 127.0.0.1
ping: icmp open socket: Operation not permitted
$ unshare -rn
# ifconfig lo up
# ping 127.0.0.1
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.053 ms
^C

해결책

chroot 환경에서 사용자 네임스페이스가 실패함커널 3.9부터 시작. 커널 구성에서 비활성화할 수도 있습니다.

답변1

제가 직접 구현해봤습니다. 이것은 다음을 사용하는 작은 도구입니다.libseccomp:

https://github.com/vi/syscall_limiter/blob/master/ban_CLONE_NEWUSER.c

#include <linux/sched.h>                // for CLONE_NEWUSER
#include <seccomp.h>                    // for seccomp_rule_add, etc
#include <stdint.h>                     // for uint32_t
#include <stdio.h>                      // for fprintf, perror, stderr
#include <unistd.h>                     // for execve

// gcc ban_CLONE_NEWUSER.c -lseccomp -o ban_CLONE_NEWUSER

int main(int argc, char* argv[], char* envp[]) {

    if (argc<2) {
        fprintf(stderr, "Usage: ban_CLONE_NEWUSER program [arguments]\n");
        fprintf(stderr, "Bans unshare(2) with any flags and clone(2) with CLONE_NEWUSER flag\n");
        return 126;
    }

    uint32_t default_action = SCMP_ACT_ALLOW;

    scmp_filter_ctx ctx = seccomp_init(default_action);
    if (!ctx) {
        perror("seccomp_init");
        return 126;
    }

    int ret = 0;
    ret |= seccomp_rule_add(ctx, SCMP_ACT_ERRNO(1),  seccomp_syscall_resolve_name("unshare"), 0);
    ret |= seccomp_rule_add(ctx, SCMP_ACT_ERRNO(1),  seccomp_syscall_resolve_name("clone"), 1, SCMP_CMP(0, SCMP_CMP_MASKED_EQ, CLONE_NEWUSER, CLONE_NEWUSER));

    if (ret!=0) {
        fprintf(stderr, "seccomp_rule_add returned %d\n", ret);
        return 124;
    }

    ret = seccomp_load(ctx);
    if (ret!=0) {
        fprintf(stderr, "seccomp_load returned %d\n", ret);
        return 124;    
    }

    execve(argv[1], argv+1, envp);

    perror("execve");
    return 127;
}
$ ban_CLONE_NEWUSER /bin/bash
$ unshare -r
unshare: unshare failed: Operation not permitted

관련 정보