Search code examples
gosslhttps

Should applications accessing a user-specified host via HTTPS attempt to be helpful by looking up its FQDN?


I'm playing around with a golang app that talks to a server via HTTPS on another host. Specifically if context matters: Talking to a Dataproc cluster from a GCE instance in the same Google Cloud project (no special domain setup).

The server generates a self-signed certificate, which I've manually installed on the client side.

Both server and client are GCE instances on my Google cloud project (their FQDNs are <hostname>.c.<project_id>.internal)

If I try to connect from client to server with golang's http.Client, I get an error like:

failed to verify certificate: x509: certificate is valid for *.c.<project_id>.internal, not <server_hostname>

If, however, I pass it its FQDN (<server_hostname>.c.<project_id>.internal), it works out of the box.

For reference, this behavior is consistent with what I see when I run cURL:

curl: (60) SSL: no alternative certificate subject name matches target host name '<server_hostname>'

So my questions are:

  1. Why does it not work with the short/partial hostname? It's on the same domain, so it is part of *.c.<project_id>.internal and just work out of the box, no? Or does it always require the string the uses passes in to actually match the wildcard string (meaning it doesn't do the lookup, and would only work if you pass in the fqdn)?
  2. What's the best practice around this when building apps to distribute? Should I add some logic to have it compute a FQDN, so it can convert short names to long names that are more likely to work with self-signed certs, or leave it up to the caller to figure out the cryptic error message?

Note: I do NOT want to skip verification - I just want to better understand what's going on, and know what the best practice here is.

Thanks!


Solution

    1. Certificates are matched to domains/hosts against the names contained in them, so even though <server_hostname> and <server_hostname>.c.<project_id>.internal resolve to the same thing, the certificate only contains the second one (or a wildcard that matches it). Since these are self-generated, you can likely add the short name as a SAN (Subject Alternate Name) in there. Additional flag to OpenSSL:
    -addext "subjectAltName = DNS:localhost,DNS:<server_hostname>" 
    

    Public CA's are unlikely to give you a certificate with a SAN that is not publically resolveable however. (Some might, I haven't tried this)

    You wouldn't want google.com to be served or trusted from google.com.someevildomain.org as an example, so this exists as a security feature.

    1. This depends. If you have control over the certs, you can just add the names you expect to be using. This might end up as a single cert with many SANs, in which case it might be cleaner to get everyone talking using the FQDNs. If you can import many certs, it's possibly better to have each service have its own cert with the FQDN and the short name.