在 Linux 中,SFTP 本身依赖于 SSH 子系统,默认情况下用户拥有与系统权限一致的读写删除能力。要“禁止 SFTP 删除文件”,常见且可控的方案如下(从推荐到补充):
rssh / scponly 类受限 Shell(简单但老)适合只允许上传下载、完全禁止删除、重命名等
scponly:只能 scp/sftp 读和写,不能执行命令⚠️ 这两种工具目前已较少维护,不推荐新系统使用。
OpenSSH + 自定义 SFTP 包装脚本(最灵活 ✅)用 Subsystem sftp internal-sftp 改为调用自定义脚本,在脚本中过滤掉 remove / rmdir 等命令。
vi /usr/local/bin/sftp-no-delete.sh
内容:
#!/bin/bash
exec /usr/lib/openssh/sftp-server -e 2> >(grep -v -E 'remove|rmdir' >&2)
或更严格(禁止删除):
#!/bin/bash
while read cmd; do
case "$cmd" in
remove*|rmdir*)
echo "Permission denied"
;;
*)
echo "$cmd"
;;
esac
done | /usr/lib/openssh/sftp-server -e
实际更可靠的是用
sftp-server的-p参数限制协议命令(见下)
Subsystem sftp /usr/local/bin/sftp-no-delete.sh
或只针对某用户:
Match User sftpuser
ForceCommand /usr/local/bin/sftp-no-delete.sh
sftp-server -p 限制协议命令(官方支持)OpenSSH 的 sftp-server 支持 协议级命令白名单/黑名单
sftp-server -Q requests
输出类似:
open
close
read
write
lstat
fstat
stat
mkdir
rmdir
remove
rename
...
Subsystem sftp internal-sftp -p open,close,read,write,stat,lstat,mkdir
或针对用户:
Match User sftpuser
ForceCommand internal-sftp -p open,close,read,write,stat,lstat,mkdir
✅ 这样:
即使 SFTP 不允许,也要防止:
chattr +a /sftp/upload
+a:只能追加,不能删除或修改chattr +i file
Match User sftpuser
ChrootDirectory /sftp
ForceCommand internal-sftp -p open,close,read,write,stat,mkdir
| 需求 | 推荐方式 |
|---|---|
| 禁止删除 | internal-sftp -p |
| 禁止删除+重命名 | 同上,去掉 rename |
| 高安全 | chroot + 权限 + chattr |
| 审计 | 日志 + 只读挂载 |
如果你愿意,我可以: