You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Paramiko的connect中添加参数,实现指定SSH命令的交互式shell?

Replicating ssh -t -l user P.P.P.P D.D.D.D with Paramiko

Great question! As a fellow network engineer who’s been down the Python/Paramiko road, let’s break down exactly how to replicate your SSH jump command behavior using Paramiko.

First, let’s unpack what your original SSH command does:

  • ssh -t -l user P.P.P.P: Connects to your proxy server P.P.P.P as user, with the -t flag forcing a pseudo-terminal allocation (critical for interactive shell functionality).
  • The trailing D.D.D.D is passed as a command to the proxy server, which triggers its internal logic to forward your session to the target device D.D.D.D.

To mirror this in Paramiko, we need two key pieces: connect to the proxy server, then trigger the session forwarding by passing D.D.D.D as a command (while ensuring we get that pseudo-terminal for interactivity).

Option 1: For Single Commands (Simpler)

If you just need to run a single command on D.D.D.D and capture output, use exec_command with the get_pty=True parameter (this replaces the -t flag):

import paramiko

def run_command_via_proxy(proxy_host, username, target_host, password=None, key_path=None):
    # Initialize SSH client
    ssh_client = paramiko.SSHClient()
    ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    
    try:
        # Connect to proxy server
        ssh_client.connect(
            hostname=proxy_host,
            username=username,
            password=password,
            key_filename=key_path  # Use this instead of password for key-based auth
        )
        
        # Execute the target host command (triggers proxy forwarding) with pseudo-terminal
        stdin, stdout, stderr = ssh_client.exec_command(target_host, get_pty=True)
        
        # Example: Send a command to the target device's shell
        stdin.write("show ip interface brief\n")
        stdin.flush()
        
        # Read and print the output
        output = stdout.read().decode()
        print("Target Device Output:\n", output)
        
        # Check for errors
        error = stderr.read().decode()
        if error:
            print("Errors:\n", error)
            
    except Exception as e:
        print(f"Connection or command failed: {str(e)}")
    finally:
        # Clean up the connection
        ssh_client.close()

# Replace with your actual credentials/hosts
run_command_via_proxy(
    proxy_host="P.P.P.P",
    username="user",
    target_host="D.D.D.D",
    password="your_password"  # Omit if using key auth
)

Option 2: For Persistent Interactive Shell

If you need a full interactive session (like manually using ssh -t), use invoke_shell() to open a persistent terminal channel:

import paramiko
import time

def interactive_shell_via_proxy(proxy_host, username, target_host, password=None, key_path=None):
    ssh_client = paramiko.SSHClient()
    ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    
    try:
        ssh_client.connect(
            hostname=proxy_host,
            username=username,
            password=password,
            key_filename=key_path
        )
        
        # Open an interactive shell channel
        shell = ssh_client.invoke_shell()
        shell.settimeout(10)
        
        # Send the target host command to trigger forwarding
        shell.send(f"{target_host}\n")
        time.sleep(1)  # Give the proxy time to forward the session
        
        # Verify we're connected to the target device (read initial prompt)
        if shell.recv_ready():
            initial_output = shell.recv(4096).decode()
            print("Connected to target device:\n", initial_output)
        
        # Example: Send an interactive command
        shell.send("show version\n")
        shell.flush()
        time.sleep(2)
        
        if shell.recv_ready():
            command_output = shell.recv(4096).decode()
            print("Command Output:\n", command_output)
            
        # Keep the session open if you want to add more interaction
        # ...
        
    except Exception as e:
        print(f"Session failed: {str(e)}")
    finally:
        ssh_client.close()

# Run the interactive session
interactive_shell_via_proxy(
    proxy_host="P.P.P.P",
    username="user",
    target_host="D.D.D.D",
    password="your_password"
)

Key Notes for Your Use Case:

  • Pseudo-Terminal Requirement: get_pty=True (for exec_command) or invoke_shell() is non-negotiable for interactive shells, just like the -t flag in your original SSH command. Without it, most network devices won’t present a usable prompt.
  • Proxy Server Logic: This solution assumes your proxy server P.P.P.P is configured to accept the target host as a command parameter. Since your original SSH command works, this logic should hold—but if not, double-check the proxy’s configuration.
  • Authentication: Swap password with key_filename if you use SSH keys instead of password auth (far more secure for network devices!).

内容的提问来源于stack exchange,提问作者PurnaChand Medisetty

火山引擎 最新活动