Nowadays it’s quite common for orgnizations to request SSL/TLS certificates for multiple domains. Instead of buying an individual SSL certificate for each and every domain, a single multiple domain (Unified Communications) certificate is good enough to save cost and simplify process. This certificate will have a common name with multiple SANs (Subject Alternative Names).
Here you might be thinking of a wildcard SSL, but it’s different where a whildcard SSL secures unlimited number of sub-domains hosted on the same domain name. For example a wildcard certificate issued to *.yourdomain.com is valid for any subdomians: web.yourdomain.com, mail.yourdomain.com, blog.yourdomain.com etc.
On the other hand, a Unified Communications Certificate can have quite different domain names (public names, priviate names, even IPs) specified with SANs. For example, web.Adomain.com, web.Bdomain.com, 192.168.0.1 within one certificate.
Another scenario you would think about is that multiple application servers sit behind a load balancer. You will need a common name for your application, but sometimes when testing your application directly against the individual servers, you may want to bypass the LB and use the server name or IP of a specific server. In this case, a UCC with multiple domain names (public FQDN for the application and private server names) listed as SANs is a good fit. Otherwise, with only the public FQDN in the certificate, you will see the error NET::ERR_CERT_COMMON_NAME_INVALID in a browser when visiting the application using the server name or IP directly which is a bit of annoying.
On Linux, the command “openssl” is a versatile full-featured toolkit for the Transport Layer Security (TLS) and Secure Sockets Layer (SSL) protocols. It can be used to create certificate reuqests, issue certificate, create & manage priviate and public keys etc. We can use it to create a multi-domain certificate request.
To do so, it needs a confiugration file. The command has an option “-reqexts” which is used to specify alternative sections in the configuration file for certificate extentions or certificate request extentions.
Below is a simplified configuration file for demonstration of SANs
[req] default_bits = 2048 distinguished_name = req_distinguished_name req_extensions = req_ext prompt = no [req_distinguished_name] countryName = US stateOrProvinceName = New York localityName = Rochester organizationName = MyOrg organizationalUnitName = Information Technology & Services commonName = www.mydomain.com emailAddress = email@example.com [req_ext] subjectAltName = @alt_names [alt_names] DNS.1 = server1.domain_A.com DNS.2 = server2.domain_A.com DNS.3 = server3.domain_B.com IP.1 = 10.10.69.20 IP.2 = 10.10.75.20
Put the above content in a configuration file named san.cnf, then use the following command to generate the request file
openssl req -out ssl_cert_req.csr -newkey rsa:2048 -nodes -keyout ssl_cert_req_private.key -config san.cnf
It will create two files,
- ssl_cert_req_private.key — private key file
- ssl_cert_req.csr — certificate request file
To verify what SANs included in the request file just created:
openssl req -noout -text -in ssl_cert_req.csr | egrep "DNS|IP"
A couple of things to note in the configuration file:
- Literal values (keywords) to lead SANs: DNS, IP, email, URI, RID, dirName
- If an extension has multi-values, comma is used to separate them. And if a field value must contain a comma, the long form (as indicated in the example configuration above — @alt_names leads another section) must be used otherwise the comma would be misinterpreted as a field separator.
- The same field name can only occur once in a section, the last value wins in the section. To have multiple values in a section, append suffix “.1”, “.2” etc. That’s why DNS.1, DNS.2, DNS.3 is used.
- “prompt=no” will direct openssl to take values from the configuration file instead of asking input from the user.
To get more information, check man pages:
- man 1 req
- man 5 x509v3_config
- man openssl