Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Paramiko: Add host_key to known_hosts permanently

This code helps me make an ssh connection. I know that set_missing_host_key_policy helps when the key is not found in the known_hosts. But it is not behaving like the actual ssh, because after the first time I run this code, I assumed that that the host_key would be added to known_hosts and that I need not have the function set_missing_host_key_policy() anymore. But, I was wrong (paramiko.ssh_exception.SSHException). How can I permanently add the host_key to known_hosts using paramiko? (As a certain part of the backend code is written in 'C' and it needs the host_key to be found in known_hosts)

Or am I misunderstanding something? I would need some guidance on this...

import paramiko

client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hostname=str(host),username =str(user),password=str(pswd))
like image 226
nidHi Avatar asked Sep 16 '16 03:09

nidHi


People also ask

Where does Paramiko store host keys?

This type of file unfortunately doesn't exist on Windows, but on posix, it will usually be stored in os. path. expanduser("~/. ssh/known_hosts") .

What is Set_missing_host_key_policy?

set_missing_host_key_policy (policy) Set policy to use when connecting to servers without a known host key.

Can I delete the Known_hosts file?

Windows with PuTTY Search for regedit.exe and open it. Navigate to HKEY_CURRENT_USER/SOFTWARE/SimonTatham/PuTTy/SshHostKeys. Right click the offending key and click delete.

What is Known_hosts in .SSH folder?

The known_hosts File is a client file containing all remotely connected known hosts, and the ssh client uses this file. This file authenticates for the client to the server they are connecting to. The known_hosts file contains the host public key for all known hosts.


2 Answers

From the package documentation, compare

client.load_system_host_keys(filename=None)

Load host keys from a system (read-only) file.  Host keys read with
this method will not be saved back by `save_host_keys`.

with

client.load_host_keys(filename)

Load host keys from a local host-key file.  Host keys read with this
method will be checked after keys loaded via `load_system_host_keys`,
but will be saved back by `save_host_keys` (so they can be modified).
The missing host key policy `.AutoAddPolicy` adds keys to this set and
saves them, when connecting to a previously-unknown server.

So to make Paramiko store any new host keys, you need to use load_host_keys, not load_system_host_keys. E.g.

client.load_host_keys(os.path.expanduser('~/.ssh/known_hosts'))

But it's generally a good idea to avoid using AutoAddPolicy, since it makes you open to man-in-the-middle attacks. What I ended up doing was to generate a local known_hosts in the same folder as the script:

ssh -o GlobalKnownHostsFile=/dev/null -o UserKnownHostsFile=./known_hosts user@host

and then load this file instead:

client.load_host_keys(os.path.join(os.path.dirname(__file__), 'known_hosts'))

This way I can distribute the known_hosts together with my script and run it on different machines without touching the actual known_hosts on those machines.

like image 198
danmichaelo Avatar answered Sep 19 '22 15:09

danmichaelo


If you want to add one specific key in runtime (without any file):

from paramiko import RSAKey
from paramiko.py3compat import decodebytes

client = SSHClient()

# known host key
know_host_key = "<KEY>"
keyObj = RSAKey(data=decodebytes(know_host_key.encode()))

# add to host keys
client.get_host_keys().add(hostname=HOST, keytype="ssh-rsa", key=keyObj)

# login to ssh hostname
client.connect(hostname=HOST, port=PORT, username=USER)...

source: https://github.com/paramiko/paramiko/blob/2.6.0/tests/test_hostkeys.py#L75-L84

like image 30
Ramon Medeiros Avatar answered Sep 18 '22 15:09

Ramon Medeiros