Today I will show you how to quickly generate ready to use self-signed SSL certificate for nginx HTTP server using command-line. It is a very handy ability that will allow you to perform various tasks locally or in home laboratory without touching dedicated certificates.
Initial notes
Use the minimal Debian Jessie
installation and basic nginx
server configuration to host and secure example.org
website used in the following examples and easily inspect commands described in this article.
Basic nginx
site configuration used in the following examples.
server { listen 443 ssl; ssl_certificate ssl/nginx.crt; ssl_certificate_key ssl/nginx.key; server_name example.org; root /var/www/html/; index index.nginx-debian.html; }
Use hosts
file or dnsmasq
to resolve domain names.
Single domain SSL certificate
The simplest possible case is to create single domain SSL certificate which can be generated using the following openssl
command.
$ sudo openssl req -subj "/commonName=example.org/" -x509 -nodes -days 730 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt
It is purely optional, but you can provide more detailed information that will be included in generated certificate. Both of the following commands are equivalent.
$ sudo openssl req -subj "/countryName=PL/stateOrProvinceName=pomorskie/organizationName=personal/localityName=Malbork/commonName=example.org/organizationalUnitName=IT/emailAddress=example@example.org/" -x509 -nodes -days 730 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt
$ sudo openssl req -subj "/C=PL/ST=pomorskie/O=personal/L=Malbork/CN=example.org/OU=IT/emailAddress=example@example.org/" -x509 -nodes -days 730 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt
Attributes are described in Additional notes section at the end of the article.
Wildcard SSL certificate
Generating wildcard SSL certificate is almost the same as the previous example, but it deserves distinct section due to asterisk label which only protects subdomains.
$ sudo openssl req -subj "/commonName=*.example.org/" -x509 -nodes -days 730 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt
You need to use two distinct certificates (example.org
and *.example.org
) or one multi-domain certificate to protect whole domain with its subdomains. Most, if not all, of the commercially available wildcard certificates will secure domain name as well as its subdomains.
It is important to know that this kind of definition using wildcard character will protects only one level of subdomains. It means that certificate with defined common name *.example.org
will protect cdn.example.org
, but not milosz.users.example.org
subdomain.
Multi-domain SSL certificate
This is where the fun begins, as creating multi-domain SSL certificate requires additional configuration file to define subject alternative names
extension. That is why, it is also sometimes named as multi-domain (SAN) certificate.
.
$ cat <<EOF | sudo tee /etc/nginx/ssl/certificate.cfg [ req ] req_extensions = req_ext distinguished_name = req_distinguished_name prompt = no [req_distinguished_name] commonName=example.org [req_ext] subjectAltName = @alt_names [alt_names] DNS.1 = example.org DNS.2 = *.example.org DNS.3 = *.users.example.org DNS.4 = example.com DNS.5 = *.example.com DNS.6 = *.users.example.com EOF
See RFC 3280 – Internet X.509 Public Key Infrastructure [ HTML | TXT | PDF] for additional information about available options (DNS
, IP
and URI
).
Generate certificate including additional req_ext
section (see x509
manual page).
$ sudo openssl req -x509 -config /etc/nginx/ssl/certificate.cfg -extensions req_ext -nodes -days 730 -newkey rsa:2048 -sha256 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt
Additional notes
The following table lists attributes that are used to describe certificate.
Attribute | Short | Description | Example |
---|---|---|---|
commonName | CN | Common name (domain) | example.org |
organizationalUnitName | OU | Organizational unit | IT Department |
organizationName | O | Organization | Personal Organization |
localityName | L | Locality | Malbork |
stateOrProvinceName | ST | State or province name | pomorskie |
countryName | C | Country name (ISO code) | PL |
emailAddress | Email address | admin@example.org |
You can also use configuration file to store definitions for single single domain SSL certificate or wildcard SSL certificate.
$ cat <<EOF | sudo tee /etc/nginx/ssl/certificate.cfg [ req ] distinguished_name = req_distinguished_name prompt = no [req_distinguished_name] commonName=example.com EOF
$ sudo openssl req -x509 -config /etc/nginx/ssl/certificate.cfg -nodes -days 730 -newkey rsa:2048 -sha256 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt
You can always print subject line using the following command.
$ openssl x509 -in /etc/nginx/ssl/nginx.crt -subject -noout
subject= /CN=*.example.org