linux - 期待 TCL - 如何处理 ssh 远程主机识别在某些设备上发生了变化?
问题描述
我有 tcl 期望脚本每天检查网络设备上的某些版本。
#!/usr/bin/expect --
set env(TERM) vt100
set timeout 5
set username [lindex $argv 0]
set password [lindex $argv 1]
set hostname [lindex $argv 2]
set success 1
#login script
log_user 1
spawn ssh $username@$hostname
expect {
"Connection refused" {
spawn telnet $hostname
expect {
"?sername:" {
if { $success == 0 } {
log_user 1
puts "error user or password incorrect"
exit 1;
} else {
incr success -1
send "$username\r"
}
exp_continue
}
"?assword:" {
send "$password\r"
exp_continue
}
timeout {
log_user 1
puts "error could not ssh or telnet devices"
exit 1;
exp_continue
}
"#" {
send "terminal length 0\r"
}
}
exp_continue
}
timeout {
spawn telnet $hostname
expect {
timeout {
log_user 1
puts "error could not ssh or telnet devices"
exit 1;
exp_continue
}
"?..." {
log_user 1
puts "error could not ssh or telnet devices"
exit 1;
exp_continue
}
"?sername:" {
if { $success == 0 } {
log_user 1
puts "error user or password incorrect"
exit 1;
} else {
incr success -1
send "$username\r"
}
exp_continue
}
"?assword:" {
send "$password\r"
exp_continue
}
"#" {
send "terminal length 0\r"
}
}
exp_continue
}
"continue connecting (yes/no)?" {
send "yes\r"
exp_continue
}
"?assword:" {
if { $success == 0 } {
log_user 1
puts "error user or password incorrect"
exit 1;
} else {
incr success -1
send "$password\r"
}
exp_continue
}
"$ " {
send "ssh keygen -R $hostname\r"
exp_continue
}
"#" {
send "terminal length 0\r"
}
}
#execute script
expect "#"
send "\r"
expect "#"
log_user 1
send "show version\r"
expect "#"
send "exit\r"
我的期望脚本像这样工作,
- ssh 到设备。
- 如果 ssh 不工作(“连接被拒绝”或“超时”),它将进入 telnet 状态
- 如果 ssh known_hosts 密钥在 linux 设备上不存在,它将发送“yes”
- 如果远程设备上的 ssh 密钥被更改,它将发送“ssh-keygen -R $hostname”
问题是,如果远程设备上的 ssh 密钥发生更改,我的期望程序将无法运行。
[linux]$ ./sshtelnet.tcl mine password 1.1.1.1
spawn ssh mine@1.1.1.1
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that the RSA host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
83:24:a5:c4:2c:98:0d:0b:d6:ad:cb:74:12:7e:84:83.
Please contact your system administrator.
Add correct host key in /home/linux/.ssh/known_hosts to get rid of this message.
Offending key in /home/linux/.ssh/known_hosts:152
RSA host key for 1.1.1.1 has changed and you have requested strict checking.
Host key verification failed.
expect: spawn id exp4 not open
while executing
"expect "#""
(file "./sshtelnet.tcl" line 106)
解决方案
当远程主机标识发生变化时,ssh 进程终止。假设您知道这不是因为“有人在做讨厌的事情”,您想在本地执行“ssh-keygen -R $hostname”,而不是将其发送到生成的 ssh 进程。清理有问题的密钥后,您必须再次生成 ssh 命令。
能够重复 ssh 命令的最简单方法是将内容放入 procs 中:
proc connectssh {username password hostname} {
global spawn_id
set success 1
spawn ssh $username@$hostname
expect {
"Connection refused" {
connecttelnet $username $password $hostname
}
timeout {
connecttelnet $username $password $hostname
}
"continue connecting (yes/no)?" {
send "yes\r"
exp_continue
}
"?assword:" {
if {$success == 0} {
log_user 1
puts "error user or password incorrect"
exit 1;
} else {
incr success -1
send "$password\r"
}
exp_continue
}
"Host key verification failed" {
wait
exec ssh-keygen -R $hostname
connectssh $username $password $hostname
}
"#" {
send "terminal length 0\r"
}
}
}
proc conecttelnet {username password hostname} {
global spawn_id
spawn telnet $hostname
expect {
# ...
}
}
set env(TERM) vt100
set timeout 5
lassign $argv username password hostname
log_user 1
connectssh $username $password $hostname
# The rest of your script
推荐阅读
- html - 文本滚动时如何使背景图像保持不变?(苹果浏览器)
- java - 如何使用 Spring Boot 将图像上传到 Firebase 上的特定参考或文件夹
- spring - Spring Entity mult inverseJoinColumns
- sql - 如何从hire_date发表初级声明
- unity3d - material.SetColor 不起作用 PC/Android 版本
- ms-access - 请协助将用户的 Text34 值添加到 MS ACCESS 上的 thisParcel 表达式中。运行代码时出现 3075 运行时错误
- java - 获取注解泛型方法参数
- node.js - AWS Lambda 的 SQL Server 数据库访问问题
- verilog - Verilog inout 端口分配导致 X
- python - pyqtgraph 图像点选择