Kaito's Blog

致力成为一枚silver bullet.

0%

堡垒机Expect登陆服务器

最近公司线上服务器都换上了堡垒机登陆,这样每个开发人员都只分配堡垒机账号,然后运维人员划分对应的权限机器就好了,相比之前的跳板机登陆要有很多优点:

  • 只需给开发人员分配一个账号和密码,避免机器过多账号繁多的情况;
  • 运维人员分配机器权限便捷,只需给开发人员账号分配权限机器即可;
  • 相对跳板机来说更安全,堡垒机登陆到线上服务器后,可以记录每个用户的所有操作记录;

大概说下堡垒机的使用机制:

  • 开发人员使用自己的账号登陆堡垒机,输入账号和密码
  • 登陆成功后,堡垒机会列出该账户下有权限可操作的服务器列表,每个服务器对应一个数字
  • 开发人员输入对应的服务器数字或者选择搜索选项搜索服务器
  • 如果是直接选择了服务器,则会列出可用的账户,如果是搜索服务器,则需输入服务器IP
  • 然后堡垒机会列出可用的账号列表,每个账户对应一个数字
  • 输入账户对应的数字,选择使用哪个账户操作服务器,进入服务器,登陆完成

其实说白了,和很多客服电话原理差不多,列出来多个选项菜单供你选择,然后一步步选择,最终进入服务器。

也就是说我进入一台线上服务器,需要输入账号密码->选择/搜索服务器->选择操作账户->登陆成功这几个步骤。每次登陆服务器只是IP不同,但都需要频繁输入相同的数字进行选择,肯定受不了,最好的方式是,能不能通过一个脚本,根据命令行的提示信息,自动选择,最终进到服务器。当然,答案是可以的,这里就使用到了Expect工具。

简单介绍下Expect:

Expect是Unix系统中用来进行自动化控制和测试的软件工具,该工具利用Unix伪终端包装其子进程,允许任意程序通过终端接入进行自动化控制。

现在很多终端工具客户端都提供这些操作,例如SecureCRTXShell都是支持的,最终都是使用的Expect。

这些工具的使用就不介绍了,这里主要介绍一下不借助工具,在终端编写脚本来完成此功能,例如在Linux、Mac终端下进行登录操作。

使用背景:

  • 堡垒机IP:192.168.0.50
  • 堡垒机账号密码:test_dev / test_passwd
  • 服务器A IP:192.168.0.100
  • 服务器B IP:192.168.0.200

通过堡垒机登录到服务器A/B,使用方式最好是这样:

  • 执行go_servera –> 登录到服务器A
  • 执行go_serverb –> 登录到服务器B

可以编写login.sh脚本如下:

#!/usr/bin/expect

# 定义堡垒机账号/密码/IP
set user test_dev
set passwd test_passwd
set bastion_host 192.168.0.50

# 如果参数少于1个,提示错误并退出
if { $argc != 1 } {
    puts stdout "useage: ./login.sh \$host\n"
    exit 1
}

# 把第一个参数赋值给dest_host
set dest_host [lindex $argv 0]

# 执行ssh操作,登录到堡垒机
spawn ssh $user@$bastion_host
# 检测命令行的返回的信息,匹配Password关键字
expect "*Password:"
# 自动输入密码 回车
send "$passwd\r"
# 检测命令行的返回的信息,匹配Choice关键字    
expect "*Choice:"
# 假设命令行提示信息输入s表示根据IP搜索服务器
send "s\r"
# 检测命令行的返回的信息,匹配IP关键字        
expect "*IP:"
# 自动输入dest_host变量内容 回车
send "$dest_host\r"
# 检测命令行的返回的信息,匹配Choice关键字        
expect "*Choice:"
# 假设命令行提示信息输入1表示选择某个账户进行操作
send "1\r"
# 自动交互结束,控制权交给终端,用户可以进行操作
interact

此脚本编写完成后,并增加可执行权限chmod +x login.sh后,可以这样使用:

# 登陆到服务器A
$ ./login.sh 192.168.0.100
# 登陆到服务器B
$ ./login.sh 192.168.0.200
# 如果任何参数都没有
$ ./login.sh
# 提示:useage: ./login.sh \$host

该方法可以执行一个脚本,并使用IP地址为参数,最终完成通过堡垒机登陆服务器的操作。

不过这样做不是最佳方法,因为这样还需要输入机器的IP,很麻烦,我希望最好是通过一条命令,就如上面所述,执行go_servera登陆到服务器A,执行go_serverb登陆到服务器B,这样就方便很多!

可以这样来达到目的:

  • login.sh放到自己的用户目录~/
  • ~/.bashrc中加2个别名:
    • alias go_servera='./login.sh 192.168.0.100'
    • alias go_serverb='./login.sh 192.168.0.200'

重新登陆终端或执行source ~/.bashrc命令,然后试试go_serverago_serverb命令,是不是可以直接登陆到服务器了,而且不用记服务器IP,通过别名的方式执行脚本,更加便捷!

如果此文章能给您带来小小的工作效率提升,不妨小额赞助我一下,以鼓励我写出更好的文章!