巧用 SecureCRT 实现复杂的 ssh 登录过程自动化
以前公司的服务器都是在 SecureCRT 里直接 ssh 连接,但是最近公司处于安全审计考虑,在所有服务器前加了一层堡垒机,而且密码采用 kerberos 集中授权认证。这样问题就来了,虽然安全审计的目的达到了,但是登录服务器的效率却大打折扣,以前点一次鼠标就登录的过程,现在还要手动输入3次命令或密码才能完成。机器少还好,多的话,这个体验和流程对于追求效率的 RD 来说苦不堪言。记得在《打造 Facebook》一书中也曾提到了 Facebook 的工具文化,其中一条是说凡是被很多人不断重复的好的习惯,都要将其自动化。推而广之,那么这里究竟有没有办法自动化这个登录过程呢?
其实 SecureCRT 本身就可以实现,SecureCRT 的 Logon Action 可以在登录过程中发送指令去完成权限校验实现自动登录。你只需要把整个复杂登录认证流程走一遍,把其中的关键提示文本记下来,然后根据流程顺序创建相应的 Action 即可。
1、自动登录单台服务器
先看图,后面我会说原理。
2、批量登录多台服务器
如图 copy → paste 然后右键属性改下你的 ssh ip 保存即可,这样以后你就可以以文件夹为单位批量登录了。
其实在 %AppData%RoamingVanDykeConfigSessions 下面保存了这些 session 的配置文件,原本应该是可以一条 shell 命令批量创建好这些 session,而不是手动一个个复制粘贴修改的,只是现在它的 session 配置里有两处加密了,无法直接这么干。。。
3、自动登录的原理
其实对于在 shell 下写过自动登录认证或者命令行交互的同学来说,这个应该不算陌生,常用的 expect 命令和上面的类似,都是通过捕获、匹配标准输出中的提示符关键词,然后发送预定义的字符串或者执行预定义的命令,例如下面的代码是 expect 实现 ssh 自动登录并做简单交互:
#!/usr/bin/expect
# 设置超时时间为 60 秒
set timeout 60
# 设置要登录的主机 IP 地址
set host 192.168.1.46
# 设置以什么名字的用户登录
set name root
# 设置用户名的登录密码
set password 123456
#spawn 一个 ssh 登录进程
spawn ssh $host -l $name
# 等待响应,第一次登录往往会提示是否永久保存 RSA 到本机的 know hosts 列表中;等到回答后,在提示输出密码;之后就直接提示输入密码
expect {
"(yes/no)?" {
send "yesn"
expect "assword:"
send "$paswordn"
}
"assword:" {
send "$passwordn"
}
}
expect "#"
# 下面测试是否登录到 $host
send "unamen"
expect "Linux"
send_user "Now you can do some operation on this terminaln"
# 这里使用了 interact 命令,使执行完程序后,用户可以在 $host 终端进行交互操作。
Interact
4、脚本自动登录:应对繁琐多变的交互式登录场景
文初提到的 logon action 也许对某些业务场景而言过于简单,你可能需要更强大的功能扩展,比如每个月公司会强制要求修改Kerboros密码,上百台机器都需要变更一次,这在文初的方案中是非常繁琐费事的,secureCRT 也为你提供了这样的功能,在 session 属性里勾选 logon script 然后会自动加载执行相应的脚本,这样可以完成更强大的交互过程,默认情况下在你的 C:Program FilesSecureCRTscripts 目录下会有一些示例脚本,比如 example1.vbs 就是模拟登陆的,目前支持的语言有:python、perl、vbs、vbe、js。
下面的例子是把 kerboros 密码保存在文件中,登录脚本会自动根据标题 IP 去匹配密码,然后执行自动登录,这样每次系统改密码后只需修改文件中的密码,所有机器配置不用任何修改即可正常登录。
注意:kerboros 和 SecureCRT 最好以管理员权限启动,否则会有各种莫名其妙问题,比如还是提示让你输入密码。
#$language = "VBScript"
#$interface = "1.0"
Sub main
' Constant used by OpenTextFile()
Const ForReading = 1
' Open a file, read it in & send it one line at a time
Dim fso, f, passwd
Set fso = CreateObject("Scripting.FileSystemObject")
' 请把密码保存在这个文件里,注意修改为自己的路径
Set f = fso.OpenTextFile("C:UsersJunDesktoppasswd.txt", ForReading, 0)
Do While f.AtEndOfStream <> True
' Read each line of the printers file.
passwd = f.Readline
Exit Do
Loop
' Get ipAddress from current tabName
caption = crt.window.caption
Set re = New RegExp
re.Global = True
re.IgnoreCase = True
re.MultiLine = True
key = "(?:1?d?d|2[0-4]d|25[0-5])"
re.Pattern = "b" & key & "." & key & "." & key & "." & key & "b"
set ex = re.Execute(caption)
For Each e In ex
'str = str & e & vbCrLf
ipv4 = e
Exit For
Next
' Debug
'PrintResult(crt.Dialog.MessageBox("Login Succ..."))
' turn on synchronous mode so we don't miss any data
crt.Screen.Synchronous = True
' Wait for a string that looks like "login: " or "Login: "
crt.Screen.WaitForString "ogin:"
' Send your cmd or data followed by a carriage return
crt.Screen.Send "ssh work@" & ipv4 & VbCr
crt.Screen.WaitForString "ermission :"
crt.Screen.Send "2" & VbCr
crt.Screen.WaitForString "kerberos password :"
crt.Screen.Send passwd & VbCr
'crt.Screen.WaitForString "assword:"
'crt.Screen.Send "2" & VbCr
' turn off synchronous mode to restore normal input processing
crt.Screen.Synchronous = False
End Sub
5、SecureCRT 的其它极具生产力特性:
SecureCRT 作为一款功能完备的终端管理软件,除了上面的功能之外,还有其它一些极具生产力的功能,用好了能极大提升大家的工作效率,我这里摘录一些,大家如果还有其它的技巧点也可以补充,多多益善~
Refer:
[1] expect 使用
http://blog.chinaunix.net/uid-25063573-id-2956675.html
[2] Facebook元老王淮谈科技公司应有的工具文化
http://www.infoq.com/cn/news/2012/08/facebook-tools-culture
[3] 《打造FACEBOOK》读书笔记
http://aoxuis.me/post/2013-04-16-facebook-review
[4] securecrt 官方脚本范例参考:
https://www.vandyke.com/support/securecrt/python_examples.html
https://www.vandyke.com/support/securecrt/scripting_faq.html
https://www.vandyke.com/support/securecrt/scripting_examples.html
https://forums.vandyke.com/archive/index.php/t-1525.html
https://www.vandyke.com/support/tips/scripting/index.html
- 使用Let's Encrypt的SSL证书配置HTTPS手记
- Mybatis_day01
- golang 如何验证struct字段的数据格式
- ggolot2 画ROC曲线
- 47. 访问MySql数据库实现增删改查 | 厚土Go学习笔记
- 39. channel管道 | 厚土Go学习笔记
- springmvc学习第二天
- 厚土Go学习笔记 | 38. goroutine轻量级线程
- 厚土Go学习笔记 | 37. 图片(image)生成器
- 编写地道的Go代码
- 开发你不能忽略的问题?JavaScript(JS)
- 厚土Go学习笔记 | 36. web服务指定路径下的get参数接收与处理
- 用R进行文本分析初探——包含导入词库和和导入李白语句
- Golang事务模型
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 技术分享 | 改写 mysqldump 解决 DEFINER 问题
- CNS图表复现04—单细胞聚类分群的resolution参数问题
- 学习Vue3.0,先从搭建环境开始
- AIM Tech Round 5 (rated, Div. 1 + Div. 2)C. Rectangles
- PAT (Basic Level) Practice (中文)1006 换个格式输出整数 (15 分)
- 编译原理实战入门:用 JavaScript 写一个简单的四则运算编译器(二)语法分析
- PAT (Basic Level) Practice (中文)1023 组个最小数 (20 分)
- Angular里使用createEmbeddedView动态加入新的模板元素
- PAT (Basic Level) Practice (中文)1002 写出这个数 (20 分)
- [笔记整理]几个有点重要的知识点
- PAT (Basic Level) Practice (中文)1005 继续(3n+1)猜想 (25 分)
- PAT (Basic Level) Practice (中文)1033 旧键盘打字 (20 分)
- SAP电商云CCV2 Restful API enablement
- PAT (Basic Level) Practice (中文)1007 素数对猜想 (20 分)
- 两种方式解决子集问题