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 RejectPolicyand provision keys via secure channels.
- Automation: Use AutoAddPolicyonly within controlled networks.
- Development: Use WarningPolicyto 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 RejectPolicyfor production security.
- Use AutoAddPolicyonly in trusted, internal environments.
- Use WarningPolicyin development to log unknown hosts.
- Implement custom policies to enforce fingerprint whitelists or external validation.
