【问题标题】:Expect TCL - How to handle ssh remote host identification has changed on some devices?期待 TCL - 如何处理 ssh 远程主机识别在某些设备上发生了变化?
【发布时间】:2020-07-16 02:41:13
【问题描述】:

我有 tcl expect 脚本每天检查网络设备上的某些版本。

#!/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"

我的期望脚本是这样工作的,

  1. SSH 到设备。
  2. 如果 ssh 不工作(“连接被拒绝”或“超时”),它将进入 telnet 状态
  3. 如果 ssh known_hosts 密钥在 linux 设备上不存在,它将发送“yes”
  4. 如果远程设备上的 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 -oStrictHostKeyChecking=no mine@1.1.1.1 禁用ssh 中的严格主机检查?
  • 是的已经尝试使用它但仍然失败,返回错误是这样的。 Password authentication is disabled to avoid man-in-the-middle attacks.Keyboard-interactive authentication is disabled to avoid man-in-the-middle attacks.

标签: linux ssh tcl expect


【解决方案1】:

当远程主机标识发生变化时,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

【讨论】:

  • 您好,谢尔特感谢您的回答。我已经设法使用您的代码link 编辑了我的源代码,但随后又出现了另一个错误,您可以在链接上看到。
  • 您的 ssh-keygen 版本必须与我测试的版本不同,因为它将输出发送到 stderr。您可以通过将 stderr 重定向到 stdout 来防止该问题:exec ssh-keygen -R $hostname 2>@1,或者在命令周围添加一个 catch。
猜你喜欢
  • 2017-08-12
  • 1970-01-01
  • 2011-11-04
  • 2014-01-17
  • 2014-06-02
  • 2020-02-29
  • 2016-02-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多