Ubuntu Gutsy - Nginx, SSL and vhosts

So you've followed the Nginx self signed certificate article and now you want to configure Nginx to serve your site on the standard HTTPS port (443).

With Nginx, it is very easy to configure your virtual host to use a secure connection.


Defaults

Enabling SSL support for your site is very simple and involves the addition of just a few lines to the virtual host file.

Go ahead and open up your virtual host file:

sudo nano /etc/nginx/sites-available/domain1.com

My example vhost (details of which can be found in this article) looks like this:

server {

            listen   80;
            server_name  www.domain1.com;
            rewrite ^/(.*) http://domain1.com permanent;

           }


server {

            listen   80;
            server_name domain1.com;

            access_log /home/demo/public_html/domain1.com/logs/access.log;
            error_log /home/demo/public_html/domain1.com/logs/error.log;

            location / {

                        root   /home/demo/public_html/domain1.com/public/;
                        index  index.html;

                        }

            }

Very simple and straight forward.

Port 443

To enable the use of port 443 with our SSL certificate all we need to do is let Nginx know we want to listen on port 443 and to define the location of the certificate.

To do this, simply copy and paste the existing content so, to begin with, you have two sets of server modules that are exactly the same.

Now change the ports on the second set from 80 to 443:

server {

            listen   80;
            server_name  www.domain1.com;
            rewrite ^/(.*) http://domain1.com permanent;

           }


server {

            listen   80;
            server_name domain1.com;

            access_log /home/demo/public_html/domain1.com/logs/access.log;
            error_log /home/demo/public_html/domain1.com/logs/error.log;

            location / {

                        root   /home/demo/public_html/domain1.com/public/;
                        index  index.html;

                        }

            }



server {

            listen   443;
            server_name  www.domain1.com;
            rewrite ^/(.*) http://domain1.com permanent;

           }


server {

            listen   443;
            server_name domain1.com;

            access_log /home/demo/public_html/domain1.com/logs/access.log;
            error_log /home/demo/public_html/domain1.com/logs/error.log;

            location / {

                        root   /home/demo/public_html/domain1.com/public/;
                        index  index.html;

                        }

            }

Good.

Certificate Location

Now all we need to do is let Nginx know we want to use SSL and where the certificate is located.

As such, we need to add the following to each port 443 server module:

ssl    on;
ssl_certificate    /etc/ssl/certs/myssl.crt;
ssl_certificate_key     /etc/ssl/private/myssl.key;

Remember the locations of the crt and key files were defined during the certificate generation (see here).

So now the beginning of each port 443 server module looks like this:

server {

            listen   443;

            ssl    on;
            ssl_certificate    /etc/ssl/certs/myssl.crt;
            ssl_certificate_key    /etc/ssl/private/myssl.key;

            server_name domain1.com;

That's it.

Restart

To enable the changes we need to restart Nginx:

sudo /etc/init.d/nginx restart

Navigate

Now you are ready to navigate to your secure domain:

https://admin.domain.com

In this example, we have used a self signed certificate so you will receive a warning similar to this:

SSL Certificate Warning

All the information matches that which we entered when generating the certificate but, as it is not 'official' or 'trusted', a warning is shown.

You may also receive a second warning if you are using the certificate on a domain that does not match the Common Name setting.

However, it is perfectly fine for administration areas or private areas of your site and, of course, if you use a commercial certificate, you will not receive any warnings.

Summary

Creating a virtual host that uses an HTTPS connection to encrypt your connection is very easy to do with Nginx.

Remember a self signed certificate will produce warnings when accessed but will be fine for personal administration areas.

PickledOnion.

Article Comments:

Ben commented Fri Apr 18 18:11:52 UTC 2008 ago:

Note to SSL neophytes like me: you can have only one SSL cert per IP.

nginx will happily let you make multiple server{} entries with different SSL certs and won't complain, but only one gets bound to port 443.

The error you will get is "host name mismatch" or "domain mismatch" in the web browser.

This is true because the SSL connection is established before any HTTP information is exchanged. So by the time the HTTP request is processed by nginx, it has already used an SSL cert.

It would make more sense if the nginx config put SSL setup outside the server{} block since SSL and vhosts don't have much to do with each other.

Want to comment?


(not made public)

(optional)

(use plain text or Markdown syntax)