root 和非 root 用户之间的 unix 域套接字权限和 umask 集成

root 和非 root 用户之间的 unix 域套接字权限和 umask 集成

我试图了解 unix 域套接字的权限,当使用现有文件时,需要更改 umask 以及 dir 权限。

如果我以 root 身份创建一个世界可读的目录并使用 netcat 打开一个套接字:

root$: mkdir /tmp/mydir
root$: chmod 777 /tmp/mydir
root$: nc -l -U /tmp/mydir/sock

然后,作为非 root 用户尝试连接到上述套接字,它会失败,尽管该目录是世界可读的:

https://man7.org/linux/man-pages/man7/unix.7.html

在 Linux 实现中,路径名套接字尊重它们所在目录的权限。如果进程对创建套接字的目录没有写入和搜索(执行)权限,则新套接字的创建将失败。

root$: runuser -u user1 -- nc -U /tmp/mydir/sock 
nc: unix connect failed: Permission denied

现在通过执行umask 0,并再次重新启动同一个套接字,它从非 root 用户连接到。

root$: umask 0
root$: nc -l -U /tmp/mydir/sock
root$: runuser -u user1 -- nc -U /tmp/mydir/sock 
ping 

此外,修改/tmp/mydir权限chmod 600将阻止非 root 用户再次访问套接字。

root$: chmod 600 /tmp/mydir
root$: runuser -u user1 -- nc -U /tmp/mydir/sock 
nc: unix connect failed: Permission denied

很明显,根据手册,目录权限按预期工作,但是如果父目录具有正确的权限,为什么需要 umask 0 ? netcat 是否仍在创建某种其他文件?

答案1

你同样错过了这个UNIX(7)您引用的联机帮助页:

在 Linux 上,连接流套接字对象需要写权限 在那个插座上;向数据报套接字发送数据报同样需要该套接字的写权限。

当然,您还需要对其路径中的所有主要目录进行搜索(执行)权限,就像任何其他文件一样。

你引用的部分指的是创造一个套接字,其中仅有的bind(2)ing 到它时会发生,这就是事实nc -l -U /path/to/sock。同样,就像创建任何其他文件一样,umask 将影响创建的套接字的权限(umask == 022 => 其他用户没有写权限 => 他们无法连接到套接字):

$ umask
0022
$ nc -Ul sock
^C
$ ls -l sock
srwxr-xr-x 1 xxx xxx 0 Oct 16 18:35 sock
^    ^  ^

绑定到 unix 域套接字总是必须从头开始创建它。您无法绑定到现有文件,这将失败并显示EADDRINUSE.因此,大多数程序(包括nc)将在绑定到任何同名文件之前强制删除该文件:

$ echo text > file
$ strace nc -l -U file
...
socket(AF_UNIX, SOCK_STREAM, 0)         = 3
unlink("file")                          = 0
bind(3, {sa_family=AF_UNIX, sun_path="file"}, 110) = 0
listen(3, 5)                            = 0
accept4(3, 

注意:两个片段都讨论了磁盘上的“套接字”特殊文件/索引节点,而不是表示活动套接字对象的索引节点(出现在/proc/<pid>/fd/proc/net/unix等中):

$ nc -lU sock &
[1] 4424
$ ls -li sock
20983212 srwxr-xr-x 1 xxx xxx 0 Oct 17 18:01 sock
^^^^^^^^
$ ls -li /proc/4424/fd
total 0
43825 lrwx------ 1 xxx xxx 64 Oct 17 18:02 0 -> /dev/pts/4
43826 lrwx------ 1 xxx xxx 64 Oct 17 18:02 1 -> /dev/pts/4
43827 lrwx------ 1 xxx xxx 64 Oct 17 18:02 2 -> /dev/pts/4
43828 lrwx------ 1 xxx xxx 64 Oct 17 18:02 3 -> socket:[46378]
                                                        ^^^^^
$ grep 46378 /proc/net/unix
00000000ee8c0faa: 00000002 00000000 00010000 0001 01 46378 sock

相关内容