expect命令实现多层服务器一键登录

公司工作经常需要登录服务器,但是真实服务器和本地之间隔着一个跳板机,必须登录跳板机才能登录真实服务器。这种低效的工作方式如果不实用自动化脚本改进一下还是程序员吗?
所以,本篇文章教大家如何使用expect命令实现一键登录真实服务器。

我下面的代码解决了这种需求:首先使用固定pin码+动态token码登录跳板机,然后从跳板机登录目标服务器。

我直接把代码放在这里,然后说使用方式,有兴趣的可以细细研究脚本的实现方式。

注意,第40行你应该根据实际情况修改一下expect期待的字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#!/usr/bin/expect

# 用法:./login.exp 堡垒机 堡垒机用户名 token前缀 目标服务器 目标服务器用户名 目标服务器密码

# 设置超时时间
set timeout -1


# 跳板机服务器
set TERMSERV [lindex $argv 0]
# 跳板机用户名
set USER [lindex $argv 1]
# 跳板机密码构成为:6位密码+Token动态密码
# 这里输入前6位密码
set PWD [lindex $argv 2]

# 输入Token码,用于登录跳板机
send_tty "请输入6位Token动态密码: "
expect "\n" {
set TOKEN $expect_out(buffer)
# 跳板机密码
set PASSWORD "$PWD$TOKEN"
}

# 需要登录的机器信息
# 这里只要输入线上机器IP
set MACHINE [lindex $argv 3]
# 需要登录的机器的用户名
set USER2 [lindex $argv 4]
# 需要登录的机器的密码
set PWD2 [lindex $argv 5]


# 登录跳板机
spawn ssh -l $USER $TERMSERV
expect "password:" { send "$PASSWORD\r" }


# 登录机器
expect "*-bash-baidu-ssl$*" {
send "ssh -l $USER2 $MACHINE\r"
# 最后如果输入了密码就是6个参数,那就需要输入密码
if {$argc == 6} {
expect "password:" { send "$PWD2\r" }
}
interact
}

调用方式:
./login.exp 跳板机 登录跳板机的用户名 固定pin码 目标服务器 进入目标服务器的用户名 进入目标服务器的密码(不需要密码可以不写)

总共有6各参数,前5个是可选的,最后一个根据需要选填。

感谢