使用python语言编写一份,服务器之间免登陆脚本,基于python3.12.5版本编写。

前言:
用户让我用Python 3.12.5写一个服务器之间免登录的脚本。
首先,我需要明确用户的需求。
免登录通常指的是通过SSH密钥对实现无密码登录,
这样在服务器之间传输文件或执行命令时不需要手动输入密码。
用户可能是在管理多台服务器,需要自动化任务,比如部署、备份或者同步数据。
手动输入密码效率低下,也不适合自动化脚本。所以,用户需要一个自动生成和分发SSH密钥的方案。
接下来,我得考虑如何用Python实现这个功能。
Python有paramiko库,可以处理SSH连接。
但是生成密钥对的话,可能用ssh-keygen命令更直接,
毕竟这是标准做法。不过,如果用户希望完全用Python实现,
可能需要调用subprocess来执行这些命令。
步骤大概分为生成密钥对、将公钥分发到目标服务器、测试连接。
生成密钥对可以用RSA算法,现在虽然推荐ed25519,但RSA兼容性更好。
然后,需要将公钥内容追加到目标服务器的~/.ssh/authorized_keys文件中,
这一步可能需要处理权限问题,比如目录的权限必须是700,文件的权限是600,
否则SSH会拒绝。 还要考虑异常处理,比如连接失败、认证错误、权限问题等。
需要给用户清晰的错误提示,方便排查问题。另外,脚本可能需要用户输入目标服务器的信息,
比如IP、端口、用户名和密码,这些可以通过参数或者配置文件传入。
安全方面,用户密码在输入时应避免明文显示,可以使用getpass模块。
分发公钥时,确保目标服务器的authorized_keys文件正确设置,避免覆盖已有的密钥。
测试连接部分,可以用paramiko尝试建立SSH连接,执行简单的命令如’echo “Hello”'来验证是否成功。
同时,脚本应该提供示例用法,说明如何调用函数,并处理可能的异常。
用户可能对paramiko不熟悉,所以需要在注释中说明需要安装这个库,以及可能的依赖。
另外,提醒用户注意安全,比如在真实环境中使用密钥对管理,避免密码泄露。
最后,确保代码兼容Python 3.12.5,检查语法和库的兼容性,比如subprocess和paramiko在最新Python版本中的使用情况。
可能还需要处理不同操作系统之间的路径差异,比如Windows和Linux,但通常服务器是Linux,所以可以假设路径为Linux风格。
总结下来,脚本需要完成密钥生成、分发、测试,处理各种异常,并提供清晰的提示。
代码结构分为几个函数,每个函数负责一个步骤,主程序调用这些函数并处理用户输入。
这样用户可以根据需要调整参数,比如密钥路径、服务器列表等,提高脚本的灵活性。
以下是一个基于Python 3.12.5实现的服务器间SSH免密登录配置脚本,使用paramiko和subprocess库实现密钥生成与分发:

python
import os
import sys
import subprocess
import paramiko
from getpass import getpass

def generate_ssh_key(key_path="~/.ssh/id_rsa"):
    """
    生成SSH密钥对
    :param key_path: 密钥保存路径(默认 ~/.ssh/id_rsa)
    :return: 公钥内容
    """
    key_path = os.path.expanduser(key_path)
    if os.path.exists(key_path):
        print(f"密钥文件 {key_path} 已存在,跳过生成")
        with open(f"{key_path}.pub") as f:
            return f.read().strip()
    
    print("正在生成新的SSH密钥对...")
    try:
        subprocess.run(
            ["ssh-keygen", "-t", "rsa", "-b", "4096", "-f", key_path, "-N", "", "-q"],
            check=True
        )
        with open(f"{key_path}.pub") as f:
            return f.read().read().strip()
    except subprocess.CalledProcessError as e:
        print(f"密钥生成失败: {str(e)}")
        sys.exit(1)

def distribute_public_key(server_info, public_key):
    """
    分发公钥到目标服务器
    :param server_info: 服务器信息字典 {host, port, username, password}
    :param public_key: 需要分发的公钥内容
    """
    try:
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(
            hostname=server_info['host'],
            port=server_info.get('port', 22),
            username=server_info['username'],
            password=server_info['password']
        )

        # 创建.ssh目录(如果不存在)
        ssh.exec_command("mkdir -p ~/.ssh && chmod 700 ~/.ssh")

        # 追加公钥到authorized_keys
        sftp = ssh.open_sftp()
        try:
            auth_keys = sftp.file('.ssh/authorized_keys', 'a+')
            auth_keys.write(f"\n{public_key}")
            auth_keys.chmod(0o600)
        finally:
            auth_keys.close()
            sftp.close()

        print(f"成功配置 {server_info['host']} 的SSH免密登录")
    except Exception as e:
        print(f"配置 {server_info['host']} 失败: {str(e)}")
    finally:
        ssh.close()

def test_ssh_connection(server_info):
    """ 测试SSH连接 """
    try:
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(
            hostname=server_info['host'],
            port=server_info.get('port', 22),
            username=server_info['username'],
            timeout=5
        )
        _, stdout, _ = ssh.exec_command('echo "Hello from $(hostname)"')
        print(stdout.read().decode().strip())
        ssh.close()
        return True
    except Exception as e:
        print(f"连接测试失败: {str(e)}")
        return False

if __name__ == "__main__":
    # 配置目标服务器列表
    servers = [
        {
            "host": "192.168.1.100",
            "port": 22,
            "username": "root",
            "password": getpass("输入192.168.1.100的密码: ")
        },
        {
            "host": "192.168.1.101",
            "username": "ubuntu",
            "password": getpass("输入192.168.1.101的密码: ")
        }
    ]

    # 生成密钥
    public_key = generate_ssh_key()

    # 分发公钥
    for server in servers:
        distribute_public_key(server, public_key)

    # 验证配置
    print("\n验证配置结果:")
    for server in servers:
        print(f"测试连接到 {server['host']}:")
        if test_ssh_connection(server):
            print("✅ 连接成功\n")
        else:
            print("❌ 连接失败\n")

脚本使用说明:

安装依赖:pip install paramiko
修改servers列表中的服务器配置信息
运行脚本后会依次要求输入各服务器的密码
特性说明:

自动密钥生成:使用4096位RSA密钥,空密码短语
安全传输:使用Paramiko的SSH连接进行密钥分发
权限管理:自动设置.ssh目录权限为700,authorized_keys权限为600
兼容性处理:自动创建不存在的.ssh目录
连接验证:执行测试命令验证配置结果
注意事项:

确保目标服务器已开启SSH服务
首次连接需要人工确认主机指纹
生产环境建议使用更安全的密钥类型(如ed25519)
建议将密码存储方式改为加密输入(示例中使用getpass隐藏输入)
可以通过修改servers列表配置多个服务器,支持不同端口和用户名混合配置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值