当 HTTP CONNECT 辅助程序把隧道返回到目标 SSH 服务器后,将该数据流交给 Paramiko:

with paramiko.SSHClient() as client:
    client.load_system_host_keys()
    client.connect('ssh.example.com',
                   username='operator',
                   sock=tunnel,
                   banner_timeout=10,
                   auth_timeout=10)
    # Use the verified SSH connection.

替换示例主机,并加载部署中正确的 known-hosts 数据。tunnel 必须已经指向同一台服务器。传给 connect 的主机名用于识别 SSH 主机密钥,而不是代理。

sock 接口接受已打开的套接字或类套接字对象。它不会替您协商 HTTP。在返回之前,连接器必须:

  1. 连接到代理,并为目的地发送有效的 CONNECT 请求。
  2. 完成任何受支持的代理认证,并确认隧道状态成功。
  3. 读取完整的代理头部区段,处理分段读取并保留边界之后的字节。
  4. 限制建立过程,并通过其清理路径关闭被拒绝或出错的套接字。

这项工作要求使用持续维护的连接器。在单个接收缓冲区中搜索英文成功短语,会漏掉被拆分的状态行、可变的理由文本和不完整的头部。代理 TCP 连接成功并不等于已被接受的 SSH 隧道。

代理必须允许所请求的 SSH 端口;网页浏览权限并不建立到 22 端口的 CONNECT 访问。407 发生在 SSH 登录之前,而 SSH 账户失败发生在隧道之后。请将这两类账户分开。

完成后关闭 SSH 客户端以及连接器持有的资源。任务停止读取本身并不会关闭仍在活动的连接。

相关文章