基本的な
ユーザーネームスペース(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