I am applying configuration management to a VPS hosted by a VPS hosting company. Changing the hosting company is not an option, unfortunately.
This VPS has the following properties:
- when newly-imaged or re-imaged, it generates a new, random, SSH public/private key-pair;
- neither the VPS hosting company's web interface, nor the VPS hosting company's API, provide a way to replace that key-pair a known key-pair;
- neither the VPS hosting company's web interface, nor the VPS hosting company's API, provide a way to obtain that key-pair's public key fingerprint;
- the VPS host does not have signed (e.g. DNSSEC) DNS records;
- the VPS hosting company's web interface and API do allow the VPS's IP address to be retrieved;
- the VPS hosting company's web interface and API do use TLS, and have a valid certificate from a decent CA;
- the VPS hosting company's web interface does allow an SSH client's public key to be uploaded, after which each time the VPS is re-imaged it will add that public key to a specified account's
.ssh/authorized_keys
file.
The first point above is normally a good thing, but coupled with the next two points, it means that it is impossible for the configuration management tool, when it attempts to log in to the VPS via SSH for the first time after the VPS has been re-imaged, to tell for sure whether the connection is being man-in-the-middled. In other words, the configuration management tool can, at best, use the trust-on-first-use ("TOFU") approach.
Normally, I would use a VPS's fully qualified hostname as the VPS's identifier in the configuration management tool, and I would avoid the need for TOFU by separately obtaining the VPS's SSH public key fingerprint out of band (e.g. via a secure API). With this particular VPS, though, the latter step is not possible.
As such, connecting via the fully qualified hostname seems to risk a MITM attack, e.g. via DNS spoofing, exploiting the fact that the configuration management tool would have to TOFU.
It seems to me that the most secure option here would be to fetch the VPS's IP address from the API over HTTPS, and have the configuration management tool SSH to that instead. At least this would avoid the DNS spoofing risk.
(Also, taking advantage of point 7 above will mean that even if a malicious server successfully masquerades as the VPS, at least the malicious server will not obtain the client's password or private key.)
Am I correct about this? Are there other risks, or better solutions, that I am overlooking?