Setup your own https server with nginx


You would like to setup a nginx server with a HTTPS handler. The setup will used pem certificates so we will look at both generating your own certificates and That handler will used signed certificates in this post.

https is required for most callbacks handler for bot services, so this post will be used in the context of having nginx running in front of a clojure based application.

trying the self-signed cert

To generate your own certificates in pem format, you can use the openssl command. If you don’t set the -subj parameter, questions will be asked in real time at the prompt.

openssl req -newkey rsa:2048 -sha256 -nodes -keyout YOURPRIVATE.key -x509 -days 365 -out YOURPUBLIC.pem -subj "/C=US/ST=New York/L=Brooklyn/O=Example Brooklyn Company/"

Make really sure the value of the CN parameter in the command is equal to your website hostname, here

convert a certificate from your SSL provider

If you have receive certificates and would like to convert them, the openssl tooling is your best call too:

openssl x509 -inform der -in YOURPUBLIC.cer -out YOURPUBLIC.pem

set up nginx to use those certificates

With the private key and the certificate in hand, it is time to setup the webserver to use them for SSL. In this case, nginx is the server of choice. In the file /etc/nginx/sites-enabled/default, edit the server section to use the generated certificates:

    listen 443 ssl default_server;

    ssl on;
    ssl_certificate /home/niko/timebot/ssl/YOURPUBLIC.pem;
    ssl_certificate_key /home/niko/timebot/ssl/YOURPRIVATE.key;


    location / {
        index  index.nginx-debian.html;

Note that in this example, the standard listen on port 80 is deleted.

When accessing the root url at, you will get a certificate warning, to complain the certificate is not setup properly:


After accepting your own certificate, you can see your choice of home page showing up:


proxy_pass setup

In the context of a standard app running on a plain http port, you can use nginx to proxy the request for you.

The configuration below is a slightly updated version with the proxy_pass settings:

server {
    listen 443 ssl default_server;

    ssl on;
    ssl_certificate /home/niko/timebot/ssl/YOURPUBLIC.pem;
    ssl_certificate_key /home/niko/timebot/ssl/YOURPRIVATE.key;


    location / {
        proxy_pass  http://localhost:9090/;

        # this is the default
        proxy_pass_request_body on;
        proxy_redirect     off;
        proxy_set_header   Host             $host;
        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;


Not related directly to SSL setup, but nginx logging can be tuned to offer more information about why the SSL handshake fails, or why the response downstream is not coming back appropriately.

In nginx.conf, you can add the log level right after the log file as showm below:

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log debug;