Permissions

root 和非 root 使用者之間的 unix 域套接字權限和 umask 集成

  • October 17, 2021

我試圖了解 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 是否仍在創建某種其他文件?

您在引用的同一個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, 

注意:這兩個片段都討論了磁碟上的“套接字”特殊文件/inode,而不是代表活動套接字對象的 inode(出現在/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

引用自:https://unix.stackexchange.com/questions/673474