How To Create Self-Signed SSL Certificate for Apache in Debian 9


create self-signed certificate for apache in debian

Transport Layer Security (TLS) and Secure Sockets Layer (SSL) are web protocols that encrypt all data transferred between users’ web browser and your web server. This protects your data from being tracked by third-party and also allows users to verify your site’s identity. Here’s how you can create a self-signed SSL certificate for Apache in Debian 9.

Before we begin, make sure you have installed Apache server on your system. It is fine if you haven’t installed other aspects of your stack like MySQL/PHP. Only Apache server is enough for now.

 

How To Create Self-Signed SSL Certificate for Apache in Debian 9

Here’s how to create a self-signed SSL certificate for Apache in Debian 9

 

1. Create SSL Certificate

TLS/SSL work with the help of a private key and public certificate. The private key (also called SSL key) should be kept secret at your server. It is used to encrypt the data sent to the client (browser).

When the client receives data from your server, it uses the publicly available SSL certificate to decrypt the data signed with the associated SSL key.

We use OpenSSL to create a SSL certificate and self-signed key pair. OpenSSL is installed, by default, on most Linux systems.


$ sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/apache-selfsigned.key -out /etc/ssl/certs/apache-selfsigned.crt

Let us look at the above command

  • openssl – command to create SSL keys, certificates and other files.
  • req – tells OpenSSL that we need to use the X.509 certificate signing request. It is the public key standard that TLS and SSL follow.
  • -x509 – indicates that we need a self-signed certificate and not a certificate signing request, as available by default.
  • -nodes – skip using a passphrase to secure the certificates. Apache should be able to use the certificate automatically, without manual input. Passphrase requires manual intervention every time you start/restart the server.
  • -days 365 – number of days your certificate is valid. We set it to 1 year.
  • -newkey rsa:2048 – specifies to create certificate and key at the same time. rsa:2018 tells OpenSSL to create a 2048-bit long RSA key.
  • -keyout – location of the created private key file
  • -out – location of the created certificate

Once you enter this command, you’ll be required to enter a series of information about your business/website. OpenSSL uses this information to create a key-certificate pair for you.

Here’s an example:


Output
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:New York
Locality Name (eg, city) []:New York City
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Ubiq Business Intelligence
Organizational Unit Name (eg, section) []:IT Company
Common Name (e.g. server FQDN or YOUR name) []:server_IP_address or your domain name
Email Address []:admin@your_domain.com

Both the private key and public certificate will be created and placed at /etc/ssl

 

2. Configure Apache to Use SSL

Not that you have created both these files, we need to modify Apache configuration to use them.

We will make 3 changes:

  • Update configuration to use strong default SSL settings
  • Modify SSL Apache Virtual Hosts File to mention the location of generated SSL files.
  • Modify Virtual Hosts file to automatically redirect HTTP requests to HTTPS

 

Update configuration to use strong default SSL settings

Create a new file called ssl-params.conf in /etc/apache2/conf-available


$ sudo nano /etc/apache2/conf-available/ssl-params.conf

 

We will use the template for SSL settings by Remy Van Elst. We will only disable Strict-Transport-Security (HSTS) Header. Although HSTS provides more security, it can have unintended consequences if not set up correctly.

You can copy paste the following in ssl-params.conf


SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
SSLProtocol All -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLHonorCipherOrder On
# Disable preloading HSTS for now. You can use the commented out header line that includes
# the "preload" directive if you understand the implications.
# Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
Header always set X-Frame-Options DENY
Header always set X-Content-Type-Options nosniff
# Requires Apache >= 2.4
SSLCompression off
SSLUseStapling on
SSLStaplingCache "shmcb:logs/stapling-cache(150000)"
# Requires Apache >= 2.4.11
SSLSessionTickets Off

 

Save and close the file when you are finished.

 

Modify SSL Apache Virtual Hosts File to point to our generated SSL files

Open the default Apache SSL Virtual Hosts file /etc/apache2/sites-available/default-ssl.conf

First, we create a back up of the file


$ sudo cp /etc/apache2/sites-available/default-ssl.conf /etc/apache2/sites-available/default-ssl.conf.bak

 

Open the file


$ sudo nano /etc/apache2/sites-available/default-ssl.conf

 

It should look like


<IfModule mod_ssl.c>
 <VirtualHost _default_:443>
  ServerAdmin webmaster@localhost

  DocumentRoot /var/www/html

  ErrorLog ${APACHE_LOG_DIR}/error.log
  CustomLog ${APACHE_LOG_DIR}/access.log combined

  SSLEngine on

  SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
  SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key

  <FilesMatch "\.(cgi|shtml|phtml|php)$">
  SSLOptions +StdEnvVars
  </FilesMatch>
  <Directory /usr/lib/cgi-bin>
  SSLOptions +StdEnvVars
  </Directory>

 </VirtualHost>
</IfModule>

 

We will basically change the Server Admin, Server Name and the locations of SSL certificates. You can replace the parts in bold below.


<IfModule mod_ssl.c>
<VirtualHost _default_:443>
ServerAdmin your_email@example.com
ServerName server_domain_or_IP

DocumentRoot /var/www/html

ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined

SSLEngine on

SSLCertificateFile /etc/ssl/certs/apache-selfsigned.crt
SSLCertificateKeyFile /etc/ssl/private/apache-selfsigned.key

<FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
<Directory /usr/lib/cgi-bin>
SSLOptions +StdEnvVars
</Directory>

</VirtualHost>
</IfModule>

 

Save and close the file.

 

Modify Virtual Hosts file to automatically redirect HTTP requests to HTTPS

At this point, your server will serve both HTTP as well as HTTPS requests. So we ensure that all HTTP requests to your site are automatically redirected to HTTPS.

Open the server config file


$ sudo nano /etc/apache2/sites-available/000-default.conf

 

Within the VirtualHost block, add a Redirect directive directing all HTTP requests to HTTPS


<VirtualHost *:80>
 . . .

  Redirect "/" "https://your_domain_or_IP/"

 . . .
</VirtualHost>

 

Save and close the file.

 

3. Update the Firewall(Optional)

In case you are using ufw, you might need to update it to allow SSL traffic. Otherwise, you can skip this part if you want.

See the existing firewall rules


$ sudo ufw status

 

If you were allowing only HTTP traffic, it will look like:


Output
Status: active

To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
WWW ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
WWW (v6) ALLOW Anywhere (v6)

 

To allow HTTPS traffic, use the command


$ sudo ufw allow 'WWW Full'
$ sudo ufw delete allow 'WWW'

 

Now your setting will look like:


$ sudo ufw status

Output
Status: active

To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
WWW Full ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
WWW Full (v6) ALLOW Anywhere (v6)

 

Next, we will enable a few Apache modules to allow SSL properly.

 

4. Enable Changes in Apache

Next we need to enable SSL modules (mod_ssl, mod_headers) in Apache, enable your SSL Virtual Hosts and then restart Apache to apply the changes.

You can enable mod_ssl and mod_headers using a2enmod


$ sudo a2enmod ssl
$ sudo a2enmod headers

 

Then enable SSL Virtual Host


$ sudo a2ensite default-ssl

 

Also enable the ssl-params.conf file you had created earlier.


$ sudo a2enconf ssl-params

 

Now all the necessary modules and config files have been enabled. You can test the config


$ sudo apache2ctl configtest

 

If there are no errors, you’ll see the message


Output
Syntax OK

 

Restart Apache to apply the changes


$ sudo systemctl restart apache2

 

5. Testing the SSL setup

If you open your browser and type https://your_domain_or_server_ip then you’ll see the following screen

self signed warning

 

This is because you have created a self-signed certificate, and it is not signed by one of browser’s trusted certificate authorities

Click ADVANCED, and click the link to provided to proceed to your site.

warning override

 

In your browser’s address bar, you’ll see a “Not Secure” flag. It only means that browser cannot validate your certificate. It is still encrypting the data. You won’t find this notice with third-party SSL certificates.

 

In fact, you can even type the HTTP URL http://your_domain_or_server_ip and see if it is redirected to the HTTPS version.

 

6. Create a Permanent Redirect

The redirect that you had created earlier, in step 2 is a temporary one. Now that your complete setup works properly, you can convert it into a permanent redirect (301).

Open your server config file


$ sudo nano /etc/apache2/sites-available/000-default.conf

 

Look for the redirect you had added earlier. Add the keyword permanent in it as shown


<VirtualHost *:80>
 . . .

 Redirect permanent "/" "https://your_domain_or_IP/"

 . . .
</VirtualHost>

 

Save and close the file

 

Check your configuration for syntax errors.


$ sudo apache2ctl configtest

 

If there are no errors reported, then restart Apache


$ sudo systemctl restart apache2

 

Now your redirect is permanent and your site will serve traffic only over HTTPS. You have created a Self-Signed SSL Certificate for Apache in Debian 9.

 

About Sreeram Sreenivasan

Sreeram Sreenivasan is the Founder of Ubiq, a business dashboard & reporting platform for small & medium businesses. Ubiq makes it easy to build business dashboards & reports for your business. Try it for free today!