使用 Expect 实现自动化安全登录:实用指南

149 阅读4分钟
  • 在某些特殊场景下,例如使用 SSO 验证或跳板机(jumpserver)登录服务器,且无法随意安装其他远程登录工具时,Expect 是一个强大的自动化工具。它能高效处理交互式任务,如自动输入 SSH 密码。本指南将详细介绍如何安装 Expect,并提供一个通过跳板机登录服务器的优化脚本示例。

1. 为什么选择 Expect?

  • Expect 是一个轻量级脚本工具,擅长自动化需要用户输入的交互式流程,尤其适合受限环境中无法使用高级终端工具的场景。本文将覆盖:
    1. 在 Debian/Ubuntu 和 CentOS/RHEL 系统上安装 Expect。
    2. 编写一个健壮的 Expect 脚本,通过跳板机实现 SSH 登录。
    3. 确保脚本可靠性和安全性的最佳实践。

2. 安装 Expect

  • 在使用 Expect 编写脚本之前,需要确保系统中已安装 Expect。以下是常见 Linux 发行版的安装步骤。

2.1. 在 Debian/Ubuntu 上安装

sudo apt update
sudo apt install expect -y
  • 说明:
    1. sudo apt update:更新软件包列表以获取最新版本。

    2. -y:自动确认安装,减少交互。

    3. 安装完成后,运行 expect -v 检查版本,验证安装是否成功。

2.2. 在 CentOS/RHEL 上安装

  • 对于 CentOS/RHEL 7 及以下版本,使用 yum:
sudo yum update
sudo yum install expect -y
  • 对于 CentOS 8 及以上版本,使用 dnf:
sudo dnf update
sudo dnf install expect -y
  • 说明:
    1. 根据系统版本选择合适的包管理器(yum 或 dnf)。
    2. 使用 expect -v 确认安装成功。

3. Expect 脚本示例:自动化 SSH 登录

  • 以下是一个优化的 Expect 脚本,用于通过跳板机自动登录目标服务器。它支持 SSO 认证、密码输入,并包含错误处理和用户提示。

3.1. 示例脚本

#!/usr/bin/expect
# 脚本名称:auto_ssh_login.exp
# 使用方法:./auto_ssh_login.exp <目标主机IP> <跳板机域名>

# 获取命令行参数
set target_host [lindex $argv 0]
set jumpserver [lindex $argv 1]
set timeout 30

# 设置默认跳板机域名(若未提供)
if { $argc < 2 } {
    set jumpserver "default.jumpserver.com"
    send_user "未提供跳板机域名,使用默认值:$jumpserver\n"
}

# 定义凭据(生产环境中建议使用安全存储)
set sso_password "your_sso_password"
set sentry_password "your_sentry_password"

# 验证输入
if { $argc < 1 } {
    send_user "错误:必须提供目标主机IP。\n"
    send_user "使用方法:$argv0 <目标主机IP> [<跳板机域名>]\n"
    exit 1
}

# 提供用户反馈
send_user "正在通过 $jumpserver 连接到 $target_host\n"

# 步骤 1:执行 SSO 认证命令
spawn cmd
expect {
    "*password*" {
        send "$sso_password\r"
        exp_continue
    }
    eof {
        send_user "SSO 认证完成。\n"
    }
    timeout {
        send_user "错误:SSO 认证超时。\n"
        exit 1
    }
}

# 步骤 2:通过跳板机 SSH 连接目标主机
spawn ssh $jumpserver -tt ssh user@$target_host
expect {
    "*password*" {
        send "$sentry_password\r"
        exp_continue
    }
    "*yes/no*" {
        send "yes\r"
        exp_continue
    }
    eof {
        send_user "已连接到 $target_host。\n"
    }
    timeout {
        send_user "错误:SSH 连接超时。\n"
        exit 1
    }
}

# 交还控制权给用户
interact

3.2. 脚本解析

  • 脚本头和用法:脚本以 #!/usr/bin/expect 开头,接受两个参数:目标主机 IP 和跳板机域名。

  • 默认值处理:如果未提供跳板机域名,脚本使用默认值 default.jumpserver.com。

  • 凭据管理:密码为简化示例而硬编码。生产环境中,建议使用环境变量或安全存储(如密钥管理服务)。

  • 错误处理:检查是否缺少必要参数,并提供清晰的使用说明。

  • Expect 执行流程:

    1. 执行初始 cmd 命令处理 SSO 认证,自动输入 SSO 密码。
    2. 通过跳板机发起 SSH 连接,处理密码提示或主机密钥验证(如 yes/no 提示)。
    3. 使用 exp_continue 处理多个提示循环。
    4. 置 30 秒超时,若无响应则报错退出。
    5. 用户交互:连接建立后,interact 将控制权交还给用户。

3.3. 使用示例

  • 将脚本保存为 auto_ssh_login.exp,添加执行权限,然后运行:
chmod +x auto_ssh_login.exp
./auto_ssh_login.exp 192.168.1.100 jumpserver.example.com

4. 最佳实践

  • 保护凭据:避免硬编码密码,推荐使用环境变量或密钥管理工具。
  • 超时调整:根据网络延迟调整 set timeout 值(默认 30 秒)。
  • 日志记录:使用 log_file 记录输出便于调试,但注意保护敏感信息。
  • 错误处理:脚本已包含基本错误检查,可进一步添加针对 SSH 连接失败的特定处理。
  • 权限管理:设置脚本权限为 chmod 700,防止未授权访问凭据。

总结

  • Expect 是一个高效的工具,适合在受限环境中自动化 SSH 登录流程。本文提供的脚本通过跳板机实现安全登录,处理 SSO 和密码提示,兼顾简洁性和可靠性。参考安装步骤和脚本示例,希望您可以轻松优化服务器登录流程,提升工作效率。