一、背景
- 每次使用Iterm登陆堡垒机,都需要动态验证码才可以登陆,然后就感觉很麻烦
- 所以为了解决这个问题,就写一个Java程序+Expect脚本配合Iterm的能力让其自动生成获取登陆
- 然后查了动态验证码的生成算法,因为用的Google Authenticator,所以查下这方面的文档,发现Google已经公开了此算法,这就简单多了
二、Java代码
- Java引入依赖
- 把下面这段程序打包成Jar
<dependency> <groupId>de.taimos</groupId> <artifactId>totp</artifactId> <version>1.0</version> </dependency>
public class XxxUtil { . public static String getTOTPCode(String secretKey) { Base32 base32 = new Base32(); byte[] bytes = base32.decode(secretKey); String hexKey = Hex.encodeHexString(bytes); return TOTP.getOTP(hexKey); . } } //Main方法 public class DemoMain { public static void main(String[] args) { // Google Authentication生成密钥这里就不过多讲了,可自行研究 String secretKye = "你的密钥(绝对不可泄漏)"; System.out.println(XxxUtil.getTOTPCode(secretKye)); } }
三、Iterm & Expect脚本
- Iterm 配置
#创建一个脚本文件login_expect.sh expect /Users/login_expect.sh your_username your_host your_password your_ip
- Expect脚本
#!/usr/bin/expect #set 设置变量 set HOST [lindex $argv 0] # 获取命令中设置的your_host set USER [lindex $argv 1] # 获取命令中设置的your_username set PWD [lindex $argv 2] # 获取命令中设置的your_password set IP [lindex $argv 3] # 获取命令中设置的your_ip,登陆堡垒机后,登陆的节点IP # CODE 是执行Java的程序,来获取的动态验证码 # GoogleAuthentication.jar就是上面打包后的Java程序 set CODE [exec sh -c {java -jar /Users/GoogleAuthentication.jar}] #我们的二次验证码CODE是这样用的,其他方式(可比葫芦画瓢) set PIN_TOKEN $PWD_$CODE_ #打印出来,查看是否正确 send_user $PIN_TOKEN\n #设置expect等待时间为3s, 如果超出该时间没有响应, 自动向下执行 set timeout 3 #使用expect内置函数spawn执行命令 spawn ssh $HOST@$USER #第一次为了输入密码,其实第一次和第二次expect可以写在一块,用它:exp_continue(不难,自行研究) expect { "*password*" {send "$PIN_TOKEN\r"} } #第二次为了登陆子节点IP expect { "*relay*" {send "$IP\r"} } #表示与终端持续交互, 完成正常跳转. 如果没有此条命令, 则在跳转后会退出. interact
四、思路
- 通过Java程序,使用密钥生成有效的CODE码,然后通过Iterm的能力执行Expect脚本实现登陆
- 生成密钥的方式不一定非要使用Java程序,也可以使用Python或者其他,可自行研究
- 注意:算法可公开,密钥绝不可泄漏
五、其他
- Iterm SSH登陆会话保持存活
- Iterm 会话Copy免登
vim ~/.ssh/config # config文件添加如下配置 Host * ServerAliveInterval 60 ControlMaster auto ControlPath ~/.ssh/master-%r@%h:%p
- Iterm 动态登陆RZ、SZ问题
# 方案来源:https://blog.51cto.com/fulin0532/2439271 # 新增shell脚本,亲测有效 # 添加如下内容: #!/bin/sh export LC_CTYPE=en_US exec expect.sh脚本的绝对路径
温馨提醒:转载请说明原地址