我们需要设置一个 SFTP 目录(在 Linux 服务器上),以便我们可以从多个来源接收文件。这些来源将共享同一个帐户来上传文件。连接时,用户被限制在一个acount_name
目录中,他们将文件上传到account_name/upload
。
但是,我们不希望最终用户能够与其他用户上传的文件进行交互。显然,系统无法区分,因为每个人都使用同一个帐户。因此,我们需要的行为是,用户可以将新文件写入文件夹,但无权访问该文件夹中的任何文件。
我两次都差点成功,但还是没成功。第一次尝试非常简单,我授予用户文件夹的只写权限。使用 WinSCP,用户实际上可以将文件上传到该文件夹。但由于它没有执行权限,因此在上传完成后会显示“权限被拒绝”,因为它无法列出目录的内容。目录仍然看起来是空的,看起来好像上传没有成功。
第二次尝试时,我允许用户完全访问目录,这样用户才能真正看到目录中的文件,但我依靠默认 ACL 来实现这一点,即对于每个新文件,文件所有者和特定用户帐户都无权访问该文件。这几乎成功了,因为用户无法读取或修改他上传的任何文件。但是,它仍然可以删除文件,这显然也是我不希望看到的。
我想要做的事情真的可行吗?我没想到 ChatGPT 在这方面如此无用。
如果每个上传者都有自己的账户,那么这是可行的。我的意思是,这就是账户的用途。
否则,您无法仅使用 POSIX ACL 来实现这一点。具体来说,相同的权限(写入目录)既用于创建文件,也用于删除文件,因此您不能只允许其中一个而不允许另一个(并且由于所有文件都归同一用户所有,因此“粘性”位在这里也无济于事)。您需要一个具有 Windows/NTFS/NFSv4 样式 ACL 的系统来实现这一点。
传统 FTP 服务器通过实际服务中的逻辑实现仅上传目录,SFTP 也是如此。如果您使用的是标准 OpenSSH,其sftp-server(8)子系统会接受
-P
阻止某些协议请求(例如-P remove
)的选项,但无法区分 open-for-create 和 open-for-update 等。(但可以使用 LD_PRELOAD 对其进行修补以拒绝某些请求。)(存在其他 SFTP 服务器,例如 ProFTPd 有一个 SFTP 模块,但不太清楚它的其他面向 FTP 的配置如何与其交互。)
无论实际服务是什么,您都可以使用一些进程外方法:
一个后台作业,使用“inotify”(例如
incron
)来监视新文件,并在看到 CLOSE_WRITE 事件时立即chmod
关闭它们。chown
LD_PRELOAD 拦截从 sftp 服务器到操作系统的实际 open() 调用,当文件位于某个路径以下时拒绝打开现有文件的尝试。