SSH known_hosts with a dynamic IP

known-hostssshssh-keystunnelingvpn

I have a machine behind a firewall. I connect to it remotely using a VPN tunneling with a port forward through ssh. To connect to the machine I use the external IP of the VPN and my personal and temporary assigned port. The command I use is:

ssh USER@VPN_IP -p PORT

Since VPN_IP and PORT change frequently I cannot get advantages of saving the host key in known_host to get rid of man man-in-the-middle attacks, but at the same time the host key is well known to me and I could provide it to ssh in order to use it for the current VPN_IP and PORT combination. Is that possible? How?

Best Answer

The known_hosts file is for providing these keys and there's no direct command line alternative (and it wouldn't be so handy, anyway). However, your goal is completely possible with the known_hosts file!

Read through man sshd's ssh_known_hosts file format.

When performing host authentication, authentication is accepted if any matching line has the proper key; either one that matches exactly or, if the server has presented a certificate for authentication, the key of the certification authority that signed the certificate.

It is possible to use wildcards in ~/.ssh/known_hosts (and /etc/ssh/ssh_known_hosts):

Each line in these files contains the following fields: markers (optional), hostnames, keytype, base64-encoded key, comment. The fields are separated by spaces.

Hostnames is a comma-separated list of patterns (* and ? act as wildcards); each pattern in turn is matched against the canonical host name (when authenticating a client) or against the user-supplied name (when authenticating a server). A pattern may also be preceded by ! to indicate negation: if the host name matches a negated pattern, it is not accepted (by that line) even if it matched another pattern on the line. A hostname or address may optionally be enclosed within [ and ] brackets then followed by ‘:’ and a non-standard port number.

It is possible to make a key trusted for

  • a network range, if known, e.g. for TEST-NET-2:

    198.51.100.* ssh-rsa AAAAB3Nza...2iQ==
    
  • multiple ranges (e.g. all TEST-NETs) using comma-separated list:

    192.0.2.*,198.51.100.*,203.0.113.* ssh-rsa AAAAB3Nza...2iQ==
    
  • or even when connecting anywhere:

    * ssh-rsa AAAAB3Nza...2iQ==
    

If this key is not present, it will still warn you about the authenticity of the other keys, show the fingerprint and add it automatically, if you answer yes. The comparison is done line by line.