How to integrate your own SSL certificate in Nginx or Apache

Last updated: May 11th 2020

Introduction

SSL which stands for Secure Socket Layer is the protocol that keeps your website secure. It is also known as a digital certificate or identity certificate that digitally bind a cryptographic key to an organization’s details. It enables the padlock icon next to your website address in your browser and underlies the https protocol which allows secure connections between the web server and a browser. Typically, SSL is used to secure logins, data transfer and credit card transactions. Having an SSL enabled website is a must for every website nowadays and is part of mantaining a good SEO ranking as well as privacy for your visitors.

There are two types of SSL certificates, Commercial and Free SSL Certificates. It’s important to understand the difference between these and when you might want to use either.

Commercial (Paid) SSL Certificates

A commercial certificate is issued and signed by a trustworthy certificate authority (CA). You can get it directly from the Certificate Authority’s website or buy it from 3rd party resellers such as Verisign, Comodo or any of the many CAs out there. You would typically only need a paid SSL certificate if you need some special features which a free certificate cannot provide, or if you for some reason do not trust the CA you are getting a free certificate from. In the case of Let's Encrypt which we use extensively here at Webdock, we do not see any reason for concern at this time.

Free SSL Certificates

Free SSL Certificates are awesome, primarily because they are free and are just as secure as paid certificates. Here at Webdock we use Let's Encrypt certificates in order to provide free SSL to all our clients. Let's Encrypt is a free and open certificate authority brought to you by the nonprofit Internet Security Research Group. It aims to help people by providing them with online safety easily with free SSL Certificates. Compared to commercial SSL, 

In terms of the actual encryption method, a free SSL certificate provides the same level of encryption as a paid one. However, there are several reasons why you need to buy a paid certificate and not use Let's Encrypt:

  • Validity : Let’s Encrypt SSL certificates are valid only for 90 days, while a paid SSL certificate has a minimum validation of 2 years. As Let’s Encrypt certificates are only valid for 90 days and are based on an automation system which allows for automatic renewal. If you missed out on a renewal however and did not see their notification email, this can put your website in danger of showing a nasty error message to your end-users
     
  • Validation : Commercial CA provides three types of SSL Certificates validation, domain validation (DV), organization validation (OV) and extended validation (EV). Since Let’s encrypt is based on an automation system, it can only provide Domain Validation SSL certificates.
     
  • Warranty : Commercial SSL Certificates provides a warranty in form of insurance against the certificate failure event. While Let’s Encrypt Certificates do not offer any warranty.
     
  • Level of Trust : Commercial SSL Certificates provides a trust seal that will increase visitor confidence and customer conversions (potentially). While Let’s Encrypt Certificates do not provide any type of site seal.

In the following tutorial, we will learn how to integrate your own SSL certificate which you have bought or generated yourself in Nginx or Apache on a Webdock stack.

Please note: Doing these actions will temporarily bring down your server. Do not do this on a live site unless you know what you are doing. We suggest you create a new server from a snapshot and test this out then migrate your changes back to your live server once you've verified everything is working.

Prerequisites

  • A fresh Webdock cloud Ubuntu instance with LEMP/LAMP installed.
  • A valid domain name is pointed to your VPS server IP.
  • You have shell (SSH) access to your VPS.

Generate Your Own Self-signed SSL Certificate

SSL "Secure Sockets Layer" plays an essentiall role when it comes to securing your webserver. You can purchase an SSL certificate from a third party CAs (Certificate Authority) as mentioned, but for the purposes of this guide we will show how you can generate and use a self-signed certificate with your own domain name pointing to your server. This will also encrypt communication between your server and client in the same way as a paid certificate, however; 

Just using a self-signed certificate is not good enough for a real website and should be avoided as this will show a security alert in your visitors browser. We are just showing how to generate your own certificate here for the purposes of this guide, as the files you receive from a real CA after you buy a certificate will be the same as the ones shown here.

SSL works by using a public and private keys. The private key is kept on the server and used to encrypt content sent to clients. The public key is shared with all clients to decrypt the content.

First, you will need to create a private key and a certificate signing request (CSR) for a domain name or hostname on your web server. which will specify the relevant information about the requester.

You can create them with the following command:

openssl req -nodes -newkey rsa:2048 -keyout /etc/ssl/private/private.key -out /etc/ssl/private/request.csr

You will be asked to specify the certificate information as shown below:

Generating a RSA private key
..........+++++
..................................................................................................................+++++
writing new private key to '/etc/ssl/private/private.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:California
Locality Name (eg, city) []:Newyork
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Webdock
Organizational Unit Name (eg, section) []:IT
Common Name (e.g. server FQDN or YOUR name) []:site1.example.com
Email Address []:admin@example.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

The above command will generate a request.csr file with all the information you entered. The certificate authority (CA) will use the information contained in the CSR to create your certificate. When you buy a certificate this procedure is usually very well documented by the CA and you can get help from them with creating your certificate request if you get into trouble.

A brief explanation of each CSR option is shown below:

  • Common Name: It represents the server or domain name protected by the SSL certificate. For example, site1.example.com.
  • Organization: It represents the legeal name of your company. For example, webdock.
  • Organization Unit (OU): It represents the division name of the company that managing the certificate. For example, IT
  • City or Locality: It represents the name of the city where you company is located.
  • State or Province: It represents the name of the state or province where you company is located.
  • Country: It represents the name of the country where you company is located.

The CSR which you have created above is in the Base-64 encoded PEM format. You can see the content of the CSR with the following command:

cat /etc/ssl/private/request.csr

You should see the "-----BEGIN CERTIFICATE REQUEST-----" and "-----END CERTIFICATE REQUEST-----" lines as the header and footer tags in the following output:

-----BEGIN CERTIFICATE REQUEST-----
MIIDBDCCAewCAQAwgZExCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlh
MRAwDgYDVQQHDAdOZXd5b3JrMRAwDgYDVQQKDAdXZWJkb2NrMQswCQYDVQQLDAJJ
VDEaMBgGA1UEAwwRc2l0ZTEuZXhhbXBsZS5jb20xIDAeBgkqhkiG9w0BCQEWEWFk
bWluQGV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
042T1Yg7zrMVbGTv7btElD+AG7fgPh/Ut4hkmljDDb/I7LdTcglBK4FviAVdky9O
zk1QEEO2QqXNwiiX5p41bamxA8rkumiWkVI8HA6gQamYPzUqm9eBMVoPs98YeOOe
wqkGDmtULirNObz24AW1JSIXBjsXu5FRT4RkSK2OTPoh5qTJZe5sEVR+v0sy+wJk
qy8NEyhdEwdt0r/hRk+RXXDbtn5xJWy+PVXLJvBoHk0myiY8jJ/nAl//Vuxl39cf
NAwQ0wZjjQEbhNVzWoCsP243AwsJ6n/qz98+N7+APwkEkiX2w9Rp2Fw83UHcr40r
tvQ8GbvSEubbrboO0O4a5wIDAQABoC0wEwYJKoZIhvcNAQkHMQYMBGFzZGYwFgYJ
KoZIhvcNAQkCMQkMB1dlYmRvY2swDQYJKoZIhvcNAQELBQADggEBADmxALY19C86
M5vfP+B31NZnrAgCnzvY+pya6zDTn0NDq9KE3NLpC2Pum6eDIfap6+/qxIR+0A7v
kVD6cqX2u/AMrkQUCxJDah0AwB1dOTOCD7vFlDWvPNtv8BOJB6LYwNg3I6CAx4V2
U1DJ9RV+NrcWSNaXYqrAbAvxVQKhB5/1PkwwdLHp83ypcCKdtRi5lniOjy5rF8a+
9GOmGSIid+jlsPQLg6HW5dWM4ngMhiQ3ThgupPkPh7NjNntM6akrM/fQiTzGMx6E
DY4t/T6l5LEE4rRQZSdmpM5+zodaL+7jxc3b8zZzgM+1UIdYuBFf0neym5OW5MgO
0l0bTA+FP1k=
-----END CERTIFICATE REQUEST-----

At this point, your request.csr is ready for the certificate generation. You can generate the SSL certificate with the following command:

openssl x509 -in /etc/ssl/private/request.csr -out /etc/ssl/private/certificate.crt -req -signkey /etc/ssl/private/private.key -days 365

Once the SSL certificate has been generated successfully, you should get the following output:

Signature ok
subject=C = US, ST = California, L = Newyork, O = Webdock, OU = IT, CN = site1.example.com, emailAddress = admin@example.com
Getting Private key

At this point, the certificate.crt file is ready to be used with Nginx or Apache webserver.

Please note: After generating the CSR, you can theoretically use this CSR to order a commercial SSL certificate from a third party Certificate Authority (CA) website. Upon making an order, your order will enter the validation process with the issuing Certificate Authority (CA). Once the validation process has been completed, you will receive the trusted SSL Certificate from the issuing Certificate Authority (CA). You can use this certificate to secure your website. However, you should always defer to their specific guides on how to generate your request.

Configure Nginx/Apache Webserver to use your SSL Certificate

The self-signed certificate is worthless for production websites but the certificate files you get from this procedure are the same as the ones you get from an SSL certificate provider when you buy a certificate.

In this section, we will explain how to link your new SSL certificate with Nginx/Apache webserver.

Configure Nginx to use your SSL Certificate

To link your new SSL certificate with Nginx, we will copy the default webdock config and create a new one for your domain which links in your certificate. This has the effect that our standard SSL certificate will still work for your default Webdock alias - e.g. myserver.vps.webock.io - so that you can access e.g. phpmyadmin securely. If you do not need this, you can edit the Webdock server configuration directly instead. Start with making a copy of the Webdock config:

cp /etc/nginx/sites-enabled/webdock /etc/nginx/sites-enabled/yourdomain-ssl

Add/Modify only highlighted lines so they match your domain name and paths:

server {
        root /var/www/html;
        client_max_body_size 256M;
        index index.html index.htm index.php;
        server_name site1.example.com;

        location / {
            try_files $uri $uri/ /index.php?$query_string;
        }

        location = /favicon.ico { access_log off; log_not_found off; }
        location = /robots.txt  { access_log off; log_not_found off; }
        access_log /var/www/logs/example_access.log;
        error_log  /var/www/logs/example_error.log error;
        error_page 404 /index.php;

        location ~ \.php$ {
          fastcgi_split_path_info ^(.+\.php)(/.+)$;
          fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
          fastcgi_index index.php;
          include fastcgi_params;
          fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
          fastcgi_intercept_errors off;
          fastcgi_buffer_size 16k;
          fastcgi_buffers 4 16k;
          fastcgi_connect_timeout 600;
          fastcgi_send_timeout 600;
          fastcgi_read_timeout 600;
        }

    listen [::]:443 ssl ipv6only=on;
    listen 443 ssl;
    ssl_certificate /etc/ssl/private/certificate.crt;
    ssl_certificate_key /etc/ssl/private/private.key;
    include /etc/letsencrypt/options-ssl-nginx.conf;
}
server {
    if ($host = site1.example.com) {
        return 301 https://$host$request_uri;
    }

        listen 80;
        listen [::]:80;
        server_name site1.example.com;
        return 404;
}

Here we are maintaining the standard SSL configuration options for Nginx which Let's Encrypt creates (/etc/letsencrypt/options-ssl-nginx.conf) but you are free to make a copy of that file and create your own configration - this may be required by your SSL provider as well, so it is good to inspect the Let's Encrypt configuration and potentially take a look at our other guide: Increasing SSL Security

Save and close the file when you are finished. Then, restart the Nginx service to apply the changes:

systemctl restart nginx

At this point, your website site1.example.com should now be secured with SSL certificate. You can access it by visiting the URL https://site1.example.com.

If you have problems with this procedure contact first your SSL provider and if all fails be in touch with Webdock support and we will help you out.

Configure Apache to use your SSL Certificate

To link your new SSL certificate with Apache, we will copy the default Let's Encrypt config and use as our template and edit this file on order to link in your certificate for your domain. This has the effect that our standard SSL certificate will still work for your default Webdock alias - e.g. myserver.vps.webock.io - so that you can access e.g. phpmyadmin securely. If you do not need this, you can remove the Let's Encrypt config file.

Start with making a copy of the Let's Encrypt config:

cp /etc/apache2/sites-enabled/webdock-le-ssl.conf /etc/apache2/sites-enabled/yourdomain-ssl.conf

Add/Modify only highlighted lines so they match your domain name and paths:

<IfModule mod_ssl.c>
<VirtualHost *:443>
        ServerName site1.example.com

        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html

        # Deny access to any git repository
        RedirectMatch 404 /\.git

    <FilesMatch \.php$>
        # 2.4.10+ can proxy to unix socket
         SetHandler "proxy:unix:/run/php/php7.4-fpm.sock|fcgi://localhost"
    </FilesMatch>

    <Directory /var/www/>
        Options FollowSymLinks Includes ExecCGI
        AllowOverride All
        Require all granted
    </Directory>

        # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
        # error, crit, alert, emerg.
        # It is also possible to configure the loglevel for particular
        # modules, e.g.
        #LogLevel alert rewrite:trace3 alias:debug

        CustomLog /var/www/logs/access.log combined
        ErrorLog /var/www/logs/error.log


        SSLEngine on
        SSLCertificateFile /etc/ssl/private/certificate.crt
        SSLCertificateKeyFile /etc/ssl/private/private.key
        Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>

<VirtualHost *:80>
RewriteEngine on
RewriteCond %{SERVER_NAME} =site1.example.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

Please note we have added the last VirtualHost section which makes sure any non-ssl requests are redirected to https and then is handled by the block above serving your certificate files.

Here we are maintaingin the standard SSL configuration options for Apache which Let's Encrypt creates (/etc/letsencrypt/options-ssl-apache.conf)  but you are free to make a copy of that file and create your own configration - this may be required by your SSL provider as well, so it is good to inspect the Let's Encrypt configuration and potentially take a look at our other guide: Increasing SSL Security

Save and close the file when you are finished then restart the Apache service to implement the changes:

systemctl restart apache2

At this point, your website site1.example.com is now secured with your SSL certificate. You can access it by visiting the URL https://site1.example.com.

If you have problems with this procedure contact first your SSL provider and if all fails be in touch with Webdock support and we will help you out.

Conclusion

In the above guide, we learned the difference between free and paid SSL certificate. We also learned how to generate self-signed SSL certificate and integrate it with Nginx and Apache webserver. We hope you can now get through the slightly complicated process of buying an SSL certificate and integrate it with your website.