web-dev-qa-db-ja.com

CAP_NET_ADMINがioctl(TUNSETIFF)の十分な権限を持たないのはなぜですか?

Rustでtun/tapプログラムを記述しようとしています。ルートとして実行したくないので、CAP_NET_ADMINをバイナリの機能に追加しました。

$Sudo setcap cap_net_admin=eip target/release/tunnel
$getcap target/release/tunnel
target/release/tunnel = cap_net_admin+eip

ただし、これは機能していません。私が読んだすべては、これがtunを作成するために必要な唯一の機能であると言いますが、プログラムはioctlでEPERMを取得します。 straceで、私はこのエラーを見ます:

openat(AT_FDCWD, "/dev/net/tun", O_RDWR|O_CLOEXEC) = 3
fcntl(3, F_GETFD)                       = 0x1 (flags FD_CLOEXEC)
ioctl(3, TUNSETIFF, 0x7ffcdac7c7c0)     = -1 EPERM (Operation not permitted)

バイナリが完全なroot権限で正常に実行されることを確認しましたが、Sudoを実行する必要はありません。ここでCAP_NET_ADMINでは不十分なのはなぜですか?

参考までに、私はLinux version 4.15.0-45このioctlがカーネルでEPERMを返すことができるのはいくつかの方法だけです( https://elixir.bootlin.com/linux/v4.15/source/drivers/net/tun.c# L2194 )そしてそれらの少なくとも1つは満足しているようです。他の人を調査する方法がわかりません:

if (!capable(CAP_NET_ADMIN))
    return -EPERM;
...
if (tun_not_capable(tun))
    return -EPERM;
...
if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
    return -EPERM;
3
Teague Lasser

あなたの_target/release/tunnel_バイナリが存在するファイルシステムは、nosuidオプションでマウントされていると思います。これは、setuidビットだけでなく、ファイル機能にも影響します。

また、set-capabilitiesまたはsetuidバイナリをトレースすることはできません-カーネルは、ptracedプロセスからexecve()を呼び出すときにファイル機能を無視します。

_$ getcap tapy
tapy = cap_net_admin+eip
$ ./tapy
tapy: {tap1}
^C
$ strace -e trace=ioctl ./tapy
ioctl(3, TUNSETIFF, 0x7ffdc5b2fef0)     = -1 EPERM (Operation not permitted)
tapy: ioctl TUNSETIFF: Operation not permitted
+++ exited with 1 +++
_
3
mosvy