I am trying to log into a remote computer that requires a passphrase even though I have ssh set up with private/public keys. I cannot be made a sudden. Here is the script I use to do this.
⌂107% [:~/bin] develop( 1/-1) ± cat _script
#!/bin/bash
#
# provide the info to remote-host from this script
#
function _ssh() {
USER=$1
HOST=$2
PSWD=$3
/usr/local/bin/expect<<EOD
set timeout 30
log_user 1
set send_slow {1 .01}
log_file ~/log/ssh_tmp.log
send_log "Connecting to $HOST using $USER user\n"
eval spawn ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o ConnectTimeout=30 "$USER\@$HOST"
expect {
timeout {send_user "timeout while connecting to $HOST\n"; exit }
"*No route to host*" { send_user "$HOST not reachable\n"; exit }
"*assword: " { send -s $PSWD\r }
}
expect {
timeout { send_user "timeout waiting for prompt\n"; exit }
"*]#" { send_user "Login successful to $HOST\n" }
}
send "\hostname\r"
expect {
"[*~]$" { send "exit\r" }
}
send_user "Disconnected\n"
close
EOD
}
_ssh remote-userid remote-host 'required-passphrase'
Here is the response I get:
⌂77% [:~/bin] develop( 1/-1) 11s ± _script
spawn ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o ConnectTimeout=30 useid@remote-host
Warning: Permanently added 'remote-host,128.255.155.99' (ECDSA) to the list of known hosts.
--------------------------------------------------------------------------------
This is a private computing facility. Access to this service is limited to those
who have been granted access by the operating service provider on behalf of the
contracting authority and use is restricted to the purposes for which access was
granted. All access and usage are governed by the terms and conditions of access
agreed to by all registered users and are thus subject to the provisions of the
Computer Misuse Act, 1990 under which unauthorised use is a criminal offence.
If you are not authorised to use this service you must disconnect immediately.
--------------------------------------------------------------------------------
userid@remote-host's password:
Welcome to remote-host-name
Website: https://remote-host/
Documentation: https://remote-host/en/master/
Last login: Sat Dec 10 10:16:03 2021 from my-ip
[userid@remote-host ~]$ ls (I entered this, when the [userid@remote-host ~]$ appeared)
timeout waiting for prompt
It appears to log me in and show me the prompt, but is it expecting something else? How do I handle this?
CodePudding user response:
Just what it says: "timeout waiting for prompt"
expect {
timeout { send_user "timeout waiting for prompt\n"; exit }
"*]#" { send_user "Login successful to $HOST\n" }
}
Change the prompt pattern to -re {\][$#] $}
to match a close bracket followed by either #
(root) or $
(you), followed by a space at the end.
Since you'll expect the prompt in several places, store it in a variable
set prompt {\][$#] $}
expect {
timeout { send_user "timeout waiting for prompt\n"; exit }
-re prompt
}
send_user "Login successful to $HOST\n"
Adding an expect program into a bash script, use a quoted here-doc and pass the shell variables to expect through the environment: this is important because you don't want the shell to expand your expect variables and you don't want to have to start escaping thing.
function _ssh() {
export USER=$1
export HOST=$2
export PSWD=$3
/usr/local/bin/expect << 'EOD'
...
send_log "Connecting to $env(HOST) using $env(USER) user\n"
spawn does not need eval:
spawn ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o ConnectTimeout=30 "$env(USER)@$env(HOST)"
Change close
to expect eof
to allow the ssh connection to end gracefully.
Lastly, your expect code is doing all the interaction with the ssh process. You won't be able to type at the remote prompt unless you instruct expect to cede control of the ssh process to the user. You use the interact
command to do that.
CodePudding user response:
I suggest:
function _ssh() {
local user="$1"
local host="$2"
declare -x SSHPASS="$3"
sshpass -e ssh "$user@$host"
}