我正在寻找一个安全的地方来放置 Unix 域套接字,该套接字将用于控制 REPL。
在 Linux 上,我会使用/run/user/$UID
,它满足除可移植性之外的所有要求。我需要处理它们的程序是可移植的。
一种选择是使用下面的目录,~
但这会遇到不同的问题:由于路径长度的限制,用户的主目录可能位于太深而无法绑定 Unix 域套接字的目录中。
将套接字放在下面的目录中/tmp
是可移植的,但我担心删除目录时的竞争条件。我还担心是否/tmp
可以在所有平台上设置粘性位(即用户无法删除或重命名其他用户的临时文件)。然而,我假设它/tmp
是粘性的,否则许多应用程序(每个使用的脚本mkstemp
)都是不安全的。
我当前的计划是让服务器在 中 创建一个临时目录/tmp
,并让客户端在使用套接字之前检查包含目录的所有权。这对于安全来说足够了吗?
答案1
这法律上的标准临时文件的位置在环境变量中给出TMPDIR
。
该变量应表示可供需要创建临时文件的位置的程序使用的目录的路径名。
事实上,很多系统并没有定义TMPDIR
。这事实上的临时文件的标准位置是/tmp
.因此,请检查TMPDIR
,如果未设置,请使用/tmp
。在 shell 脚本中,您可以使用${TMPDIR:-/tmp}
,或者如果您觉得它更方便,
if [ -z "$TMPDIR" ]; then TMPDIR=/tmp; fi
或应付set -u
: "${TMPDIR:=/tmp}"
您可以假设该位置是可写的,但它可能是世界可读和世界可写的,因此:
- 创建常规文件时,请始终确保不会覆盖现有文件,因为该文件可能不属于您。不要为此使用 shell 重定向。单独测试所有权并不安全,因为对手可能会在程序运行时移动符号链接来欺骗检查。此外,您不能依赖不存在的特定名称;为了防止并发程序通过在您之前创建同名文件来造成拒绝服务,请使用随机名称。您可以使用
mktemp
实用程序(广泛使用,存在于 GNU、BusyBox、BSD,但不存在 POSIX)或mkstemp
C 库函数。在幕后,open
还是creat
必须用旗帜来称呼O_EXCL
。 - 您可以使用 来创建目录
mkdir
。这可以防止所有权欺骗窃取,因为这不会重用现有文件,但它很容易像常规文件一样出现拒绝服务的情况,因此您应该使用随机名称。mktemp -d
是一个很好的方法来做到这一点。 - 您可以创建一个套接字(没有标准的 shell 实用程序)。与目录情况一样,它可以防止所有权欺骗,但不能防止拒绝服务。
Linux 尊重命名套接字上的权限,但有些 Unix 变体则不尊重。这就是为什么/tmp
通常在子目录中创建套接字的原因。
创建子目录/tmp
(或$TMPDIR
如果设置)并创建命名套接字的程序包括 X11 服务器、ssh-agent、gpg-agent、KDE、emacs,...(这只是我发布此文章的计算机上存在的程序) )。正如您所看到的,您将会有很好的陪伴。