12

構成

  • LOCAL: ssh 接続を作成し、リモート ボックスでコマンドを発行するローカル マシン。
  • PROXY: LOCAL と REMOTE の両方に ssh アクセスできる EC-2 インスタンス。
  • 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. LOCAL から REMOTE への転送された ssh 接続を (PROXY 経由で) 作成します。

    # 新しいターミナル ウィンドウでローカル マシンから実行
    ssh -p 1234 REMOTE_USER@localhost

    # これで REMOTE ボックスに ssh 接続し、コマンドを実行できるようになりました

パラミコリサーチ

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

Paramiko が「ボンネットの下」で行っていることの詳細な説明は、@bitprohet のブログ (こちら) にあります

上記の構成を想定すると、私が作業しているコードは次のようになります。

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ポートも転送する必要がありますか?

REMOTE ボックスに SSH で接続する必要があるだけの場合、Paramiko は SSH レベルのゲートウェイ機能 (PROXY sshd に REMOTE への接続を開き、LOCAL に代わって SSH トラフィックを転送するよう指示する) と ProxyCommand サポート (ローカル コマンドを介してすべての SSH トラフィックを転送する) の両方をサポートします。リモートボックスと通信できるものなら何でもかまいません)。

PROXYは明らかにすでにsshdを実行しているため、前者が必要なようです。Fabric のコピーをチェックアウトし、'gateway' を検索すると、Fabric が Paramiko のゲートウェイ サポートをどのように使用しているかへのポインタが見つかります (私は今、自分で特定のスポットを掘り下げる時間がありません.)

于 2013-09-24T00:37:52.227 に答える