How to: Create a Self Signed Certificate in Ubuntu
Many times during the initial phases of a Web Server deployment we are in need of testing secure communications (and its configuration) using a certificate. Unfortunately we might not have a valid certificate from a certification authority at the time. There are also other scenarios were you can’t or don’t really need a full fledged certificate so you are in need of using an alternative.
A Self Signed Certificate as its name implies, is a certificate which you are creating yourself. The benefits are clear: you control the entire process and can create a certificate with whatever characteristics you want. The downside is that because it is self-signed, in other words, not signed by a valid and trusted certification authority, most browsers/clients will get security warnings or deny the user access to the site. Clearly this solution works well for testing scenarios or personal sites where you don’t need to establish public trust. If however, you are creating an online store and you’re going into production then you more likely than not need a certificate from a certification authority. I personally recommend StartSSL as their costs are most competitive.
Now that we have cleared why you may want to create a self signed certificate, let’s focus on the actual how:
Step One — Create or choose a location for your SSL Certificate
Depending on your personal taste and needs, you might want to place your SSL certificate in a number of places. I recommend you dedicate a place to store them as you probably will want to secure access to it somehow.
Apache people like using /etc/apache2/ssl while NginX people like using /etc/nginx/conf.ssl from what I’ve seen. But clearly this is a matter of choice. Because I use shared storage, I have my SSL store on a shared mount close to my www files. Again, this is mostly a decision based on your personal/corporate taste and system requirements.
Step Two — Create your Self Signed SSL Certificate
We are going to go ahead now and create both our public certificate and private key. The public certificate is used to present yourself and for the client/browser to know how to communicate securely with your server. As the name implies, it is for public eyes so it is not necessary you protect it zealously. Your private key, again as the name implies, needs to remain private. It contains the secret on how to decrypt the communication and it is needed by your server to know how to read the encrypted communication. If someone gains access to this then they can eavesdrop the “secured” traffic to your site.
Now that we have cleared that, let’s go ahead and create our certificate:
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/conf.ssl/selfsigned.key -out /etc/nginx/conf.ssl/selfsigned.crt
Let’s go step by step over the parameters we used on this command:
- sudo: You need admin credentials in order to run the command.
- openssl: This is the command tool for OpenSSL which is used to create and manage certificates, keys, signing requests, etc.
- req: This subcommand is used to specify the parameters for the request.
- -x509: This option specifies that we want to make a self-signed certificate file instead of generating a certificate request. X.509 is a public key infrastructure standard that SSL adheres to for its key and certificate managment.
- -nodes: This option tells OpenSSL that we do not wish to secure our key file with a passphrase. The benefit of securing your private key file with a passphrase is that it can’t be used without the passphrase. In the case of a webserver, it means that everytime you start the web service you’ll need to manually provide the password. Most people won’t use a passphrase for a web server because of this.
- -days 365: This specifies for how many days the certificate will be valid for. The accepted standard nowadays is one to two years for added security. I believe 3 years has been set as the maximum allowed and 5 year certificates are considered insecure. I recommend using a validity of 1 year for most certificates. Remember, you can always get a new one before it expires.
- -newkey rsa:2048: This option will create the certificate request and a new private key at the same time. Following that we are indicating we want an RSA key and that it should be 2048 bits long. 2048 bits is the minimum size accepted as secure this days. The most common key sizes go from 2k all the way up to 16k (2k, 4k, 8k and 16k). I used to use a 16k certificate but my experience is that once you start hitting a lot of SSL traffic it does consume a lot of CPU power. That’s the reason why you’ll see 2k is the standard. There are other types of keys like -sha256 which you could use.
- -keyout: This parameter names the output file for the private key file that is being created.
- -out: This option names the output file for the certificate that we are generating.
When you hit “ENTER”, you will need to provide additional information that will go into the certificate. You can also specify an answer file which I will cover later on. This answer file is useful when you’re trying to secure multiple domains with one certificate (using a SAN – Subject Alternative Name).
Most of this information can be considered useless. Your end users will see it only when they take a peak into the certificate which will be less than 1% of the people if I had to guess. Regardless, the key piece of information is going to be the Common Name. The Common Name is the domain name that will be used by the certificate.
Common Names are key. Take for example this site: CloudIngenium.com:
- a CN of CloudIngenium.com only works for CloudIngenium.com
- a CN of www.CloudIngenium.com only works for www.CloudIngenium.com
- a CN of *.CloudIngenium.com works for Kx.CloudIngenium.com, www.CloudIngenium.com but it does not work for CloudIngenium.com.
So if you are trying to secure let’s say, your main domain name and all of its subdomains you need to use a SAN certificate. You need to use the naked domain name (CloudIngenium.com is a naked domain name as it has no subdomains www.CloudIngeniu.com is technically a subdomain) and the wildcard domain name for all subdomains (*.CloudIngenium.com).
Also, if you are using a static IP address and it is dedicated to your web server you can consider including the IP address as an alternative SAN. If you are going to access the site via IP address then you use the IP address as the common name.
Below is the additional information you are going to have to provide. If you want to use SAN then you need to use an answer file as the wizard won’t ask you for alternative names:
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) : New York City
Organization Name (eg, company) [Internet Widgits Pty Ltd]: Your Company's name LLC
Organizational Unit Name (eg, section) : IT
Common Name (e.g. server FQDN or YOUR name) : CloudIngenium.com
Email Address : [email protected]
The private key and public certificate will be created and placed in your /etc/nginx/conf.ssl/ssl directory.
Step 2.1 — Create your Self Signed SSL Certificate using multiple Subject Name Alternatives
As I mentioned above, using a regular certificate is only good for a site with no subsites (subdomains). Here we are going to explore how to create SAN certificates so one certificate can work with multiple domain names and subdomains.
In order to configure OpenSSL to use V3 Requirements (Subject Name Alternatives) we need to edit the openssl.cnf file located on Debian and Ubuntu systems this file can found at:
/usr/lib/ssl/openssl.cnf, on CentOS and Fedora at:
I. Insert the following line immediately before the “HOME” entry:
You should use your own domain name used for your server’s fully qualified domain name (FQDN) as well as a valid support email adddress. OpenSSL will append the default support email address to the SAN field for all new SSL certificates if you don’t provide a SAN variable. This is required as we cannot leave the subjectAltName parameter empty.
II. Next, add the following line immediately after the
[ v3_req ] and
[ v3_ca ] section markers.
III. Configure your “SAN” environment variable
- At the shell prompt you will issue a command to manually configure the SAN environment variable. will be read to obtain a list of alternate DNS names that should be considered valid for new certificates. Remember if you don’t specify this the only SAN that will be included is your support email address so these changes won’t cause issues if you forget to add a SAN.
- At the shell prompt type:
export SAN=”DNS:*.CloudIngenium.com, DNS:CloudIngenium.com, DNS:www.JCBauza.com, DNS:JCBauza.com”
Substitute your own domain names adding additional domains delimited by commas. Remember you need to add each subdomain and domain you want to protect and that the wildcard subdomain ‘*’ does not include the naked domain name.
Now you are ready to request your certificate again!