SSHをSFTPサーバーとして実行するAmazon Linuxインスタンスがあります。クライアントがログインし、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 File Storage Gateway)は問題ないと思います。私は迷っていて、助けてくれてありがとう。
答え1
@Kensterのヒントのおかげで、この問題を発見しました。ドキュメントに記載されているように、AWS File Storage Gateway NFSマウントがハードリンクをサポートしていると誤って仮定しました。特別に定義されたしかしそれは真実ではない。
私はそれが本当だと確信していたので、最終的にstraceを使ってシステムコールを追跡するようになりました。サーバーにSSHを接続している間にSFTPクライアントをサーバーに接続する場合は、現在のSFTPプロセスのpidを取得しますps -eaf | grep sftp
。その後、straceを使用してシステムコールを追跡し、次を使用して出力をファイルに保存できます。strace -ff -p 2116 -o sftp_rename.log
ここで、-ffは子プロセスを追跡し、-pはpid、-oは出力ファイルです。
これは本当に見苦しい結果をもたらすでしょう。しかし、私が見つけた興味深い点は次のとおりです。
write(7, "\0\0\0L\0\0\0\3\0\0\0Drename old \"/testuse"..., 80) = 80
lstat("/testuser/test/asdfasdf.txt", {st_mode=S_IFREG|0664, st_size=159, ...}) = 0
link("/testuser/test/asdfasdf.txt", "/testuser/test/as.txt") = -1 ENOTSUPP (Unknown error 524)
その後、単純なリンクコマンドを使用してハードリンクを生成するようにテストしましたが、失敗しました。
# ln asdfasdf.txt link.txt
ln: failed to create hard link ‘link.txt’ => ‘asdfasdf.txt’: Unknown error 524
#
これでAWSドキュメントに戻ります。しかし、それはすべてではありません。明らかにSFTP名の変更〜するParamikoなど、一部の実装固有のベンダー固有の顧客と協力しますCMD_EXTENDED
。本当にパラミコ:
oldpath = self._adjust_cwd(oldpath)
newpath = self._adjust_cwd(newpath)
self._log(DEBUG, 'posix_rename({!r}, {!r})'.format(oldpath, newpath))
self._request(
CMD_EXTENDED, "[email protected]", oldpath, newpath
)
すべてのクライアントがこのオプションを使用するように強制する方法はないようですが、posix-rename
少なくとも何が起こっているのか、なぜ起こるのかを知っています。