为什么我通过 ssh(通过 authorized_keys 的命令)执行的 tar 会损坏档案?

为什么我通过 ssh(通过 authorized_keys 的命令)执行的 tar 会损坏档案?

我想从备份机器中提取生产服务器的 tgz 转储。两台机器都运行 ubuntu 16.04。

因此,备份服务器通过 ssh 和特定的 ssh 连接到生产服务器。

生产服务器上相应用户的文件~/.ssh/authorized_keys应该只允许一个命令并施加尽可能多的限制(?我希望):

command="tar -cz --file - --ignore-command-error --ignore-failed-read /dir/ 2>/dev/null | cat",no-agent-forwarding,no-port-forwarding,no-user-rc,no-X11-forwarding ssh-rsa AABLASHKEY comment

/dir/要备份的目录在哪里?当然AABLASSHKEYcomment“真实”的值。

在这种情况下需要| cat,因为否则该 ubuntu 版本(“tar (GNU tar) 1.28”)中的 tar 将无法与 ssh (PTY) 给出的标准输出通信。stderr 应该进入 void ( 2> /dev/null)。 编辑:关于 PTY 的观点是一种误解,请参阅@grawity 的回答。

在接收端(服务器backup),我按如下方式接收它:

ssh -i /path/to/key the-user@production-server > dir.tgz

但是,如果我在服务器上创建文件并且它不是有效的存档(例如),则生成的文件的大小与存档不同gzip: stdin: invalid compressed data--crc error ... gzip: stdin: invalid compressed data--length error。大小差异为 22 字节。

如果我通过删除其中的限制允许备份服务器在生产服务器上执行任何命令,那么它就可以authorized_keys正常工作。我忽略了什么要点?

约束

  • 我确实想使用tar(而不是 rsync、rrsync 或类似的东西)。
  • 连接应由备份服务器发起
  • 生产服务器不应创建任何临时文件

解决方案

正如 @Grawity 在他的回答中指出的那样(阅读它以消除一些误解),下面这行~.ssh/authorized_keys解决了这个问题(并且在给定的 OpenSSH 版本下适用于 Ubuntu 16.04):

command="tar -cz --file - --ignore-command-error --ignore-failed-read /dir/ 2>/dev/null",restrict ssh-rsa ....

为了使 back-up-server 命令不发出警告,请连接:

ssh -o RequestTTY=no -i /path/to/key the-user@production-server > dir.tgz

答案1

在这种情况下是| cat需要的,因为否则 tar […] 将不会与 ssh(PTY)给出的标准输出对话。

不。拥有 PTY 恰恰是你的问题之一。tty 层用于处理终端控制字符,这不是你想要的根本用于其他类型的数据。

正常运行远程控制在批处理模式下(即ssh <host> <cmd>),不会在服务器端分配 PTY;它将提供一个 8 位干净通道。但是,当您不在客户端提供命令时,您需要明确添加-TRequestTTY客户端选项以禁用 TTY 请求,

远程控制-Ttheuser@prod > dir.tgz
远程控制-o 请求TTY=否theuser@prod > dir.tgz

或者提供一个虚拟命令,

ssh 用户@prod> 目录.tgz

或者使用authorized_keys选项禁止此类请求no-pty

命令=“tar -czf - /dir/ 2> /dev/null”,无 pty,限制 ssh-rsa ABCDEF

restrict是最近添加的别名,可同时禁用所有转发,包括将来可能添加的转发。它自OpenSSH 7.2。事实上,它甚至包括no-pty,尽管我在这个答案中将它单独列出。)

相关内容