Using Namecheap's Free SSL with Nginx

⚠️  Archived — Originally published November 2009

This article describes an obsolete method for obtaining and installing SSL certificates. 1024-bit RSA keys and manually-assembled certificate bundles are no longer recommended. An updated guide covering Let's Encrypt, Certbot, and modern TLS practices is coming soon. The content below is preserved for reference only at this time, but may be removed once a modern guide is published.

Most of my domains are registered with Namecheap, and powered by Nginx. The site you are viewing now is one such example. Currently with Namecheap, domain registrations, hosting, transfers and WhoIS protection come with a free PositiveSSL subscription (course even if they eventually stop that special, 9.95/year is still a good price for a PositiveSSL certificate). This section will show you how to generate a certificate request with OpenSSL and how to install the provided certificate into Nginx.

Most hosting providers that allow you to install a SSL certificate will normally be using a Cpanel/WHM setup with the Apache Webserver. In which case SSL installation can be quite and visually straight forward, as its pretty much cut and paste back an forth. While you don't get this luxery with Nginx, its not that difficult to configure.

What you will need on the server:

A unique IP address. The domain you are getting the certificate for does not have the be the only domain served on the chosen IP address. However Nginx will only serve one certificate per IP. An attempt to install two certificates on the same IP will result in the latter domain serving the previous domain's certificate.

SSH access. Otherwise known as 'shell access', would be required to perform most of the tasks yourself. If you have installed Nginx onto a remote server yourself, then chances are you have shell access. Also if you're running Nginx you're not likely using shared hosting, which is normally void of shell access.

OpenSSL In order to actually generate a request and serve the certificate you will need OpenSSL installed. Using a repository such as yum on CentOS you can install this with the package openssl and openssl-devel (depending on the repository the package names could vary).

Nginx webserver configured with SSL. In order for Nginx to serve SSL certificates, Nginx must be built with the option --with-http_ssl_module. To verify you can run nginx -V from the terminal to see all the options your current release was built with. If you installed Nginx from a repository, you may need to see if there exists a SSL variation. KBeezie.com is currently running on Nginx 1.0 and hosted by IonVz.

Assuming you have all the above in place, we can start by creating private key followed by the CSR file otherwise known as a Certificate Signing Request.


First thing we need to do is create a private key for your site, this key will be used both in Nginx and in creating the certificate signing request. To make things easier create a folder called certs in your Nginx configuration folder (ie: /opt/local/nginx/conf).

$ mkdir /opt/local/nginx/conf/certs
$ cd /opt/local/nginx/conf/certs
$ openssl genrsa -des3 -out domain.key 1024

You will be prompted to enter a passphrase (make sure you remember this). Once the key has been generated you'll need to make a certificate signing request.

$ openssl req -new -key domain.key -out domain.csr

Above will prompt you for the passphrase you entered above. Then it'll prompt you for your country code, state, city, business/company name, unit name (can be blank), common name, email address and some extra information.

When it comes to the common name, it is very important to understand that the free PositiveSSL is not the more expensive wildcard certificate. Meaning if you are assigning a certificate to subdomain.domain.com , the certificate will only be good for that specific domain, likewise a certificate made for www.domain.com won't be good for any other subdomain.

You'll also want to make sure to use a valid email address, as the certificate providers may send your final certificate to that address.

Now that you have created a CSR file, you'll want to grab the content of the file for your SSL order.

$ cat ./domain.csr
-----BEGIN CERTIFICATE REQUEST-----
MIIBnTCCAQYCAQAwXTELMAkGA1UEBhMCU0cxETAPBgNVBAoTCE0yQ3J5cHRvMRIw
EAYDVQQDEwlsb2NhbGhvc3QxJzAlBgkqhkiG9w0BCQEWGGFkbWluQHNlcnZlci5l
eGFtcGxlLmRvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAr1nYY1Qrll1r
uB/FqlCRrr5nvupdIN+3wF7q915tvEQoc74bnu6b8IbbGRMhzdzmvQ4SzFfVEAuM
MuTHeybPq5th7YDrTNizKKxOBnqE2KYuX9X22A1Kh49soJJFg6kPb9MUgiZBiMlv
tb7K3CHfgw5WagWnLl8Lb+ccvKZZl+8CAwEAAaAAMA0GCSqGSIb3DQEBBAUAA4GB
AHpoRp5YS55CZpy+wdigQEwjL/wSluvo+WjtpvP0YoBMJu4VMKeZi405R7o8oEwi
PdlrrliKNknFmHKIaCKTLRcU59ScA6ADEIWUzqmUzP5Cs6jrSRo3NKfg1bd09D1K
9rsQkRc9Urv9mRBIsredGnYECNeRaK5R1yzpOowninXC
-----END CERTIFICATE REQUEST-----

You'll want to copy the output for this next step.

If you have not yet ordered a domain or transferred a domain to Namecheap, be sure to watch for the Comodo SSL offer that shows up near the end of checkout. It will look something like this:

SSL Option

Simply click the link to add it to your order. The SSL Certificate is not restricted just to the domain you ordered or transferred (as it also comes with hosting and whois guard) since you assign a domain after the order has been completed.

Now you should be able to click on "SSL Certificates" -> "Your SSL Certificates", and see a list similar to this.

Your SSL Certs

As you can see I been taking advantage of their special lately (there's least 3 others not shown above already assigned).

To start assigning a certificate to a domain click on the "Activate Now" link. You'll then see a form showing the type of certificate, number of years purchased, the server type and a text area. You'll want to select "Other" for server type as there's no Nginx option. You would then paste your CSR content into the box provided.

Once you click next it'll ask you to verify your information and select an email to receive the certificate. When completed it'll take roughly two hours to receive.

Once received from "NameCheap.com SSLSupport", you'll see your certificate in the email starting with -----BEGIN CERTIFICATE------". What you will want to do is save that content into a file domain.crt and upload it to your /nginx/conf/certs folder.

But we've run into a problem... Nginx supports PEM formated certificates and this is not a PEM formated certificate. So we'll need to use OpenSSL to convert it to the PEM format.

openssl x509 -in domain.crt -out domain.der -outform DER
openssl x509 -in domain.der -inform DER -out domain.pem -outform PEM

You should now have a PEM file.


Now we need to actually configure Nginx for the certificates. So open up your Nginx configuration file and we'll copy the configuration of the domain you wish to secure resulting in something like this (I've removed some extra stuff to concentrate mainly on the SSL options here).

server {
 	listen 80;
	server_name subdomain-if-used.your-domain.com;

	# ... rest of your stuff here
}
server {
	# to ensure you do not cause issues with certificates, 
	# explicitly bind the domain to its intended IP.
 	listen 1.1.1.1:443;
	server_name subdomain-if-used.your-domain.com;

	# the next three lines enables the SSL Certificate to be served
	ssl on;
	ssl_certificate certs/domain.pem;
	ssl_certificate_key certs/domain.key;	

	# ... rest of your stuff here
}

With the exception of the listening IP/Port, and SSL options the two configurations could remain identical.
Once saved you'll need to restart Nginx. You'll notice when you restart it'll ask for your PEM passphrase, the same one that was used when creating the private key.

If you are using a subdomain such as billing.your-domain.com and you want to revert ALL traffic to the secure domain, you can use a configuration like this:

server { 
 listen 1.1.1.1:80; 
 server_name billing.domain.com; 
 rewrite ^(.*) https://$server_name$1 permanent; 
}
server {
 	listen 1.1.1.1:443;
	server_name billing.domain.com;

	ssl on;
	ssl_certificate certs/domain.pem;
	ssl_certificate_key certs/domain.key;	

	# ... rest of your stuff here
}

The above will redirect all requests at the unsecured location to the secure location.
If you would rather control the destination via links on your site, you can actually simplify your configuration by merging both the unsecured and secured configuration into a single server { } block.

server {
	listen 1.1.1.1:80; 
	listen 1.1.1.1:443 default ssl; 

	server_name billing.domain.com;

	#ssl on; this can be turned off since the above will automatically enable it
	ssl_certificate certs/domain.pem;
	ssl_certificate_key certs/domain.key;	

	# ... rest of your stuff here
}

From there it'll automatically serve up the certificate when someone comes in on port 443 (https).

To remove the passphrase from your server key, so that you don't have to re-enter it every time you restart Nginx.

$ cp server.key server.key.org
$ openssl rsa -in server.key.org -out server.key
$ chmod 400 server.key

The last line makes it where only root can read the new unencrypted server key (very important that someone doesn't get ahold of this, or they can imitate you). If you are not running Nginx as root, adjust the permissions accordingly.