I am writing a script to log into multiple Cisco routers. I am running into and issue. This message pops up every time. "The authenticity of host 'x.x.x.x (x.x.x.x)' cant be established RSA key fingerprint is X. Are you sure you want to continue connecting (yes/no)?
From everything I have read about this says this is normal for the first time sshing into it, but it should store the RSA key and no longer display this message. Is there anyway to stop this message from popping up?
Here is my code so far.
#!/usr/bin/expect -f
spawn ssh -l user x.x.x.x
sleep 3
expect "*word"
send "mypassword"
send \r
Add the following to your ssh options:
-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no
Alternatively, to avoid host key verification and not use known_hosts file for a particular remote machine, you can also add the following to /etc/ssh/ssh_config:
Host remote_machine_ip
StrictHostKeyChecking no
UserKnownHostsFile=/dev/null
/etc/ssh/ssh_config - Golbal configuration
$HOME/.ssh/config - User-specific configuration
You can expect that prompt to occur, and actually answer it:
spawn ssh -l user x.x.x.x
expect {
"connecting (yes/no)" {send "yes\r"; exp_continue}
"password:" {send "mypassword\r"}
}
exp_continue basically acts as a loop so that you can keep waiting for the password prompt.
If the "connecting" prompt does not occur, no problem: expect will see the password prompt and carry on.
Related
This question already has answers here:
ssh: The authenticity of host 'hostname' can't be established
(20 answers)
Closed 1 year ago.
we have a private network that we connect to using openconnect, then we run ssh to the server we want to work
I have a file named ssh.sh:
#!/usr/bin/expect -f
set timeout -1
spawn ssh -L 3306:localhost:3306 -L 8600:localhost:8600 -L 5672:localhost:5672 -L 5000:localhost:5000 myusername#xx.xxx.xxx.xxx
expect "myusername#xx.xxx.xxx.xxx's password:"
send -- "mypass\r"
expect eof
when I call it by ./ssh.sh command, it works. but when I call this script in another one by ./ssh.sh command, it says:
spawn ssh -L 3306:localhost:3306 -L 8600:localhost:8600 -L 5672:localhost:5672 -L 5000:localhost:5000 myusername#xx.xxx.xxx.xxx
The authenticity of host 'xx.xxx.xxx.xxx (xx.xxx.xxx.xxx)' can't be established.
ED25519 key fingerprint is SHA256:AkfGt+ZPLk5EnMl+QR4Lg1bJZwolgk%KTf1o4iFoP3E.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])?
UPDATE:
it works correctly when I just call ./ssh.sh, but not when called as subshell
even if I say yes to that message, it still doesn't connect
SSH uses a key fingerprint method to determine if you are in a secure channel. This means that the host that they are contacting provides an unfalsifiable fingerprint. However, this method requires that you actually acknowledge the their fingerprint is the right one the first time you connect, and check it on next connections. This is what
The authenticity of host 'xx.xxx.xxx.xxx (xx.xxx.xxx.xxx)' can't be established.
ED25519 key fingerprint is SHA256:AkfGt+ZPLk5EnMl+QR4Lg1bJZwolgk%KTf1o4iFoP3E.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])?
means.
Therefore, your problem likely arises from the fact that SSH saves the host fingerprint somewhere where it can access it when you call it by hand, but cannot on the other case (ie. you call it being an other user).
A solution would be, instead of accepting by hand to remember the fingerprint, to let ssh.sh do the work, with the following snippet:
expect {
"key fingerprint" {send "yes\r"; exp_continue}
"password:" {send "$pass\r"}
}
I want to Provide 'Yes' automatically or Ignore it and proceed in a SECURE way, when the below statement comes during execution of my Expect Shell script?.
#!/usr/bin/expect
spawn ssh $user#$host
The authenticity of host 'abcdef (10.566.1.98)' can't be established.
RSA key fingerprint is jk:94:ba:93:0b:eb:ff:df:ea:gh:hj:23:3c:hj:9c:be.
Are you sure you want to continue connecting (yes/no)?
It's possible to avoid this question and accept all incoming keys automaticatilly by using ssh client option StrictHostKeyChecking set to no (default setting is ask, which results in that question):
ssh -o StrictHostKeyChecking=no "$user#$host"
However, note that it would be hardly any secure, as you're basically accepting connect with everyone who may act as a given host. The only secure way to avoid question is to pre-distribute host public keys to clients, i.e. in form of pre-generated known hosts file, which can be used in some way like that:
ssh \
-o UserKnownHostsFile=PATH_TO_YOUR_KNOWN_HOSTS_FILE \
-o StrictHostKeyChecking=yes "$user#$host"
This way you'll avoid the question if the check fails, and ssh will result in non-zero exit status.
This works, and it's especially convenient for docker builds
ssh-keyscan hostname.example.com >> $HOME/.ssh/known_hosts
Make use of exp_continue for this scenario.
#!/usr/bin/expect
set prompt "#|>|\\\$"
spawn ssh dinesh#myhost
expect {
#If 'expect' sees '(yes/no )', then it will send 'yes'
#and continue the 'expect' loop
"(yes/no)" { send "yes\r";exp_continue}
#If 'password' seen first, then proceed as such.
"password"
}
send "root\r"
expect -re $prompt
Reference : Expect
I want to write a script that automatically connects me via SSH to a given IP, and after that opens a telnet session from where it just connected.
My expect code till now:
# $1 = ssh root#111.111.111.111
# $2 = password
# $3 = telnet 123.123.123.123 10023
(expect -c "
set timeout 20
spawn $1
expect {
\"Password:\" { send \"$2\r\" }
timeout { send_error \"\nTimeout!\n\"; exit 1; }
}
spawn $3
interact
" )
My problem is that I cannot spawn the telnet in the ssh session, the script is just "telnetting" from my home directory. Maybe there is a way with session ids, but I could not find helpful information.
Would be nice if someone of you could suggest some solution or workaround,
thanks in advance and please excuse my bad English skills :)
Edit:
What helped with my problem, was:
(expect -c "
set timeout 20
spawn ssh root#server telnet server2
expect {
\"Password:\" { send \"$2\r\" }
timeout { send_error \"\nTimeout!\n\"; exit 1; }
}
interact
" )
I'd have a bit of a different approach for you, easier maybe.
As I understand it:
You want to SSH into a server of yours and from there telnet to another place
Did you consider using key based authentication with SSH ?
For this approach you would add your identity key to .ssh/authorized_keys on the remote server.
Here is an example which uses expect from command line, connects to a SSH server using a key file and from there connects to a mailserver and sends "HELO test"
Tested it on my servers, works
expect -c 'expect "\n" {eval spawn ssh -i identity_file my.sshserver.com telnet mail.anotherserver.com 25; expect "SMTP" {send "HELO test\r\n"};interact}'
you can also add a timeout option to ssh (-oConnectTimeout)
It will connect to the server and call the telnet command, so you would have an open SSH session which has telnet already connected.
The script waits for an initial ENTER from you to start.
As you also asked for a Workaround, here is one: You can use ssh port forwarding
ssh -f -N -n root#111.111.111.111 -L 10024:123.123.123.123:10023
[wait for connecting]
telnet localhost 10024
Here, ssh will open a connection and go into background. the local ssh client will listen on port 10024 and redirect all traffic to 123.123.123.123 port 10023. As long as this ssh instance is running, you can open and use telnet sessions (From the initial location).
I am trying to access remote ssh server from a unix client machine. For this i have used expect script which is calling a bash script to fetch some lines from server log file.
Below is my code:
#!/usr/local/bin/expect -f
set pass "password"
set prompt "(%|$|#)"
spawn ssh deployed#172.16.166.111
expect "password:"
send "$pass\r"
expect -re $prompt
send -- "./access_srvr_log.sh\r"
send -- "exit\r"
code for access_srvr_log.sh file:
#!/usr/local/bin/expect
dir="/home/deployer/Desktop/McKinsey-McKinsey-AdminPanel/log"
tail -n 100 $dir/development.log
echo "hello"
echo >> log.txt
i get this error :
./access_srvr_log.sh
-bash: ./access_srvr_log.sh: No such file or directory
Please help. I have tried lot many changes on the above code and finally reached here.
Thanks.
Friends don't let friends use SSH passwords. It's much less secure.
Use ssh-copy-id to copy your public key to the remote server. (It puts the client ~/.ssh/id_rsa.pub into the server .ssh/authorized_keys) Now you can run "ssh deployer#172.16.144.111 ./access_srvr_log.sh", and it won't prompt for a password. That means you no longer need expect and all the odd problems that come with it.
In fact, it's highly recommended that you disable SSH passwords all together.
To make your script even simpler (maintenance-wise) do this:
1) run ssh-keygen -f ~/.ssh/scriptkey on your client (don't enter a password).
2) Put the public part of your key (~/.ssh/scriptkey.pub on the client) into .ssh/authorized_keys on the server. But this time, put command="/home/deployer/access_srvr_log.sh" just before your new key. This tells the server to run that command for that key.
3) Now your script doesn't even need to specify the command, just the private key. (i.e. scp -i ~/.ssh/scriptkey deployer#172.16.144.111 will run the script). This allows the server to change (i.e. move the script, change the script name) without changing the client. It also means someone stealing your (non-password-protected) key can't log in to the server, but only run your log script.
And there are no guessable passwords laying around in scripts. (You are checking your scripts into version control, right?)
You can simplify it down too
#!/bin/bash
{
/usr/bin/expect <<- EOF
spawn ssh deployer#172.16.144.111 "tail -n 100 /home/deployer/Desktop/McKinsey-McKinsey-AdminPanel/log/development.log"
expect "password:"
send "deployer\r"
expect eof
EOF
} |grep -v "deployer#172.16.144.111's password:">> log.txt
I realize this question has been asked a few times but I could not find a relevant answer anywhere in my searching.
I am working in a development environment where security is not an issue and anyone could just guess the password if the thought for a few seconds.
What I am trying to do is simple. I have created an alias function in my local .bashrc file and I would like this function to automatically log into a machine with a default password.
My current implementation looks something like this:
function s () {
ssh root#192.168.1.$1
}
When I run it I get something like this:
~]s 122
ssh root#192.168.1.122
root#192.168.1.122's password:
Using Bash, and not using RSA keys I would like to get this to use the default password 'password'.
I've tried the following where IP and User have already been set.
Do=$(expect -c "
spawn ssh $User#${IP[0]}.${IP[1]}.${IP[2]}.${IP[3]}
expect \"yes/no\"
send \"yes\r\"
expect \"assword\" send \"password\"")
echo $Do
$Do
It gives the follwing error:
Connecting and logging into server using expect
usage: send [args] string
while executing
"send"
invoked from within
"expect "assword" send "password""
Administrator#192.168.1.176's password:
bash: spawn: command not found...
Using the following command I am able to connect a machine. If I remove the interact it just runs the uptime command and closes the connection. With the interact command I am unable to see what I am typing or actually interact with the machine. Any ideas?
Do=$(expect -c "spawn ssh $User#${IP[0]}.${IP[1]}.${IP[2]}.${IP[3]}; set timeout 4; expect \"assword\"; send \"password\n\"; expect \"test\"; send \"uptime\n\"; interact;");echo $Do;
You can do this with the expect tool: http://expect.sourceforge.net/
It's widely available, so depending on your system, the equivalent of sudo apt-get install expect or yum install expect will install it.
Here's an example of an expect script with ssh. This logs you in and gives you control of the interactive prompt:
#!/usr/bin/expect
set login "root"
set addr "127.0.0.1"
set pw "password"
spawn ssh $login#$addr
expect "$login#$addr\'s password:"
send "$pw\r"
expect "#"
send "cd /developer\r"
interact
Here's an example of how to use expect as part of a bash script. This logs in with ssh, cd to /var, runs a script, then exits the ssh session.
#!/bin/bash
...
login_via_ssh_and_do_stuff() {
# build the expect script in bash
expect_sh=$(expect -c "
spawn ssh root#127.0.0.1
expect \"password:\"
send \"password\r\"
expect \"#\"
send \"cd /var\r\"
expect \"#\"
send \"chmod +x my_script.sh\r\"
expect \"#\"
send \"./my_script.sh\r\"
expect \"#\"
send \"exit\r\"
")
# run the expect script
echo "$expect_sh"
}
You can leave these snippets in a script on your local system, and then just alias to the scripts.
Also: I know you said security isn't an issue, but I'd like to just note, again, that the "proper" way to ssh without using a password is to use a ssh key-pair =)
Use sshpass which is available in package repositories on major Linux-es.
For example, when password is in password.txt file:
sshpass -fpassword.txt ssh username#hostname
sshpass runs ssh in a dedicated tty, fooling it into thinking it is
getting the password from an interactive user.