OpenSSH 子系统(或命令=选项)背后的原理是什么?

OpenSSH 子系统(或命令=选项)背后的原理是什么?

在 OpenSSH 中,可以在配置文件 () 中声明一个子系统,或者通过将其包含在特定键的行中来/etc/ssh/sshd_config强制执行以下命令,如下所示:svnserveauthorized_keys

command="svnserve -t --tunnel-user=alice" ssh-dss AAAA...
command="svnserve -t --tunnel-user=bob" ssh-dss AAAA...

从而允许相同的系统用户可以在 Subversion()上下文中重复使用不同的“身份” svnserve

我该如何编写一个像svnserve我这样的服务,允许指定隧道的使用以及在这些情况下数据究竟是如何传输的?特别是实例如何svnserve“知道”通过哪种方式输出数据或读取输入?在这种情况下,这一切都是通过stdout和发生的吗stdin?如果是这样,是否有办法区分stderr

我想象子系统和command=使用相同的机制,但如果我错了,请纠正我。

no-port-forwarding,no-agent-forwarding,no-X11-forwarding,no-pty为了简洁我省略了它们,但我知道它们以及它们在场景中的用途。)

答案1

首先,请注意,它command=不会调用 SSH 子系统。它只是运行命令,就像在 SSH 客户端的命令行上给出命令一样;例如

ssh yourhost "svnserve -t --tunnel-user=alice"

ssh yourhost "git upload-pack /pub/git/myproject.git"

ssh yourhost "ls -la"

上述示例应该更清楚地表明,与svnservegit的通信ls与任何其他 SSH 交互一样,通过相同的 stdio(stdin/stdout/stderr)进行。对于 SVN 和 Git,客户ssh端仅用作远程调用命令的工具。


Subsystem使用中的选项配置的“真实”子系统sshd_config并没有太大区别。唯一的主要区别是它们可以通过静态、众所周知的名称调用,而不是依赖远程登录 shell(bash、zsh 等)来查找正确的可执行文件。例如,SFTP 服务器可以位于/usr/lib/ssh/sftp-server一台机器上,MULTINET_COMMON_ROOT:[MULTINET]SFTP-SERVER2.EXE另一台机器上,内置sshd在第三台机器中(子系统 sftp internal-sftp),但在所有情况下客户端仍然可以使用名称找到它sftp

至少在 OpenSSH 中,子系统可以像通过 stdin/stdout/stderr 与客户端通信的普通程序一样编写。但是,似乎不允许传递任意命令行参数,因此您不能只svnserve为所有用户配置一个子系统。

相关内容