如何用Python可靠实现远程服务器上VM的Telnet控制台访问?
问题描述
我此前成功使用telnetlib连接本地运行的VM控制台,现尝试访问远程服务器上的VM。日常操作流程是先SSH到该远程服务器,再调用telnet访问VM控制台,因此编写了一段基于paramiko的Python脚本,但该方法不稳定,经常返回服务器登录提示符的输出。请问是否有更优实现方式?比如通过端口转发在本地使用telnetlib访问远程VM?
附现有脚本:
import paramiko ssh_client = paramiko.SSHClient() ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh_client.connect("IP", username="USER", password="PSWD") tn = ssh_client.invoke_shell() tn.send(f"telnet {IP} {PORT}\r") tn.recv(4096) tn.send("foo\r")
最优实现方案:SSH本地端口转发+telnetlib
你遇到的不稳定问题,本质是invoke_shell模拟交互式终端时,难以精准控制命令执行时机和输出解析,容易混入服务器的登录提示符或其他冗余输出。用SSH本地端口转发把远程服务器上的VM telnet端口映射到本地端口,再直接用telnetlib连接本地端口,是更可靠的方案。
实现步骤
- 用paramiko建立SSH连接,创建本地端口转发通道,将本地端口的流量转发到远程服务器内的VM telnet端口
- 直接用
telnetlib连接本地映射端口,操作逻辑和连接本地VM完全一致
示例代码
import paramiko import telnetlib import time # 远程服务器SSH信息 remote_host = "远程服务器IP" remote_user = "SSH用户名" remote_pass = "SSH密码" # 远程服务器内VM的telnet地址和端口 vm_telnet_host = "VM在远程服务器内的IP" vm_telnet_port = 5900 # 替换为实际端口 # 本地映射端口(选一个未被占用的端口即可) local_port = 12345 # 建立SSH连接并配置端口转发 ssh_client = paramiko.SSHClient() ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh_client.connect(remote_host, username=remote_user, password=remote_pass) # 创建端口转发通道:本地localhost:local_port -> 远程VM的telnet端口 transport = ssh_client.get_transport() transport.request_port_forward("", local_port, vm_telnet_host, vm_telnet_port) # 等待通道建立完成 time.sleep(1) # 用telnetlib连接本地映射端口,操作和本地VM一致 tn = telnetlib.Telnet("localhost", local_port) # 发送命令示例 tn.write(b"foo\r\n") # 读取输出(可根据实际情况调整终止符和超时时间) output = tn.read_until(b"预期的提示符", timeout=5) print(output.decode()) # 关闭连接 tn.close() ssh_client.close()
方案优势
- 稳定性高:直接与VM的telnet服务通信,无需处理交互式shell的输出混淆问题
- 逻辑简洁:端口转发完成后,telnet操作逻辑和本地场景完全相同,降低代码复杂度
- 扩展性强:如需访问多个远程VM,只需建立多个不同的本地端口转发通道即可
内容的提问来源于stack exchange,提问作者aaries
相关产品推荐
相关产品推荐

