scp 因“协议错误:文件名与请求不匹配”而失败
Posted
技术标签:
【中文标题】scp 因“协议错误:文件名与请求不匹配”而失败【英文标题】:scp fails with "protocol error: filename does not match request" 【发布时间】:2019-07-03 01:35:22 【问题描述】:我有一个脚本,它使用 SCP 从 AWS 上的远程 Linux 主机中提取文件。在每晚运行相同的代码大约 6 个月没有问题后,它今天开始以protocol error: filename does not match request
失败。我在下面一些更简单的文件名上重现了这个问题:
$ scp -i $IDENT $HOST_AND_DIR/"foobar" .
# the file is copied successfully
$ scp -i $IDENT $HOST_AND_DIR/"'foobar'" .
protocol error: filename does not match request
# used to work, i swear...
$ scp -i $IDENT $HOST_AND_DIR/"'foobarbaz'" .
scp: /home/user_redacted/foobarbaz: No such file or directory
# less surprising...
我使用单引号的原因是我最初抓取了一个名称中带有空格的文件。为了处理空格,我已经做了好几个月的$HOST_AND_DIR/"'foo bar'"
,但是从今天开始,它只接受$HOST_AND_DIR/"foo\ bar"
。所以,我的问题已解决了,但我仍然对发生了什么感到好奇。
我用谷歌搜索了错误消息,但我没有看到任何真正的提及,这让我感到惊讶。
所涉及的两个主机在ssh -v localhost
的输出中都有OpenSSL 1.0.2g
,而bash --version
表示GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
有什么想法吗?
【问题讨论】:
这不是一个有用的评论,但我今天才开始收到这个,因为我已经每小时运行了一个月。只有在 ubuntu 上安装更新后才会发生。 我在这里发布了关于此功能的另一个问题:unix.stackexchange.com/questions/499958/… 【参考方案1】:我最终查看了源代码并找到了引发此错误的提交:
GitHub Commit
remote->本地目录副本满足由指定的通配符 用户。
此检查提供了一些针对恶意服务器的保护 发送意外的文件名,但有被拒绝的风险 由于客户端和服务器通配符之间的差异而需要文件 扩展规则。
因此,这也添加了一个新的 -T 标志来禁用检查。
他们添加了一个新标志-T
,它将忽略他们添加的这个新检查,因此它向后兼容。但是,我想我们应该看看为什么我们使用的文件名被标记为受限。
【讨论】:
非常有趣!我很确定我没有更新任何可以更新 openssh 内容的软件,但我刚刚了解了/var/log/apt/history.log*
,而且似乎 openssh 今天早上被 /usr/bin/unattended-upgrade
更新了。上次自动升级是在 2018 年 11 月。我根本不知道我的(非常普通的、未定制的)系统正在自动更新。我没有看到任何说这种自动更新是 EC2 Ubuntu 上的默认设置,但我想它一定是。
我们遇到了同样的问题,-T 也为我们解决了这个问题。有趣的是,我们在 src 和 dst 中都使用了没有任何通配符的绝对路径。我很想说这是上面提到的提交中的一个错误。在我们的环境中,scp 命令由一个 php 程序调用,该程序由一个 cron 作业执行。
这在你做scp -T "foo@bar:'/long filename/with annoying/spaces in it/that you dont want/to escape'"
时会派上用场
将alias scp='scp -T'
添加到您的.bashrc
将自动执行此操作。
that will ignore this new check they've added so it is backwards compatible
这不是向后兼容的工作原理......【参考方案2】:
就我而言,文件名中有[]
字符需要使用here 列出的选项之一进行转义。例如:
scp root@IP_ADDR:"/tmp/foo\[bar\].txt" /tmp
【讨论】:
以上是关于scp 因“协议错误:文件名与请求不匹配”而失败的主要内容,如果未能解决你的问题,请参考以下文章