import paramiko
import threading
# 输入堡垒机用户名和密码
bastion_username = input("请输入堡垒机用户名:")
bastion_password = input("请输入堡垒机密码:")
# 填写目标主机信息
target_hosts = [
{"host": "192.168.2.110", "port": 22, "username": "root", "password": "123456"},
{"host": "192.168.2.166", "port": 22, "username": "root", "password": "123qwe"},
# 添加更多的目标主机信息
]
bastion_host = "192.168.2.198" # 堡垒机主机名或IP地址
# 创建SSH客户端对象
bastion_ssh = paramiko.SSHClient()
bastion_ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 用于存储输出结果的字典
outputs = {}
def execute_command(target_host, command):
target_username = target_host["username"]
target_password = target_host["password"]
target_port = target_host["port"]
# 创建目标主机的SSH客户端对象
target_ssh = paramiko.SSHClient()
target_ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
# 连接到目标主机
target_ssh.connect(target_host["host"], port=target_port, username=target_username, password=target_password)
# 执行shell命令
stdin, stdout, stderr = target_ssh.exec_command(command)
# 将输出存储在outputs字典中
outputs[target_host["host"]] = stdout.read().decode()
# 关闭目标主机连接
target_ssh.close()
except paramiko.AuthenticationException:
outputs[target_host["host"]] = "认证失败,请检查目标主机 {} 的用户名和密码。".format(target_host["host"])
except paramiko.SSHException as e:
outputs[target_host["host"]] = "目标主机 {} SSH连接错误: {}".format(target_host["host"], str(e))
except paramiko.ChannelException as e:
outputs[target_host["host"]] = "目标主机 {} 通道错误: {}".format(target_host["host"], str(e))
except Exception as e:
outputs[target_host["host"]] = "目标主机 {} 发生错误: {}".format(target_host["host"], str(e))
try:
# 连接到堡垒机
bastion_ssh.connect(bastion_host, username=bastion_username, password=bastion_password)
# 创建线程列表
threads = []
# 执行shell命令
command = input("请输入要执行的shell命令:")
for target_host in target_hosts:
# 创建线程
thread = threading.Thread(target=execute_command, args=(target_host, command))
threads.append(thread)
# 启动线程
thread.start()
# 等待所有线程都执行完毕
for thread in threads:
thread.join()
# 输出命令执行结果
print("命令输出:")
for target_host in target_hosts:
print("目标主机", target_host["host"], "命令输出:")
if target_host["host"] in outputs:
print(outputs[target_host["host"]])
else:
print("目标主机", target_host["host"], "没有输出。")
# 关闭堡垒机连接
bastion_ssh.close()
except paramiko.AuthenticationException:
print("认证失败,请检查堡垒机用户名和密码。")
except paramiko.SSHException as e:
print("堡垒机SSH连接错误:", str(e))
except paramiko.ChannelException as e:
print("堡垒机通道错误:", str(e))
except Exception as e:
print("发生错误:", str(e))
脚本2:注意密码都是明文:
由于getpass库试了几个版本的都不是很稳定所以先用明文密码
import paramiko
import time
hosts = [
{"hostname": "192.168.2.110", "username": "root", "password": "123456", "port": "22"},
#{"hostname": "192.168.2.111", "username": "root", "password": "123456", "port": "22"},
{"hostname": "192.168.2.166", "username": "root", "password": "123qwe", "port": "22"}
]
paramiko.util.log_to_file("ssh.log")
for host in hosts:
# 连接到宝服务器
bao_ssh = paramiko.SSHClient()
bao_ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
bao_ssh.connect(hostname="192.168.2.198", username="root", password="123456")
print("Connected to 垒机 ok")
# 在宝服务器上执行ssh登录操作
channel = bao_ssh.invoke_shell()
channel.send(f"ssh -p {host['port']} {host['username']}@{host['hostname']}\n")
time.sleep(1)
# 发送密码
channel.send(f"{host['password']}\n")
time.sleep(1)
# 响应缓冲区清空
while channel.recv_ready():
channel.recv(1024)
# 发送执行命令
channel.send("ip addr| grep ens32\n")
time.sleep(1)
buff = b""
while channel.recv_ready():
buff += channel.recv(1024)
print(buff.decode())
channel.close()
bao_ssh.close()
脚本3: 方式比较原始1对1
import sys
import paramiko
import time
baoip = "192.168.2.198"
baouser = "root"
baopasswd = "123456"
hostname = "192.168.2.110"
username = "root"
passwd = "123456"
port = '2222'
paramiko.util.log_to_file("ssh.log")
# 连接到宝服务器
bao_ssh = paramiko.SSHClient()
bao_ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
bao_ssh.connect(hostname=baoip, username=baouser, password=baopasswd)
print("Connected to 堡垒server ok")
# 在宝服务器上执行ssh登录操作
channel = bao_ssh.invoke_shell()
channel.send(f"ssh {username}@{hostname}\n")
time.sleep(1)
# 发送密码
channel.send(f"{passwd}\n")
time.sleep(1)
# 响应缓冲区清空
while channel.recv_ready():
channel.recv(1024)
# 发送执行命令
channel.send("ip addr\n")
time.sleep(1)
buff = b""
while channel.recv_ready():
buff += channel.recv(1024)
print(buff.decode())
channel.close()
bao_ssh.close()