我有一个运行 SSH 的 Amazon Linux 实例作为 SFTP 服务器。客户端登录,并被 chroot 到 NFS 挂载的目录中。用户可以读取、写入和删除文件,但重命名文件失败并出现非特定的“协议错误”。
这是我的sshd_config
文件的副本:
Port 22
Protocol 2
HostKey /etc/ssh/ssh_host_rsa_key
UsePrivilegeSeparation yes
KeyRegenerationInterval 3600
ServerKeyBits 1024
SyslogFacility AUTH
LogLevel INFO
LoginGraceTime 120
PermitRootLogin prohibit-password
StrictModes yes
RSAAuthentication yes
PubkeyAuthentication yes
IgnoreRhosts yes
RhostsRSAAuthentication no
HostbasedAuthentication no
PermitEmptyPasswords no
ChallengeResponseAuthentication no
PasswordAuthentication yes
X11Forwarding yes
X11DisplayOffset 10
PrintMotd no
PrintLastLog yes
TCPKeepAlive yes
#UseLogin no
AcceptEnv LANG LC_*
# Subsystem sftp /usr/lib/openssh/sftp-server -u 0002
Subsystem sftp internal-sftp -l DEBUG -u 002 -d %u
UsePAM yes
Match Group sftpusers
ChrootDirectory /autohome
AllowTCPForwarding no
X11Forwarding no
ForceCommand internal-sftp -l DEBUG -u 002 -d %u
当源和目标位于不同的文件系统上时,我已经看到对 sftp rename 的引用不起作用,但这里不是这种情况。我还看到对 sftp rename 的引用在不支持硬链接的文件系统上不起作用,但我认为我们的 NFS 服务器(AWS 文件存储网关)应该没问题。我很茫然,任何帮助表示赞赏。
感谢@Kenster 的提示,我发现了这个问题。我错误地假设 AWS 文件存储网关 NFS 挂载支持硬链接,因为文档明确指出它不支持。
我非常确定我最终使用 strace 跟踪系统调用就是这种情况。如果在 ssh 连接到服务器时将 sftp 客户端附加到服务器,则使用 .d 获取当前 sftp 进程的 pid
ps -eaf | grep sftp
。然后,您可以使用 strace 跟踪系统调用并使用以下命令将输出保存到文件中:strace -ff -p 2116 -o sftp_rename.log
其中 -ff 跟踪子进程,-p 是 pid,-o 是输出文件。这会给你一些看起来很糟糕的输出,但我发现有趣的是这一点:
然后我用一个简单的链接命令对其进行了测试,以创建一个硬链接,但失败了。
这让我回到了 AWS 的文档。但这还不是全部,显然 SFTP 重命名将与实现供应商特定
CMD_EXTENDED
协议的某些客户端(如 Paramiko)一起使用,正如Paramiko 所做的那样:似乎没有任何方法可以强制
posix-rename
所有客户端使用该选项,但至少我们知道发生了什么以及为什么。