7

パスワードクエリなしで後でホストにログインできるようにするために、次の構文を使用して公開鍵をホストにコピーしています。

ssh-copy-id $hostname 

$hostname、システムのホスト名とユーザー名です (例: root@123.456.789.100. ただし、このコマンドには少なくとも 1 つのパスワード クエリと、場合によっては次のような追加の対話が必要です。

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"
  }

}

これは、最初のインタラクションを正しく「キャッチ」する限り機能しますが、2 番目のインタラクションはキャッチしません。正しいパスワード (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 の専門家でも期待の専門家でもありませんが、expect は正しい文字列 (パスワード) をssh-copy-idコマンドに送信するようです。ただし、上記の expect コマンドでは公開鍵がホストにコピーされないため、問題があるはずです。

4

5 に答える 5

3

これで問題が解決するはずです。

#!/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"
        interact
        exit 0
    }
}
于 2016-05-12T16:27:32.450 に答える
1

表示されているエラーはspawn、シェルを使用してコマンドを実行していないことが原因です。シェル制御文字が必要な場合は、シェルを生成する必要があります。

spawn sh -c "cat $home/.ssh/id_rsa.pub | ssh $hostname 'cat >> $home/.ssh/authorized_keys'"

ssh-copy-idただし、同じ質問をすると思いますので、これはドロップインの代替品にする必要があります。

spawn ssh-copy-id $hostname

「接続を続ける」プロンプトが表示される場合と表示されない場合がある場合は、入れ子になった期待が必要ですexp_continue

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 "mysecretpassword\r"
    }
}
于 2013-10-16T12:42:23.340 に答える
1

私の tcl/expect スクリプトを共有したいと思います。それは非常にうまく機能します。

#!/usr/bin/env tclsh

package require Expect

set prompt {[$❯#] }
set keyfile "~/.ssh/id_rsa.pub"
set needcopy 0

if {![file exists $keyfile]} {
    spawn ssh-keygen
    interact
}

spawn ssh $argv

expect {
    {continue connecting (yes/no)?} {
        send "yes\r"
        exp_continue
    }
    {[Pp]ass*: } {
        set needcopy 1
        interact "\r" {
            send "\r"
            exp_continue
        }
    }
    $prompt
}

if {$needcopy} {
    set fd [open $keyfile]
    gets $fd pubkey
    close $fd
    send " mkdir -p ~/.ssh\r"
    expect $prompt
    send " cat >> ~/.ssh/authorized_keys <<EOF\r$pubkey\rEOF\r"
    expect $prompt
}
interact
于 2017-12-22T10:37:46.917 に答える