12

配置

  • LOCAL:将创建 ssh 连接并在 REMOTE 机器上发出命令的本地机器。
  • PROXY:一个 EC-2 实例,可以通过 ssh 访问 LOCAL 和 REMOTE。
  • REMOTE:位于 NAT 路由器后面的远程机器(LOCAL 无法访问,但会打开到 PROXY 的连接并允许 LOCAL 与它建立隧道)。

端口转发步骤(通过命令行)

  1. 创建从 REMOTE 到 PROXY 的 ssh 连接,以将 REMOTE 机器上端口 22 上的 ssh 流量转发到 PROXY 服务器上的端口 8000。

    # 从远程机器运行
    ssh -N -R 0.0.0.0:8000:localhost:22 PROXY_USER@PROXY_HOSTNAME

  2. 创建从 LOCAL 到 PROXY 的 ssh 隧道,并将 ssh 流量从 LOCAL:1234 转发到 PROXY:8000(然后转发到 REMOTE:22)。

    # 从本地机器运行
    ssh -L 1234:localhost:8000 PROXY_USER@PROXY_HOSTNAME

  3. 创建从本地到远程的转发 ssh 连接(通过代理)。

    # 在新的终端窗口中从本地机器运行
    ssh -p 1234 REMOTE_USER@localhost

    # 我现在已经 ssh'd 到 REMOTE 框并且可以运行命令了

帕拉米科研究

我已经查看了一些与使用 Paramiko 进行端口转发相关的问题,但它们似乎并没有解决这种特定情况。

我的问题

如何使用 Paramiko 运行上面的步骤 2 和 3?我基本上想运行:

import paramiko

# Create the tunnel connection
tunnel_cli = paramiko.SSHClient()
tunnel_cli.connect(PROXY_HOSTNAME, PROXY_PORT, PROXY_USER)

# Create the forwarded connection and issue commands from LOCAL on the REMOTE box
fwd_cli = paramiko.SSHClient()
fwd_cli.connect('localhost', LOCAL_PORT, REMOTE_USER)
fwd_cli.exec_command('pwd')
4

2 回答 2

25

可以在@bitprohet 的博客中找到有关 Paramiko “在幕后”所做的详细说明。

假设上面的配置,我工作的代码看起来像这样:

from paramiko import SSHClient

# Set up the proxy (forwarding server) credentials
proxy_hostname = 'your.proxy.hostname'
proxy_username = 'proxy-username'
proxy_port = 22

# Instantiate a client and connect to the proxy server
proxy_client = SSHClient()
proxy_client.load_host_keys('~/.ssh/known_hosts/')
proxy_client.connect(
    proxy_hostname,
    port=proxy_port,
    username=proxy_username,
    key_filename='/path/to/your/private/key/'
)

# Get the client's transport and open a `direct-tcpip` channel passing
# the destination hostname:port and the local hostname:port
transport = proxy_client.get_transport()
dest_addr = ('0.0.0.0', 8000)
local_addr = ('127.0.0.1', 1234)
channel = transport.open_channel("direct-tcpip", dest_addr, local_addr)

# Create a NEW client and pass this channel to it as the `sock` (along with
# whatever credentials you need to auth into your REMOTE box
remote_client = SSHClient()
remote_client.load_host_keys(hosts_file)
remote_client.connect('localhost', port=1234, username='remote_username', sock=channel)

# `remote_client` should now be able to issue commands to the REMOTE box
remote_client.exec_command('pwd')
于 2013-09-26T22:27:51.420 回答
1

仅仅是将 SSH 命令从 PROXY 中反弹回来,还是您还需要转发其他非 SSH 端口?

如果您只需要 SSH 进入 REMOTE 框,Paramiko 支持 SSH 级网关(告诉 PROXY sshd 打开到 REMOTE 的连接并代表 LOCAL 转发 SSH 流量)和 ProxyCommand 支持(通过本地命令转发所有 SSH 流量,这可能是任何能够与远程盒子交谈的东西)。

听起来你想要前者给我,因为 PROXY 显然已经有一个 sshd 正在运行。如果您查看 Fabric 的副本并四处搜索“网关”,您会发现 Fabric 如何使用 Paramiko 的网关支持的指针(我现在没有时间自己挖掘具体位置。)

于 2013-09-24T00:37:52.227 回答