Skip to main content

Steps to generate CSR for SAN certificate with openssl

 

What are SAN (Subject Alternative name) Certificates

  • SAN is an acronym for Subject Alternative Name
  • These certificates generally cost a little bit more than single-name certs, because they have more capabilities.
  • When you request a SAN certificate, you have the option of defining multiple DNS names that the certificate can protect.
  • Once issued, the SAN certificate will contain a primary DNS name, which is typically the main name of the website, and, further inside the cert properties, you will find listed the additional DNS names that you specified during your request.
  • This single certificate can be installed on a web server and used to validate traffic for any of the DNS names that are contained in the certificate.
  • For example have a look at the certificate of facebook.com. It is using a Subject Alternative Name with multiple DNS defined in the certificate so it avoids creating multiple certificate for each sub domain.

Steps to generate CSR for SAN certificate with openssl

 

Lab Environment

We will need RootCA certificate and Private key to sign the certificates. I have already created these certificates to demonstrate this article. I will share the commands to create the same, but if you are interested then you should check other articles on similar topic from the LEFT Sidebar MENU:

cd lab
## create a directory structure for storing the rootca certificates
mkdir root/tls/{private,certs}

## navigate inside your tls path
cd root/tls

## generate rootca private key
openssl genrsa  -out private/cakey.pem 4096

## generate rootCA certificate
openssl req -new -x509 -days 3650  -config openssl.cnf  -key private/cakey.pem -out certs/cacert.pem

## Verify the rootCA certificate content and X.509 extensions
openssl x509 -noout -text -in certs/cacert.pem

You can collect my sample openssl.cnf from a different article.

 $ cat openssl.cnf
[ ca ]
default_ca      = CA_default            # The default ca section

[ CA_default ]
dir             = root/tls             # Where everything is kept
certs           = $dir/certs            # Where the issued certs are kept
crl_dir         = $dir/crl              # Where the issued crl are kept
database        = $dir/index.txt        # database index file.
new_certs_dir   = $dir/certs            # default place for new certs.
certificate     = $dir/certs/cacert.pem         # The CA certificate
serial          = $dir/serial           # The current serial number
crlnumber       = $dir/crlnumber        # the current crl number
crl             = $dir/crl.pem          # The current CRL
private_key     = $dir/private/cakey.pem # The private key
x509_extensions = v3_ca                 # The extensions to add to the cert
name_opt        = ca_default            # Subject Name options
cert_opt        = ca_default            # Certificate field options

# crlnumber must also be commented out to leave a V1 CRL.
 crl_extensions = crl_ext

default_days    = 365                   # how long to certify for
default_crl_days= 30                    # how long before next CRL
default_md      = sha256                # use SHA-256 by default

[req]
distinguished_name = req_distinguished_name
prompt = no
[req_distinguished_name]
C = US
ST = VA
L = SomeCity
O = MyCompany
OU = MyDivision
CN = www.company.com


Generate Private Key

First of all we need a private key. Now I could have combined the steps to generate private key and CSR for SAN but let's keep it simple. I have not assigned any passphrase to the private key, you can also use -des3 encryption algorithm to add a passphrase to your private key

# openssl genrsa -out server.key 4096
Generating RSA private key, 4096 bit long modulus (2 primes)
.......................................................++++
.................++++
e is 65537 (0x010001)
IMPORTANT NOTE:
You must keep your private key safely as this CSR will only work with this private key.

 

Generate CSR for SAN Certificate

We will not use the complete /etc/pki/tls/openssl.cnf instead we will create our own custom ssl configuration file with required parameters only.

To generate CSR for SAN we need distinguished_name and req_extensions

I have also added the value for individual distinguished_name parameters in this configuration file to avoid user prompt. If you are not familiar with these parameters then I suggest you to read Things to consider when creating CSR with OpenSSL

# cat server_cert.cnf
[req]
distinguished_name = req_distinguished_name
req_extensions = req_ext
prompt = no

[req_distinguished_name]
C   = IN
ST  = Karnataka
L   = Bengaluru
O   = GoLinuxCloud
OU  = R&D
CN  = ban21.example.com

[req_ext]
subjectAltName = @alt_names

[alt_names]
IP.1 = 10.10.10.13
IP.2 = 10.10.10.14
IP.3 = 10.10.10.17
DNS.1 = centos8-2.example.com
DNS.2 = centos8-3.example.com

If you prefer to manually enter the CSR details such as Country, State, Common Name etc then you can use this configuration file

[req]
[req]
distinguished_name = req_distinguished_name
req_extensions = req_ext

[req_distinguished_name]
countryName                     = Country Name (2 letter code)
stateOrProvinceName             = State or Province Name (full name)
localityName                    = Locality Name (eg, city)
organizationalUnitName          = Organizational Unit Name (eg, section)
commonName                      = Common Name (eg, your name or your server\'s hostname)
emailAddress                    = Email Address

[req_ext]
subjectAltName = @alt_names

[alt_names]
IP.1 = 10.10.10.13
IP.2 = 10.10.10.14
IP.3 = 10.10.10.17
DNS.1 = centos8-2.example.com
DNS.2 = centos8-3.example.com

Next we will use openssl to generate our Certificate Signing Request for SAN certificate.

# openssl req -new -key server.key -out server.csr -config server_cert.cnf

Since we have used prompt=no and have also provided the CSR information, there is no output for this command but our CSR is generated

# ls -l server.csr
-rw-r--r-- 1 root root 1842 Aug 10 15:55 server.csr

 

Verify Subject Alternative Name value in CSR

Next verify the content of your Certificate Signing Request to make sure it contains Subject Alternative Name section under "Requested Extensions"

# openssl req -noout -text -in server.csr | grep -A 1 "Subject Alternative Name"
            X509v3 Subject Alternative Name:
                IP Address:10.10.10.13, IP Address:10.10.10.14, IP Address:10.10.10.17, DNS:centos8-2.example.com, DNS:centos8-3.example.com

So our CSR contains all the IP Address and DNS value which we provided while generating the CSR for SAN.

 

Generate SAN certificate

Next we will use this CSR to generate our SAN certificate:

# openssl x509 -req -days 365 -in server.csr -CA root/tls/certs/cacert.pem -CAkey root/tls/private/cakey.pem -CAcreateserial -out server.crt
Signature ok
subject=C = IN, ST = Karnataka, L = Bengaluru, O = GoLinuxCloud, OU = R&D, CN = ban21.example.com
Getting CA Private Key

 

Verify SAN Extensions in the certificate

Once the certificate is generated, let's verify if our SAN fields are retained inside the certificate:

# openssl x509 -text -noout -in server.crt | grep -A 1 "Subject Alternative Name"

We get an empty output. The SAN Extensions are missing from our certificate.

 

Missing SAN Extensions from the Certificate

This is an expected behaviour. As per official documentation from openssl

Extensions in certificates are not transferred to certificate requests and vice versa.

Due to this, the extensions which we added in our CSR were not transferred by default to the certificate. So these extensions must be added to the certificate explicitly.

 

Generate SAN Certificates with X509 extensions

We need to use -extensions argument with the name of the extension to be used from the configuration file. We have defined our SAN fields under req_ext extension so we will use the same and re-generate the certificate:

# openssl x509 -req -days 365 -in server.csr -CA root/tls/certs/cacert.pem -CAkey root/tls/private/cakey.pem -CAcreateserial -out server.crt -extensions req_ext -extfile server_cert.cnf
Signature ok
subject=C = IN, ST = Karnataka, L = Bengaluru, O = GoLinuxCloud, OU = R&D, CN = ban21.example.com
Getting CA Private Key

 

Re-verify the SAN Extensions in the certificate

Now let us re-verify the SAN extension in our certificate:

# openssl x509 -text -noout -in server.crt | grep -A 1 "Subject Alternative Name"                            
X509v3 Subject Alternative Name:
                IP Address:10.10.10.13, IP Address:10.10.10.14, IP Address:10.10.10.17, DNS:centos8-2.example.com, DNS:centos8-3.example.com

So this time our certificates are properly generated with the SAN fields.

Comments

Popular posts from this blog

CKA Simulator Kubernetes 1.22

  https://killer.sh Pre Setup Once you've gained access to your terminal it might be wise to spend ~1 minute to setup your environment. You could set these: alias k = kubectl                         # will already be pre-configured export do = "--dry-run=client -o yaml"     # k get pod x $do export now = "--force --grace-period 0"   # k delete pod x $now Vim To make vim use 2 spaces for a tab edit ~/.vimrc to contain: set tabstop=2 set expandtab set shiftwidth=2 More setup suggestions are in the tips section .     Question 1 | Contexts Task weight: 1%   You have access to multiple clusters from your main terminal through kubectl contexts. Write all those context names into /opt/course/1/contexts . Next write a command to display the current context into /opt/course/1/context_default_kubectl.sh , the command should use kubectl . Finally write a second command doing the same thing into ...

OWASP Top 10 Threats and Mitigations Exam - Single Select

Last updated 4 Aug 11 Course Title: OWASP Top 10 Threats and Mitigation Exam Questions - Single Select 1) Which of the following consequences is most likely to occur due to an injection attack? Spoofing Cross-site request forgery Denial of service   Correct Insecure direct object references 2) Your application is created using a language that does not support a clear distinction between code and data. Which vulnerability is most likely to occur in your application? Injection   Correct Insecure direct object references Failure to restrict URL access Insufficient transport layer protection 3) Which of the following scenarios is most likely to cause an injection attack? Unvalidated input is embedded in an instruction stream.   Correct Unvalidated input can be distinguished from valid instructions. A Web application does not validate a client’s access to a resource. A Web action performs an operation on behalf of the user without checkin...