Foundations of Python Network Programming

(WallPaper) #1

Chapter 16 ■ telnet and SSh


306


To behave like the normal SSH command, load both the system and the current user’s known host keys before
making the connection.





client.load_system_host_keys()
client.load_host_keys('/home/brandon/.ssh/known_hosts')
client.connect('example.com', username='test')





The paramiko library also lets you choose how you handle unknown hosts. Once you have a client object created,
you can provide it with a decision-making class that is asked what to do if a host key is not recognized. You can build
these classes yourself by inheriting from the MissingHostKeyPolicy class.





class AllowAnythingPolicy(paramiko.MissingHostKeyPolicy):
... def missing_host_key(self, client, hostname, key):
... return
...
client.set_missing_host_key_policy(AllowAnythingPolicy())
client.connect('example.com', username='test')





Note that through the arguments to the missing_host_key() method, you receive several pieces of information
on which to base your decision. You could, for example, allow connections to machines on your own server subnet
without a host key but disallow all others.
Inside paramiko there are also several decision-making classes that already implement several basic host key options.


•    paramiko.AutoAddPolicy: Host keys are automatically added to your user host key store
(the file ~/.ssh/known_hosts on Unix systems) when first encountered, but any change in the
host key from then on will raise a fatal exception.

•    paramiko.RejectPolicy: Connecting to hosts with unknown keys simply raises an exception.

•    paramiko.WarningPolicy: An unknown host causes a warning to be logged, but the
connection is allowed to proceed.

When writing a script that will be doing SSH, I always start by connecting to the remote host “by hand” with the
normal ssh command-line tool so that I can answer “yes” to its prompt and get the remote host’s key in my host keys
file. This way, my programs should never have to worry about handling the case of a missing key and can die with an
error if they encounter one.
However, if you like doing things less by hand than I do, then the AutoAddPolicy might be your best bet. It never
needs human interaction, but it will at least assure you on subsequent encounters that you are still talking to the same
machine as before. Therefore, even if the machine is a Trojan horse that is logging all of your interactions with it and
secretly recording your password (if you are using one), it at least must prove to you that it holds the same secret key
every time you connect.


SSH Authentication

The whole subject of SSH authentication is the topic of a large amount of good documentation, as well as articles
and blog posts, all available on the Web. Information abounds about configuring common SSH clients, setting up an
SSH server on a Unix or Windows host, and using public keys to authenticate yourself so that you do not have to keep
typing your password all the time. Since this chapter is primarily about how to “speak SSH” from Python, I will just
briefly outline how authentication works.

Free download pdf