Paramiko’s host key policy determines what happens when connecting to an SSH server whose host key is not present in the local known_hosts
file. Properly configuring MissingHostKeyPolicy
balances convenience and security. This article explains built-in policies, risks, and how to implement secure custom policies.
1. Why Host Key Policies Matter
SSH host keys verify server identity. If a key is unknown, you risk connecting to a malicious host. MissingHostKeyPolicy handles unknown keys on initial connections.
2. Built-In Host Key Policies
Policy | Behavior | Use Case |
---|---|---|
RejectPolicy |
Refuses connection if key is unknown | Highest security; manual key management |
AutoAddPolicy |
Adds unknown key to host keys and connects | Convenience; for trusted environments |
WarningPolicy |
Logs warning on unknown key but connects | Development/testing; audit notifications |
3. Selecting a Policy
Balance security vs. automation:
- Production: Use
RejectPolicy
and provision keys via secure channels. - Automation: Use
AutoAddPolicy
only within controlled networks. - Development: Use
WarningPolicy
to track unexpected hosts.
4. Configuring Host Key Policy in Code
import paramiko ssh = paramiko.SSHClient() ssh.load_system_host_keys() # Example: Auto-add unknown keys ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect('example.com', username='user')
5. Implementing a Custom Policy
Create a policy to validate against a remote key server or fingerprint whitelist:
from paramiko.client import MissingHostKeyPolicy class CustomPolicy(MissingHostKeyPolicy): def __init__(self, allowed_fingerprints): self.allowed = allowed_fingerprints def missing_host_key(self, client, hostname, key): fp = key.get_fingerprint().hex() if fp in self.allowed: client._host_keys.add(hostname, key.get_name(), key) else: raise paramiko.BadHostKeyException(hostname, key, None) # Usage allowed = {'3f:2a:...'} # hex-encoded fingerprints ssh = paramiko.SSHClient() ssh.load_system_host_keys() ssh.set_missing_host_key_policy(CustomPolicy(allowed)) ssh.connect('example.com', username='user')
Tip: Obtain fingerprints from out-of-band secure channels to avoid MITM attacks.
6. Summary Checklist
- Always
load_system_host_keys()
or manually load a known_hosts file. - Choose
RejectPolicy
for production security. - Use
AutoAddPolicy
only in trusted, internal environments. - Use
WarningPolicy
in development to log unknown hosts. - Implement custom policies to enforce fingerprint whitelists or external validation.