通过密钥免密访问目标服务器,脚本运行过程中不需要额外交互,只需第一次需要输入密码,后面访问服务器只需ssh root@192.168.84.129就可直接免密登录
#!/usr/bin/expect -f
#检查参数个数(支持 <用户名> <目标IP> <密码>)
if {$argc != 3} {
puts "Usage: [file tail $argv0] <username> <target_ip> <password>"
exit 1
}
#解析参数
set username [lindex $argv 0]
set target_ip [lindex $argv 1]
set password [lindex $argv 2]
#定义密钥路径
set key_path "$env(HOME)/.ssh/id_rsa"
set pub_key "$key_path.pub"
#生成SSH密钥(无则自动创建,不覆盖已有密钥)
if {! [file exists key_path\] \|\| ! \[file exists pub_key]} {
puts "未找到SSH密钥,正在生成..."
spawn ssh-keygen -t rsa -b 4096 -f $key_path -N ""
expect {
"Overwrite (y/n)?" {
# 若密钥已存在(意外情况),不覆盖,直接退出
puts "密钥已存在,无需重新生成"
exit 0
}
eof
}
puts "密钥生成完成:$key_path"
}
#自动拷贝公钥到目标服务器
puts "正在将公钥拷贝到 username@username@username@target_ip..."
spawn ssh-copy-id -i $pub_key username@{username}@username@{target_ip}
expect {
# 首次连接时确认主机指纹
"*Are you sure you want to continue connecting (yes/no)?" {
send "yes\r"
exp_continue
}
# 输入密码
"*password:" {
send "$password\r"
}
# 处理公钥已存在的情况
"*already exist on the remote system.*" {
puts "公钥已存在于目标服务器,无需重复拷贝"
exit 0
}
# 处理权限拒绝(常见于root用户登录限制)
"*Permission denied*" {
puts "错误:权限拒绝,可能是用户名/密码错误或目标服务器限制root登录"
exit 1
}
eof
}
#验证拷贝结果
expect {
"*Number of key(s) added: 1*" {
puts "公钥拷贝成功!现在可免密登录:ssh $username@$target_ip"
}
default {
puts "公钥拷贝失败,请检查目标服务器连接和密码是否正确"
exit 1
}
}