Previously, I looked at setting up Debian 8 with PHP 7.0. But now, Debian 9 is the current stable version and Debian 8 is only due to receive security updates until May 2018. Sounds like a good time to upgrade!

The reason I started to look into upgrading was that I found out that the highest version of Apache available on Debian 8 is Apache 2.4.10 which is not capable of running HTTP/2. Having recently upgraded a lot of my websites to HTTPS, I also wanted to upgrade them to HTTP/2 aswell. Debian 8’s version of Apache was not able to be upgraded without doing so manually. However, Debian 9’s default version of Apache is 2.4.25 which is HTTP/2 capable, it also has PHP 7.0 as the default and has upgraded MySQL to MariaDB. All the more reason to upgrade!

From here

For those who don’t know, Debian codenames are based on the characters in the famous animated movie Toy Story. This release is named after the glittery purple rubber toy octopus, Stretch.

Alternatives to upgrading to Debian 9 (Stretch)

Upgrading from Debian Jessie to Stretch will not be for everyone. Here are some possible alternatives.

Manually installing a higher version of Apache.

This is generally thought of as possible but not recommended. You also have the gradual winding down of Debian support from May 2018 which may lead to security risks.

Changing to another flavor of Linux with a version of Apache that is capable of running HTTP/2.

Ubuntu 16.04 is one version that can run HTTP/2 without too much tinkering.

Ubuntu is similar to Debian in terms of the shell commands. I have some websites that use Ubuntu 16.04 but for this particular website, I wanted to stay with Debian. Ubuntu is thought of as more experimental, while Debian is thought of as more stable and faster.

Ubuntu 16.04 LTS looks like it will be supported until April 2021 from here so it will not need updating any time soon. The next version with long-term support (LTS) is released next month (April 2018) so I may look into upgrading the servers running Ubuntu when that arrives.

I have used AWS in the past and I have built websites on FreeBSD and CentOS servers that I can remember, but currently I am mainly using Debian and Ubuntu with un-managed VPS. This experience has made me want to try some different flavors, or at least learn about how the other flavors are different. What I’ve read so far makes me think that Debian is a decent choice for this site. Here’s a comparison between Debian, Ubuntu and CentOS for webservers.

Changing from Apache to Nginx.

While you’re still left with the Debian support for Jessie winding down, changing to Nginx is probably a good move. Debian 9 with Nginx may well be faster than it would be with Apache. The version of Nginx you install on Debian 8 with Jessie Backports can run HTTP/2.

The problem with changing to Nginx on a live website is that it is completely different as a webserver to Apache. Nginx does not have .htaccess files and the setup will be different in ways that I’m not aware of yet. I wanted to upgrade in less than a day on this live website so this option was not right for me at the time. But, I do plan to use Nginx in the near future.

Upgrading from Debian 8 (Jessie) to Debian 9 (Stretch)

The official Debian guide to doing this manually in the command line is here. I decided against doing it this way, although it may have lead to less downtime. I decided a fresh install may cause less problems in the future.

I decided to just re-install in the hosting company portal. This meant backing everything up, then with the installation, everything was erased and had to be re-added. There is only one website on the VPS which is a WordPress blog. There was nothing particularly complicated about the server setup which made life a lot easier. The main thing I had to do were to get MariaDB installed and to import the backed up SQL file from the MySQL, I referred to this guide for that. I also had to get Lets Encrypt installed and set up the SSL encryption again.

One of the things I had to change from when I set up Debian 8 with PHP 7.0 was the way PHP 7.0 is installed/served. mpm_prefork is not compatible with HTTP/2 (mod_http2) so I had to use another way of installing PHP (from here).

I was rushing the installation through as quickly as I could because the website was down. I probably did some things in the wrong order and I did encounter some problems. However, after about 45 minutes I had to leave the house and do some chores. At that stage, the WordPress blog was basically up and running but mod_rewrite was not configured correctly yet and the SSL was not set up yet either.

When I got back I started to finish off getting the site working but almost as soon as I sat down the server locked me out of SFTP and SSH. I could not even access the shell on the control panel’s console. I actually thought I’d locked myself out with the UFW firewall. I’m not sure what the problem was but it turned out to just be temporary and I hadn’t locked myself out at all.

Everything went pretty smoothly really. I got the occasional error when trying to reboot but nothing major. Every time it was pretty obvious what the problem was without doing much, if any, investigating. The dreaded error message when Apache won’t restart is definitely becoming less scary these days since I started ignoring the files it tells you to look at and just go straight for the main error.log or whatever you have set up as the main error log file.

Learning New Stuff

I was expecting more problems from exporting the MySQL then importing it into MariaDB. Even if the import/export went smoothly I was expecting to have some issues with WordPress itself. All I can say is no problems whatsoever with the database or WordPress at all. Maybe it’s because I’ve done this kind of thing a few times before and this time I was actually ready and prepared for it.

Because the website is just a WordPress blog I am not going to be doing a huge amount of work with MariaDB on that website. But, one of the things I did take a look at was the MariaDB tuning: mysqltuner. I can’t wait to do some more work with MariaDB in future.

I did all the database backup, set up and importing in the shell. I didn’t use PHPmyAdmin at all but decided to install it at the end incase I ever needed to use it. Then, setting up PHPmyAdmin needed some more shell work with the MySQL command line and MariaDB. Because of all this, I feel like I’m a lot more confident with the MySQL command line.

The Unattended Upgrades file that came with my installation seems to be the same one used with Jessie. Referred to articles such as Unattended Upgrades in Debian 9 for what to keep and what to remove.

Unattended Upgrades will need to send emails to tell you when it needs a reboot unless you have it automatically reboot or just do not want emails. I had the Jessie server set up to send emails directly from the server. This time I decided to send the server emails with Mailgun using this guide.

With trying to get the website up-and-running normally as soon as possible I feel like I got to know Nano a lot better. I even edited the nano config file, /etc/nanorc, to tweak some of the things I have disliked about using Nano.

Issues Encountered

The Sudoers file.

After setting up a user and adding it to the group, sudo, I was getting errors every time I wanted to use a sudo command. I may have done this before but the sudoers file is located at /etc/sudoers

Something like…

root ALL=(ALL:ALL) ALL

Problem installing Python and Let’s Encrypt… dependencies.

Once I’d fixed the Sudoers file I think there may have been another obstacle to installing Python and the Lets Encrypt dependencies but I have completely forgotten what it was.

PHPmyAdmin could not create the phpmyadmin table or the ‘pma’ user.

I did not use PHPmyAdmin at all but installing it at the end caused a few problems that were easily fixed.

Outcome

All-in-all I’m very happy I got the upgrade done. And, I’m pleased I was able to do it fairly quickly despite having to leave the house against my will during the process then getting locked out. I’m looking forward to playing with and configuring Debian 9 Stretch on this VPS. And I think I chose the right way to do the upgrade. Upgrading from Debian 8 Jessie to Debian 9 Stretch on a live website through the shell can be risky and I didn’t want to get to a situation where nothing worked and I didn’t know how to fix it. The cherry on the cake is that I now have HTTP/2 working which was the main thing I wanted to add at the start, plus I have some other upgrades. Debian 9 should be ok for at least a year before I need to start thinking about upgrading again – Debian Version History.

Future

Now, having researched HTTP/2, Debian and Apache for this project I am keen to try Nginx very soon. Nginx is a similar speed as Apache for some things but is much faster in others so I am looking forward to seeing what a life without .htaccess files looks like.

The internet is gradually becoming more and more encrypted and secure. While this is most important for websites where you might enter sensitive data, like credit card info, it is generally a good thing to have for any website. Browsers now warn surfers if a website is not encrypted. As I write this unsecure, unencrypted websites just have an exclamation mark inside a circle in the location bar, but the trend is towards this warning getting more and more visible on the surfers browser.

As well as having quality content for surfers, you can also try to not turn surfers off your content by having an unencrypted website. Maybe secure websites will rank higher than unsecured ones.

Contents

Setting up a SSL Certificate to make a Secure Website

When trying to set up a free SSL certificate from Let’s Encrypt the information I found to begin with was quite confusing. Then, once I got my head around what I was doing, the sites I tried to add it to were not able to use Let’s Encrypt certificates for different reasons.

Once I finally got a VPS that could handle Let’s Encrypt certificates I followed this guide… Install Let’s Encrypt to Create SSL Certificates.

I would say that starting off it is important to pay attention to detail. Make sure everything is updated to begin with, and you have all the server requirements. Also, whereas you may not have specified the IP address in your virtual host config file before, you will need to specify the IP there for this to work.

Luckily, for a Linux administration beginner there are plenty of error logs and hints to find out what if anything has gone wrong. Not all the online guides state all the pitfalls. That’s why I am putting this information together in one place on how to make your website secure with SSL encryption…

Installing Let’s Encrypt

To begin with, make sure port 443 is open in the firewall (see troubleshooting). In these lines of code make sure to change “example.com” to your website domain.

Start off by getting and installing the Let’s Encrypt software, then use it to get the certificates. The order of the two domains in the final command are fairly important because the virtual directory containing the certificates will be named after the first domain, so you might want to use the one without www for simplicity…

sudo apt-get install git
sudo git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt

Installing Let’s Encrypt SSL Certificates

Go to the directory you have cloned to when installing Let’s Encrypt…

cd /opt/letsencrypt
sudo -H ./letsencrypt-auto certonly --apache -d example.com -d www.example.com

If there are any errors after the final command, it should tell you what the error is related to, but if it does not or it is unclear there are some ideas in the troubleshooting section.

Check the certificates by typing the following commands, below. The directory should be your domain instead of “example.com“, if it does not exist or is misspelt then you’ll have to get the certificates again as it will not work. When you get the certificates you should specify both www and non-www. Let’s Encrypt does not work for wildcards so every subdomain has to be specified. If it is a subdomain with a different config file then it will need a separate set of certificates…

sudo ls /etc/letsencrypt/live/example.com
sudo stat /etc/letsencrypt/live/example.com/fullchain.pem

Modify the VirtualHost file to look for SSL Certificates

Then, once you have the certificates. Modify the config file for the website, e.g. “/etc/apache2/sites-available/example.com.conf“. You can Keep the same file just change the port from 80 to 443 and the VirtualHost tags should contain the following. The file path to the certificates should be the actual paths to your certificates. And, I believe for this to work you must have the IP address in the VirtualHost tag, a wildcard will not work…

<VirtualHost 123.123.123.123:443>
SSLEngine On
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
</VirtualHost>

Then, make sure SSL is enabled and restart apache…

a2enmod ssl
service apache2 restart

By this stage when you go to https://www.example.com your website should work! If that’s the case you can make sure that everyone gets the secure version of your site, below.

Redirecting to Force HTTPS Encryption

Once the SSL certificates are working properly you’ll want to make sure everyone gets the secure version of your website. There are a few different methods to do this but perhaps the simplest for people who are new to Linux is using .htaccess. How to force HTTPS using the .htaccess file

RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.example.com/$1 [R,L]

This will still allow https://example.com/ to work so you may choose to add another line for that.

Or, have two VirtualHost tags for ports 80 and 443 in the “/etc/apache2/sites-available/example.com.conf” file and redirect port 80 as suggested here

<VirtualHost 123.123.123.123:80>
ServerName www.example.com
ServerAlias example.com
Redirect permanent / https://www.example.com/
</VirtualHost>

Now, you’ll all done!

Checking the Expiration Date of Let’s Encrypt Certificates

Let’s Encrypt certificates last for 90 days, you do not want them to expire unless you want to stop encrypting the website. To check when your current certificates are du to expire type this into the terminal…

openssl x509 -noout -dates -in /etc/letsencrypt/live/example.com/cert.pem

Which will give you the date they were created and the date they are valid until…

notBefore=May 7 14:33:00 2017 GMT
notAfter=Aug 5 14:33:00 2017 GMT

From here there is also “ssl-cert-check” for Debian-like versions of Linux. It needs installing first if it is not already installed, so…

apt-get install ssl-cert-check

Then, run it by typing this simple code (needs superuser privileges so use “sudo”)…

ssl-cert-check -c /etc/letsencrypt/live/example.com/cert.pem

Which gives something like this…

Host                                             Status   Expires     Days
---------------------------------------------------------------------------
FILE:/etc/letsencrypt/live/example.com/cert.pem   Valid   Aug 5 2017   90

Renewing Let’s Encrypt SSL Certificates

To renew the Let’s Encrypt certificates, navigate to the Let’s Encrypt directory… cd /opt/letsencrypt.

Then, this is one way to renew the certificates…

sudo service apache2 stop
sudo -H ./letsencrypt-auto certonly --standalone --renew-by-default -d example.com -d www.example.com
sudo service apache2 restart

The “standalone” flag means that you would have to stop apache because Let’s Encrypt needs to be the only application using port 443.

However, by using --apache or --webroot you can do the same thing while apache is running, from here. This may reload or restart apache but apache would not be stopped for nearly as long as it would be if apache was manually stopped and then restarted again at the end…

sudo -H ./letsencrypt-auto certonly --apache --renew-by-default -d example.com -d www.example.com

To automatically renew the Let’s Encrypt certificates one a month, enter this command to make a monthly task in your crontab…

echo '@monthly root /opt/letsencrypt/letsencrypt-auto certonly --quiet --apache --renew-by-default -d example.com -d www.example.com >> /var/log/letsencrypt/letsencrypt-auto-update.log' | sudo tee --append /etc/crontab

To automatically renew the Let’s Encrypt software, enter this command…

echo '@monthly root cd /opt/letsencrypt && git pull >> /var/log/letsencrypt/letsencrypt-auto-update.log' | sudo tee --append /etc/crontab

Alternative Method for Debian 8 (Certbot)

Another way is to install the Let’s Encrypt certificates is to install Certbot on Debian 8 using Backports… How to Set Up Let’s Encrypt Certificates for Multiple Apache Virtual Hosts on Ubuntu 14.04.

sudo nano /etc/apt/sources.list

Then, enter this line if it is not already there…

deb http://ftp.debian.org/debian jessie-backports main

Save and exit nano, then…

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install python-certbot-apache -t jessie-backports

Troubleshooting and Checking

Check which sockets are open using ss (socket statistics)…

ss -tlnp

More information on ss here.

Check apache version and check which modules are installed

apache2 -v
apache2ctl -M

or

dpkg-query -l

For your second secure website on the same webserver you will have already enabled the SSL module and port 443 will already be serving your first website to the world. When you try to install the certificate for the second website there may be problems if you are using the --standalone flag, because Let’s Encrypt wants to use the same port as is already serving the website. To continue using --standalone you can stop Apache for a few seconds while you install the certificates.

service apache2 stop

Then, once the Let’s Encrypt certificates are done, you can restart Apache again…

service apache2 restart

To avoid having to stop and start apache like this on a production website you can use the --apache flag instead.

If you are using UFW as a firewall, the following command will show you whether socket 443 is allowed…

sudo ufw status

Also, Apache problems when trying to set up SSL (Debian).

Further Checks to make your Website Secure (Green Padlock)

If your website is working with HTTPS in the location bar (“https://www.example.com/”) but you do not have a green “SECURE” you have an “i” with a circle around it, check to see what it says by clicking on it. If it says you are not fully secure it probably means that the files and/or images you are linking to are not using the SSL encrytion. To fix this simply either fix your absolute image/file locations by changing them from HTTP to HTTPS, or just use relative linking.

Another thing that may cause errors is your .htaccess file, if you have one. Make sure that the error documents are all updated from http:// to https:// for the site in qustion.

Adding more Secure websites to the same Webserver

When “Let’s Encrypt” is already installed you do not have to re-install it, you can simply create the new certificates for the next website you want to make secure. When you are trying to create the certificates there may be an error saying that port 443 is already in use. In this case, you may have to stop apache briefly while you make the certificates, then restart apache as soon as they’re made.