首先,如果我做一个简单的事情就不会发生!所以,还有一些我不知道的东西在转换它。ssh [email protected] "cat backup.tar" > backup.tar
我需要在不授予服务器访问权限的情况下提供系统当前状态的备份。我所做的如下:
- 创建一个新用户。我们就这样称呼他吧
username
- 仅允许通过 ssh-key 访问
- 将钥匙放入
authorized-keys
- 将命令/shell 更改
/etc/passwd
为自定义脚本username
- 自定义脚本通过执行数据库转储并复制一些文件来获取数据,并最终创建一个 tar 存档到
stdout
- 确保没有额外的输出到
stdout
.
要获取数据,您需要执行以下操作:。ssh [email protected] > backup.tar
现在,除了行尾发生了变化之外,几乎一切都工作正常。变得tar
更大,我可以看到每一行都有以符号结尾的 dos 行^M
。如果我强制dos2unix
使用二进制 tar 文件,该文件将与服务器上的文件匹配。
为什么会发生这种情况以及是什么改变了行尾?我什至将其简化为以下内容:服务器上用于username
链接的脚本/etc/passwd
只需创建一个,当使用上述命令登录并将输出重定向到本地计算机上的文件cat .viminfo
时,行结尾仍然传输错误。ssh
username
答案1
可能发生的情况:当在没有命令参数(并且没有指定选项)ssh
的情况下调用时,RemoteCommand
伪终端默认情况下在远程系统上为会话分配。无论远程系统配置为运行什么命令,都会发生这种情况。伪终端通常配置为将换行符转换为回车+换行序列(LF
→ CRLF
,请参阅这个答案以获得详尽的解释)。因此,脚本的输出被写入伪终端设备,该设备会更改它,然后发送到客户端。
可以通过多种方式阻止伪终端的分配,包括:
ssh
使用-T
客户端的选项调用(或使用RequestTTY no
inssh
的配置文件(可能~/.ssh/config
));在远程系统上的用户键入前面添加
no-pty
(注意空格) ;authorized_keys
PermitTTY no
在远程系统上的 SSH 服务器配置中使用(可能/etc/ssh/sshd_config
),可能使用Match
条件块使其仅影响特定用户);例如:Match User="username" ForceCommand /path/to/your/script DisableForwarding yes PermitTTY no
(假设为用户设置了一个工作命令解释器
/etc/passwd
;然后您可能想要锁定用户的密码并确保他们没有其他登录方式);(在您的情况下,
ssh
使用命令参数调用也应该有效(例如ssh user@host :
);尽管我认为这只不过是一种解决方法)。
当然,最合适的选项取决于您的用例,特别是取决于是否允许用户选择。
也可以看看:
- 创建一个只执行一个命令的 UNIX 帐户- 对于部分替代方法,注意到,正如所指出的在评论中对于您的问题,用作用户默认解释器的脚本确实(可能)阻止用户获得 shell,但也可能添加其自身的可利用元素。
答案2
我正在ssh
为我的 python 脚本创建一个隧道。 ssh 命令行不执行任何操作,它没有参数,因此它尝试打开 shell 和伪 tty。
使用 ssh 启动后subprocess.Popen
,我的换行符Python脚本被分解成只有换行符,没有回车符,所以 python 脚本的输出会变得很糟糕。最重要的是,pytest
由于我不明白与伪tty相关的原因,python脚本将无法运行。我可以让它pytest
在-tt
提供给 ssh 的情况下运行,但正常的 python 标准输出仍然被损坏。-T
不适用于pytest
.
我通过在 ssh 命令行中输入很长的 sleep 命令解决了这个问题;即相当于ssh -L 1234:remote:1234 user@remote sleep 1000000
.然后不会发生伪 tty 有趣的事情,并且 ssh 隧道将在 11 天后自行关闭。我只需要打开隧道进行测试,因此超时不是问题。