Host key verification failed even though I use `-o StrictHostKeyChecking=no` - ssh

I try to run:
ssh -o StrictHostKeyChecking=no ${REGR_IP_ADDR}/deploy_jar.sh 1
and I get
14:02:54 Host key verification failed.
14:02:54 lost connection

StrictHostKeyChecking does not turn off the verification, if you already stored the public key of this host. Common combination is with UserKnownHostsFile=/dev/null, which makes sure that there is no other previous public key.
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ${REGR_IP_ADDR}/deploy_jar.sh 1
Should do the job for you. But note that it is not recommended in live environment, because it is the only mechanism protecting you against MITM attack.

Related

Ansible SSH authentication with password and private key

For security reasons and compliance, we're required to set up 2FA on our hosts. We implement it by forcing authentication with passwords AND a public key with the AuthenticationMethods setting in sshd_config. The private key is required to have a password as well.
So in order to run playbooks on these hosts, we need to be able to enter the login password and the password of the private key. I've used the -k flag together with the ansible_ssh_private_key_file option in the hosts file (or with the --private-key flag). It asks for the SSH login password but then it just hangs and never asks me for the private key passphrase. When I set the -vvvv flat I see that the key is passed correctly, but the SSH login password isn't passed with the command:
<10.1.2.2> SSH: EXEC sshpass -d10 ssh -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o Port=22022 -o 'IdentityFile="/home/me/.ssh/id_ed25519"' -o 'User="me"' -o ConnectTimeout=10 -o ControlPath=/home/me/.ansible/cp/db574551ae 10.1.2.2 '/bin/sh -c '"'"'echo ~me && sleep 0'"'"''
How can I make Ansible work with both passwords and public keys?
As stated in the Ansible Documentation:
Ansible does not expose a channel to allow communication between the user and the
ssh process to accept a password manually to decrypt an ssh key when using the ssh
connection plugin (which is the default). The use of ssh-agent is highly recommended.
This is why you don't get prompted to type in your private key password. As said in the comments, setup a ssh agent, when you'll be prompted for it:
$ ssh-agent bash
$ ssh-add ~/.ssh/id_rsa
Then, after playbook execution, clear out identities so to be asked for passwords the next time:
# Deletes all identities from the agent:
ssh-add -D
# or, instead of adding identities, removes identities (selectively) from the agent:
ssh-add -d <file>
You may pack key addition, playbook execution and cleaning into one wrapper shell script.

Remote port forwarding with ssh keys

I'm trying to access localhost:6006 on my remote ubuntu machine using public keys, and put it on my localhost:6006.
The command is something similar to:
ssh -N -L 127.0.0.1:6006:127.0.0.1:6006 ubuntu#XXX.XX.XX.XXX
but I keep getting public key denied (but I can access the computer with my keys via normal ssh)
You should specify your private key with option -i.
ssh -i [path_of_your_private_key] -N -L 127.0.0.1:6006:127.0.0.1:6006 ubuntu#XXX.XX.XX.XXX

How to make an SSH RSA key auto accept?

I need to check a bunch of servers via SSH (RAM, disk, CPU model, etc).
I want to make a script for it. But the RSA key yes/no is getting in the way.
Is it possible to auto accept the RSA key while connecting to the server via SSH?
(I.e. ssh root#ip "yes" or some workaround?)
To tell ssh not to worry about host keys, simply set the StrictHostKeyChecking option to no, i.e.
ssh -o StrictHostKeyChecking=no root#ip
If you also want to pass the password to it, you can do that using sshpass:
sshpass -p your_password ssh -o StrictHostKeyChecking=no root#ip
However, you'd be much better off using an ssh agent (such as PAgeant) and ssh key pairs - better than having your password hard-coded into a script somewhere.

How to reuse an ssh connection

I'm creating a small script to update some remote servers (2+)
I am making multiple connects to each server; is there a way I can reuse the SSH connections so I don't have to open too many at once?
If you open the first connection with -M:
ssh -M $REMOTEHOST
subsequent connections to $REMOTEHOST will "piggyback" on the connection established by the master ssh. Most noticeably, further authentication is not required. See man ssh_config under "ControlMaster" for more details. Use -S to specify the path to the shared socket; I'm not sure what the default is, because I configure connection sharing using the configuration file instead.
In my .ssh/config file, I have the following lines:
host *
ControlMaster auto
ControlPath ~/.ssh/ssh_mux_%h_%p_%r
This way, I don't have to remember to use -M or -S; ssh figures out if a sharable connection already exists for the host/port/username combination and uses that if possible.
This option is available in OpenSSH since 2004.
I prefer the method described at Puppet Labs https://puppetlabs.com/blog/speed-up-ssh-by-reusing-connections
Add these lines to ~/.ssh/config and run mkdir ~/.ssh/sockets
Host *
ControlMaster auto
ControlPath ~/.ssh/sockets/%r#%h-%p
ControlPersist 600
Read the full blog post for more useful information about what these do and the idiosyncrasies of ssh when used like this. I highly recommend reading the blog or you may find things don't work as you expect.
Alternatively, you can do it this way:
$ssh_conn="ssh -t -o ControlPath=~/.ssh/master-$$ -o ControlMaster=auto -o ControlPersist=60"
$ssh_conn user#server
ControlPath=~/.ssh/master-$$ sets up a control path for the ssh
connection limiting connection reuse to the current shell (via the
$$ PID)
ControlMaster=auto allows the connection session to be
shared using the ControlPath
ControlPesist=60 sets the amount of
time the connection should remain open due to inactivity
For modern-distro setups that have a /run/user/$UID/ for just-this-boot runtime stuff,
controlmaster auto
controlpath /run/user/%i/ssh-%C
controlpersist 900
at the top of the config (where no match or host restrictions are in effect) will set all ssh sessions that share hosts, port and remote username to use a single connection. I keep addkeystoagent yes and identityfile ~/.ssh/id_ed25519 up there too so ssh doesn't offer all my keys for every host.

ssh: The authenticity of host 'hostname' can't be established

When i ssh to a machine, sometime i get this error warning and it prompts to say "yes" or "no". This cause some trouble when running from scripts that automatically ssh to other machines.
Warning Message:
The authenticity of host '<host>' can't be established.
ECDSA key fingerprint is SHA256:TER0dEslggzS/BROmiE/s70WqcYy6bk52fs+MLTIptM.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'pc' (ECDSA) to the list of known hosts.
Is there a way to automatically say "yes" or ignore this?
Depending on your ssh client, you can set the StrictHostKeyChecking option to no on the command line, and/or send the key to a null known_hosts file. You can also set these options in your config file, either for all hosts or for a given set of IP addresses or host names.
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no
EDIT
As #IanDunn notes, there are security risks to doing this. If the resource you're connecting to has been spoofed by an attacker, they could potentially replay the destination server's challenge back to you, fooling you into thinking that you're connecting to the remote resource while in fact they are connecting to that resource with your credentials. You should carefully consider whether that's an appropriate risk to take on before altering your connection mechanism to skip HostKeyChecking.
Reference.
Old question that deserves a better answer.
You can prevent interactive prompt without disabling StrictHostKeyChecking (which is insecure).
Incorporate the following logic into your script:
if [ -z "$(ssh-keygen -F $IP)" ]; then
ssh-keyscan -H $IP >> ~/.ssh/known_hosts
fi
It checks if public key of the server is in known_hosts. If not, it requests public key from the server and adds it to known_hosts.
In this way you are exposed to Man-In-The-Middle attack only once, which may be mitigated by:
ensuring that the script connects first time over a secure channel
inspecting logs or known_hosts to check fingerprints manually (to be done only once)
To disable (or control disabling), add the following lines to the beginning of /etc/ssh/ssh_config...
Host 192.168.0.*
StrictHostKeyChecking=no
UserKnownHostsFile=/dev/null
Options:
The Host subnet can be * to allow unrestricted access to all IPs.
Edit /etc/ssh/ssh_config for global configuration or ~/.ssh/config for user-specific configuration.
See http://linuxcommando.blogspot.com/2008/10/how-to-disable-ssh-host-key-checking.html
Similar question on superuser.com - see https://superuser.com/a/628801/55163
Make sure ~/.ssh/known_hosts is writable. That fixed it for me.
The best way to go about this is to use 'BatchMode' in addition to 'StrictHostKeyChecking'. This way, your script will accept a new hostname and write it to the known_hosts file, but won't require yes/no intervention.
ssh -o BatchMode=yes -o StrictHostKeyChecking=no user#server.example.com "uptime"
This warning is issued due the security features, do not disable this feature.
It's just displayed once.
If it still appears after second connection, the problem is probably in writing to the known_hosts file.
In this case you'll also get the following message:
Failed to add the host to the list of known hosts
You may fix it by changing owner of changing the permissions of the file to be writable by your user.
sudo chown -v $USER ~/.ssh/known_hosts
Edit your config file normally located at '~/.ssh/config', and at the beggining of the file, add the below lines
Host *
User your_login_user
StrictHostKeyChecking no
IdentityFile ~/my_path/id_rsa.pub
User set to your_login_user says that this settings belongs to your_login_user
StrictHostKeyChecking set to no will avoid the prompt
IdentityFile is path to RSA key
This works for me and my scripts, good luck to you.
Ideally, you should create a self-managed certificate authority. Start with generating a key pair:
ssh-keygen -f cert_signer
Then sign each server's public host key:
ssh-keygen -s cert_signer -I cert_signer -h -n www.example.com -V +52w /etc/ssh/ssh_host_rsa_key.pub
This generates a signed public host key:
/etc/ssh/ssh_host_rsa_key-cert.pub
In /etc/ssh/sshd_config, point the HostCertificate to this file:
HostCertificate /etc/ssh/ssh_host_rsa_key-cert.pub
Restart the sshd service:
service sshd restart
Then on the SSH client, add the following to ~/.ssh/known_hosts:
#cert-authority *.example.com ssh-rsa AAAAB3Nz...cYwy+1Y2u/
The above contains:
#cert-authority
The domain *.example.com
The full contents of the public key cert_signer.pub
The cert_signer public key will trust any server whose public host key is signed by the cert_signer private key.
Although this requires a one-time configuration on the client side, you can trust multiple servers, including those that haven't been provisioned yet (as long as you sign each server, that is).
For more details, see this wiki page.
Do this -> chmod +w ~/.ssh/known_hosts. This adds write permission to the file at ~/.ssh/known_hosts. After that the remote host will be added to the known_hosts file when you connect to it the next time.
With reference to Cori's answer, I modified it and used below command, which is working. Without exit, remaining command was actually logging to remote machine, which I didn't want in script
ssh -o StrictHostKeyChecking=no user#ip_of_remote_machine "exit"
Add these to your /etc/ssh/ssh_config
Host *
UserKnownHostsFile=/dev/null
StrictHostKeyChecking=no
Generally this problem occurs when you are modifying the keys very oftenly. Based on the server it might take some time to update the new key that you have generated and pasted in the server. So after generating the key and pasting in the server, wait for 3 to 4 hours and then try. The problem should be solved. It happened with me.
The following steps are used to authenticate yourself to the host
Generate a ssh key. You will be asked to create a password for the key
ssh-keygen -f ~/.ssh/id_ecdsa -t ecdsa -b 521
(above uses the recommended encryption technique)
Copy the key over to the remote host
ssh-copy-id -i ~/.ssh/id_ecdsa user#host
N.B the user # host will be different to you. You will need to type in the password for this server, not the keys password.
You can now login to the server securely and not get an error message.
ssh user#host
All source information is located here:
ssh-keygen
For anyone who finds this and is simply looking to prevent the prompt on first connection, but still wants ssh to strictly check the key on subsequent connections (trust on first use), you can set StrictHostKeyChecking to accept-new in ~/.ssh/config, which will do what you're looking for. You can read more about it in man ssh_config. I strongly discourage disabling key checking altogether.
Run this in host server it's premonition issue
chmod -R 700 ~/.ssh
I had the same error and wanted to draw attention to the fact that - as it just happened to me - you might just have wrong privileges.You've set up your .ssh directory as either regular or root user and thus you need to be the correct user. When this error appeared, I was root but I configured .ssh as regular user. Exiting root fixed it.
This is trying to establish password-less authentication. So, if you try to run that command manually once, it will ask to provide the password there. After entering password, it saves that password permanently, and it will never ask again to type 'yes' or 'no'.
For me the reason is that I have wrong permission on ~/.ssh/known_hosts.
I have no write permission on known_hosts file. So it ask me again and again.
In my case, the host was unkown and instead of typing yes to the question are you sure you want to continue connecting(yes/no/[fingerprint])? I was just hitting enter .
I solve the issue which gives below written error:
Error:
The authenticity of host 'XXX.XXX.XXX' can't be established.
RSA key fingerprint is 09:6c:ef:cd:55:c4:4f:ss:5a:88:46:0a:a9:27:83:89.
Solution:
1. install any openSSH tool.
2. run command ssh
3. it will ask for do u add this host like.
accept YES.
4. This host will add in the known host list.
5. Now you are able to connect with this host.
This solution is working now......