我读了以下问题(Shell 脚本 mktemp,创建临时命名管道的最佳方法是什么?)但我想知道使用临时命名管道在程序之间传输敏感数据是否比使用未命名/匿名 shell 管道更可取?
具体来说,我感兴趣的是这种类型的方法(来自http://blog.kdecherf.com/2012/11/06/mount-a-luks-partition-with-a-password-protected-gpg-encrypted-key-using-systemd/) 是安全的:
# Open the encrypted block device
gpg --batch --decrypt $key_file 2>/dev/null | sudo $CRYPTSETUP -d - luksOpen $mount_device $key >& /dev/null || exit 3
在什么情况下 Luks 密钥文件可能被劫持?
答案1
您建议的命令行是安全的。
在所有其他条件相同的情况下,“普通”匿名管道(使用系统pipe(2)
调用或 shell 熟悉的|
语法创建)总是比命名管道更安全,因为系统外部的其他东西获取任一管道的方法较少管道末端。对于普通的匿名管道,如果您已经拥有管道的文件描述符,则只能从管道中读取或写入,这意味着您必须是创建管道的进程,或者必须继承它(直接或间接)从该进程,或某个具有文件描述符的进程故意通过套接字将其发送给您。对于命名管道,如果您还没有管道的文件描述符,则可以通过按名称打开它来获取管道的文件描述符。
在像 Linux 这样的操作系统上,/proc
总是有可能另一个进程可以窥视/proc/pid/fd
属于不同进程的访问文件描述符,但这对于管道(无论何种类型)来说并不是唯一的,就这一点而言,它们可以窥视另一个进程进程的内存空间也是如此。 “窥视者”必须在与主题或根用户相同的用户下运行,因此这不是安全问题。
答案2
Linux 上的管道是可以拦截的,/proc/$pid/fd/$thePipeFd
就好像它们是由管道创建者创建的未链接的 fifo 一样(我猜应用了它们的 umask?)。
如果从非 root shell 启动,则可以查找管道读取端的 fd 并获取数据,然后再次重写数据以隐藏窥探。
/proc/sys/kernel/yama/ptrace_scope
如果进程不使用文件系统来存储私有数据,则进程仍然期望具有来自相同 uid 进程的隐私(除非您通过 允许来自非相关进程的 ptrace 附件)。
不幸的是,Linux 上的管道似乎相当于使用带有未链接文件的文件系统。
我相信socketpair
应该是一个更安全的替代品pipe()
。虽然也通过 暴露/proc/$pid/fd/$sockeFd
,但访问/proc/$pid/fd/
文件可以通过open
ing 文件来工作,但是套接字不可open
用(通过重新创建的未链接命名 unix 套接字进行连接不会为您提供与未链接套接字的绑定器的连接)。
(为了更加严格的安全性,socketpair
父母和孩子之间的通信应该通过作为辅助凭证与消息一起发送的 pid 来进一步加强,但这不是必需的,IMO。)。
或者,共享匿名内存也应该可以工作,但这并不能很好地映射(双关语)到外壳(您可以创建一个二进制文件来允许您这样做./socketline 'command0 ...' \| 'command1 ...' \| 'command 2...'
)。