ssh - 如何使用 'expect' 将公钥复制到主机?

标签 ssh tcl expect

我使用以下语法将公钥复制到主机,以便能够在没有密码查询的情况下登录到主机:

ssh-copy-id $hostname 

其中 $hostname 是具有用户名的系统的主机名,例如root@123.456.789.100 。但是,此命令至少需要一个密码查询,有时还需要以下类型的额外交互:
The authenticity of host 'xxx (xxx)' can't be established.
RSA key fingerprint is xxx.
Are you sure you want to continue connecting (yes/no)?

我试图用 expect 解决我的问题,这是我到目前为止所拥有的(包含所有评论和建议):
#!/usr/bin/expect
set timeout 9
set hostname     [lindex $argv 0]

spawn ssh-copy-id $hostname 

expect {
  timeout { send_user "\nFailed to get password prompt\n"; exit 1 }
  eof { send_user "\nSSH failure for $hostname\n"; exit 1 }

  "*re you sure you want to continue connecting" {
    send "yes\r"
    exp_continue    
  }
  "*assword*" {
   send  "fg4,57e4h\r"
  }

}

只要它正确地“捕捉”第一个交互,而不是第二个交互,就可以工作。似乎正在使用正确的密码 (fg4,57e4h),但是当我尝试登录主机时,仍然要求我输入密码。我还检查了 .ssh/authorized_hosts 中没有任何条目。使用的密码也绝对正确,因为我可以直接复制并粘贴它来登录。该脚本不会产生任何错误,但会产生以下 exp_internal 1 输出:
 ./expect_keygen XXX
spawn ssh-copy-id XXX
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {3602}

expect: does "" (spawn_id exp6) match glob pattern "*re you sure you want to continue connecting"? no
"*assword*"? no
XXX's password: 
expect: does "XXX's password: " (spawn_id exp6) match glob pattern "*re you sure you want to continue connecting"? no
"*assword*"? yes
expect: set expect_out(0,string) "XXX's password: "
expect: set expect_out(spawn_id) "exp6"
expect: set expect_out(buffer) "XXX's password: "
send: sending "fg4,57e4h\r" to { exp6 }

虽然我既不是 tcl 也不期望专家,但似乎期望将正确的字符串(即密码)发送到 ssh-copy-id 命令。但是还是有问题,上面的expect命令没有把公钥复制到主机上。

最佳答案

在正常情况下,SSH 工具链从终端询问密码,而不是从标准输入。
您可以 provide custom SSH_ASKPASS program用它推送你的密码。

创建一个简单的脚本 askpass.sh:

#!/bin/sh
echo $PASSWORD

然后将其配置为在 ssh 中使用:
chmod a+x askpass.sh
export SSH_ASKPASS=askpass.sh

最后运行 ssh-copy-id (没有期望):
export DISPLAY=:0
PASSWORD=mySecurePassword setsid ssh-copy-id -o StrictHostKeyChecking=no hishost.thatwas.secure.com

setid 从终端分离(然后 ssh 会 panic 并寻找 askpass 程序)
DISPLAY 也由 ssh 检查(它认为您的 askpass 是一个 GUI)

请注意,这种方法可能存在隐藏的安全漏洞。

关于ssh - 如何使用 'expect' 将公钥复制到主机?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19403360/

相关文章:

ubuntu - 无法在 Ambari 服务器中添加主机

linux - SSH 连接到服务器(使用 key )

scripting - TCL : list element in quotes followed by ";" instead of space 中面临的问题

bash - 在 Bash 脚本中期望

ubuntu - 与期望级联ssh

git - 从 SSH 克隆 git 存储库时,*.git 扩展名有什么用?

ssh - 为什么 SFTP 客户端只需要知道私钥,不需要公钥?

tcl - Global 和::in TCL 有什么区别?

命名空间 : calling namespace procs give errors 内的 TclOO 类

linux - expect 的输出不完整