In my last article on Raspberry Pi, we put together a simple WordPress instance running on a Pi using only a few keystrokes. Now that we have a Pi serving up your beautiful site, I’d like to show you the easiest way to add security, and keep away, those pesky comments from Nerds, telling you how wrong it is to put
up a site that’s insecure.
On just about any web site you go to, you will find this in the upper-left corner of the page:
The lock indicates a properly secured page. It says that you typed in the site joe.com and the
server changed your request from http to https:, then responded as if had typed https. THe clean lock says the site certificate is up to date and secure.
If you get this:
It means you typed into your browser, foo.com and the server doesn’t have a way to secure that site. Everything is cleartext over the wire, and if you decide to give foo your credit card number, anyone with the proper software can intercept it and read any data.
This means you typed https, and the server does have some sort of certificate, but it’s just a placeholder until they get a proper cert for that site. Every domain must have a proper cert for itself in order for our web browsers to be happy.
With that understanding, let’s get this going properly for your WordPress website. If you used my script to install your WordPress instance, then all the software and encryption modules are already installed, so we won’t need to address that. Also anywhere you see “foo.com” in this writeup, replace it with your own. I use foo.com as the example.
Here are the prerequsites:
- Own your own domain. I have mine through dynu.com and my .com costs me $14 per year.
- Too much how-to to go into detail here, but you MUST have outside access to your site. For example, if you own foo.com, and someone anywhere in the world types foo.com in their browser, they need to see your WordPress un-secured web page, (or at least a index.html page that works). But not a 404 not found error. This involves getting into your router and forwarding port 80 (web traffic) to your Pi IP address. While you’re at it, also forward 443 for secure traffic. Http on port 80 needs to work before proceeding. Even if they get a blank page, as long as it’s on your Pi and there are no errors, that will work.
- Access to a shell prompt on your Pi, and your favorite way to edit text files. Could be SSH which was set up and working if you used my script, or with a keyboard and monitor connected.
Before we do anything, go into the admin of your WordPress site, and tell WordPress to expect its traffic to be foo.com, not 192.168.1.x.
Click Settings.
Change these to http://foo.com
We do this first because if we make the changes below first, your site will not be accessible.
After this change is made, your site won’t be accessible for right now until we finish the other configs below.
It’s a good idea you make a backup of your working Pi with WordPress first, just in case.
In a shell prompt, Type the following:
certbot certonly -d foo.com
Certbot servers will test foo.com to make sure it’s going to the same box where the request came from. It will then assign the certificates and place them in a folder on your Pi at /etc/letsencrypt/live/foo.com.
Next we’re going to do some surgery in the Apache configs.
Open /etc/apache2/sites-available and create a file called foo.com.conf
In that file, put in all below:
<VirtualHost *:80>
ServerName foo.com
ServerAlias www.foo.com
DocumentRoot /var/www/html
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
RewriteEngine On
RewriteCond %{SERVER_NAME} =foo.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName foo.com
ServerAlias www.foo.com
DocumentRoot /var/www/html
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
SSLEngine on
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/foo.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/foo.com/privkey.pem
</VirtualHost>
Now at the command prompt:
a2ensite foo.com
service apache2 restart
Now we need to tell WordPress to expect SSL content and process it accordingly.
EDIT: If you installed WordPress using my WP script after 9/4/22, the following has already been done.
You may want to check it just in case, but wp-config.php should already be modified.
Open the following file in a text editor: /var/www/html/wp-config.php
Find the following text:
/* Add any custom values between this line and the "stop editing" line. */
/* That's all, stop editing! Happy publishing. */
Put this code between those lines:
if (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {$_SERVER['HTTPS'] = 'on';}
It should look like this (added code in blue):
Now reboot your Pi so that the new php configuration takes place.
At the command prompt, type
reboot
That’s about it folks. You should be able to type https://foo.com in a browser and see the security lock. Let me know how it goes in the comments.