如何使用Python实现SSH双重登录以访问大学集群?
Alright, so you need to connect to your university cluster via a jump host (cupido.iqm.unicamp.br), and your current code only handles logging into the first server. Let's extend it to make that second jump work smoothly—here are two practical approaches using Paramiko, pick the one that fits your needs best.
Method 1: Run SSH Command Directly on the Jump Host
This is the simplest option if you just need to execute basic commands on the cluster. You’ll log into the jump host, then trigger an ssh command from there to connect to your target cluster.
def login_via_jump_command(): import paramiko # Jump host credentials (your existing setup) jump_host = 'cupido.iqm.unicamp.br' jump_user = 'gabriel' jump_pass = '*********' # Target cluster details (replace these with your actual cluster info) cluster_host = 'your-cluster-hostname' # e.g., 'cluster.iqm.unicamp.br' cluster_user = 'your-cluster-username' cluster_pass = 'your-cluster-password' # Step 1: Connect to the jump host ssh_jump = paramiko.SSHClient() ssh_jump.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh_jump.connect(jump_host, port=22, username=jump_user, password=jump_pass) # Step 2: SSH from jump host to cluster # Option A: Use sshpass (requires sshpass installed on the jump host) # ssh_command = f'sshpass -p "{cluster_pass}" ssh {cluster_user}@{cluster_host}' # Option B: Interactive password input (no extra tools needed) ssh_command = f'ssh {cluster_user}@{cluster_host}' stdin, stdout, stderr = ssh_jump.exec_command(ssh_command) # Send the cluster password when prompted stdin.write(f"{cluster_pass}\n") stdin.flush() # Read and print output from the cluster print("Cluster Output:\n", stdout.read().decode()) print("Errors (if any):\n", stderr.read().decode()) # Clean up connections ssh_jump.close()
Method 2: SSH Port Forwarding (Tunnel)
This method creates a local port on your machine that forwards traffic through the jump host to the cluster. It’s more flexible—you can use this tunnel for SSH, SFTP, or other tools as if you were connecting directly to the cluster.
def login_via_tunnel(): import paramiko # Jump host credentials jump_host = 'cupido.iqm.unicamp.br' jump_user = 'gabriel' jump_pass = '*********' # Target cluster details cluster_host = 'your-cluster-hostname' cluster_user = 'your-cluster-username' cluster_pass = 'your-cluster-password' cluster_port = 22 # Default SSH port, adjust if yours is different # Step 1: Connect to the jump host ssh_jump = paramiko.SSHClient() ssh_jump.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh_jump.connect(jump_host, port=22, username=jump_user, password=jump_pass) # Step 2: Set up local port forwarding (local port 10022 → cluster:22) local_port = 10022 transport = ssh_jump.get_transport() transport.request_port_forward('', local_port) # Step 3: Connect to the cluster via the local tunnel ssh_cluster = paramiko.SSHClient() ssh_cluster.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh_cluster.connect('127.0.0.1', port=local_port, username=cluster_user, password=cluster_pass) # Now you can run commands directly on the cluster! stdin, stdout, stderr = ssh_cluster.exec_command('hostname') print("Cluster Hostname:", stdout.read().decode().strip()) # Clean up connections ssh_cluster.close() ssh_jump.close()
Key Tips for Security & Reliability
- Avoid Hardcoded Passwords: Use environment variables (e.g.,
os.getenv("CLUSTER_PASSWORD")) or SSH key authentication instead. For keys, useparamiko.RSAKey.from_private_key_file("/path/to/your/private_key")in theconnect()method. - Agent Forwarding: If both the jump host and cluster trust your SSH key, enable agent forwarding in Paramiko to skip password prompts entirely.
- SFTP Support: To transfer files, adapt either method—use
ssh_jump.open_sftp()for Method 1, orssh_cluster.open_sftp()for Method 2.
内容的提问来源于stack exchange,提问作者Gabriel Cesar

