Introduction: Private Web Serving With the Raspberry Pi

About: I have a degree in Electronics Engineering and various certifications in all kinds of internet programming languages. Professionally, I have over 20 years of experience in various roles including an electronic…

You might be serving-up a lot more then you think you are! Do you know who is accessing your web server?

There are many ways of running a web server in a Linux environment, so to keep this Instructable a relatively reasonable length, I will focus on the common L.A.M.P.(Linux.Apache.MySQL.PHP.) implementation.

I explain searching your web server logs, setting-up typical access lists: blacklists, whitelists, and a combination of the two. I will also share with you my web interface for working with the .htaccess files remotely. Finally, we will look at an open-source firewall.

The following article assumes you have a Raspberry Pi 3 or equivalent, and installed L.A.M.P. Excellent article for getting started and RaspberryPi.org’s installing LAMP.

Image Credits: http://www.usanetwork.com/mrrobot

Step 1: Keep Your Pi Updated!

sudo rpi-update

The command will automatically update the Raspberry Pi’s firmware and then ask for a reboot. If your Pi is already up-to-date, then you can continue with:

sudo apt-get update
sudo apt-get upgrade 

Now, you’ve got the latest and greatest firmware and software!!

Step 2: Pi Passwords

Ideally, we would disable the default pi account, at the very least, set the default password for your pi account. Another major in-security is that most users have SSH (Secure Socket sHell) and VNC (Virtual Networking Computer) enabled so that they can remote into their machines. I don’t recommend allowing access outside of your network when running a publicly exposed web server.

Step 3: ​Getting Online

You have several devices connected to your WiFi router, so how can you tell the outside where you are serving-up Raspberry Pi? Let’s get familiar with our router’s advanced settings in your router manufacturer’s configuration tool. Most home networks use one of these common IP addresses for their gateway to the Internet:

http://192.168.0.1/

http://192.168.1.1/

http://10.0.0.1/

You will need to login to your router’s configuration tool. The username and password should have been assigned at the time of setup. First, we need to reserve an IP address for our Raspberry Pi to use on a regular basis. Typically, the router will have a DHCP (Dynamic Host Configuration Protocol) Settings section, List and Bindings, etc. The Raspberry Pi and all other devices on your LAN should be listed here. Hopefully, your router will have a somewhat intuitive interface that will make sense as to how to assign an IP address to a device or MAC address. If all else fails, consult your manufacturer’s instructions.

The default port for web requests is 80. You can leave the default unless your Internet Service Provider doesn’t allow port 80. Next step in your router’s configuration is to have the router forward all incoming requests on port 80 to the Raspberry Pi. Typically referred to as, Port Forwarding or Port Range Forwarding. You will want to associate the Raspberry Pi’s IP address so that it will receive all incoming requests on port 80 or whatever port you find most appropriate. The most secure web server is one that is not connected to the Internet ;-) Second to that, we should limit the access in our apache conf file to allow ONLY our IP and those known to us. You could also allow Telnet, FTP, SSH, VNC, etc but I do not recommend unless you are familiar with the security risks associated with such services.

Step 4: Get Yourself a Domain Name

http://www.YOUR_CUSTOM_DOMAIN.ddns.net

Check for the DDNS ( Dynamic Domain Name Service ) Setting in your Router’s advanced configuration settings. Most routers will support one or more of the following, http://www.dyn.com, http://www.noip.com, many others search Google for “Dynamic DNS”. The service will offer the ability to register a domain name to associate with the Dynamic IP address that is assigned to you by your Internet Service Provider. Typically, your router or a software plugin that you download and install will update the Dynamic DNS service’s database when your assigned IP address changes.

Step 5: Security Through Obscurity

“In security engineering, security through obscurity (or security by obscurity) is the reliance on the secrecy of the design or implementation as the main method of providing security for a system or component of a system. A system or component relying on obscurity may have theoretical or actual security vulnerabilities, but its owners or designers believe that if the flaws are not known, that will be sufficient to prevent a successful attack. Security experts have rejected this view as far back as 1851, and advise that obscurity should never be the only security mechanism.”
https://en.wikipedia.org/wiki/Security_through_obs...

We often rely on our security being through some sort of obscurity. “If they don’t know about it, they can’t use it to get in.” Common household door locks only have so many combinations, yet we can rely on the lock of our front doors because we know that a thief would have to try every combination or break-the-door-down. However, on the Internet, who is watching your front door, so a thief cannot try every combination? Fortunately, our web-server has an access.log file that is automatically updated and archived for us. Let’s start there and see if anyone has left their “footprints” on your web server.

Step 6: Log Diving

If you are running a LAMP setup on a Raspberry Pi , open-up a terminal window and type in the following:
cd /var/log/apache2/
zcat access.log* | awk '{print $1}' | sort -n | uniq -c | sort -nr | head -20 


The output should be a list with two columns, one containing the number of entries counted, and the second column is the IP address associated with each web request made. The easiest way to get the most information from a reverse IP lookup is by using the following command:

curl ipinfo.io/REPLACE.WITH.IP.ADDRESS.TO.LOOKUP


Rather than rely on an external web service, you can do some digging after you install some tools that are not included by default with the Pi:

sudo apt-get install geoip-bin
geoiplookup IP.ADDRESS


Here is a good article on using geoiplookup. Even more advanced digging not included by default with the Pi:

sudo apt-get install dnsutils
dig -x IP.ADDRESS

Does the location seem suspicious? Try grepping for the activity, the zgrep command includes the compressed files:


zgrep 'IP.ADDRESS' access.log* -1

By looking at the web requests that were made from the IP address, you can determine whether the activity is suspicious. Typically, you will find that these IP addresses are from bots looking for vulnerabilities in your security. You can manually block IP addresses to your blacklist or you can just deny all and allow select IP addresses. If you haven’t already, you’ll want to install and setup a firewall.

Step 7: Apache Web Server

PLEASE NOTE: The code sections in this article appear differently on different devices. When using the Instructables app for mobile devices the code is missing line endings. Most web browsers seem to work okay.

If you are serving web content world-wide then you’ll eventually want to adopt some sort of blacklist, or exclusion list, where you can keep specific IP addresses from accessing your server. However, if you want to tighten-down your security and only allow a select few access then you’ll need to make some changes.

cd /etc/apache2
sudo cp apache2.conf apache2.conf.bak 
sudo vi apache2.conf 

OR

sudo nano apache2.conf

Travel down the file until you reach this section that allows everyone access to your web server from the outside:

<Directory /var/www/>
 Options Indexes FollowSymLinks
 AllowOverride None
 Require all granted
</Directory>

The AllowOverride directive is set to None meaning we will not be using an .htaccess file to override these settings. The next directive, Require is set to all granted, meaning allow anyone access.

Please note: I have found a significant number of bot requests in my log files, snooping for those of Us using phpmyadmin, be sure to limit access:

<Directory /usr/share/phpmyadmin/>
 Order Deny, Allow
 Deny from All
 # localhost
 Allow from 127.0.0.1
 # Local-Area Network
 Allow from 192.168.0
</Directory>

Next, we can add a directory that we want to protect:

<Directory /var/www/html/hydroMazing/>
 Options Indexes FollowSymLinks
 AllowOverride All
</Directory>

The AllowOverride directive is set to All meaning we will be using an .htaccess file to override these settings. We will provide the Require directive in our .htaccess file inside the directory we specified, in this case, “/var/www/html/hydroMazing/”

# AccessFileName: The name of the file to look for in each directory
# for additional configuration directives. See also the AllowOverride
# directive.
AccessFileName .htaccess

You could change the name of the .htaccess file here to something harder to guess. Keep the dot at the beginning because it means hidden file. Use your imagination!

Now you can use an .htaccess file as your whitelist, or inclusion list:

To create a .htaccess ( or whatever you’ve named it ) file:

 cd /var/www/html/mydirectory/
sudo vi .htaccess 

OR

sudo nano .htaccess
# Allow access to localhost
Require ip 127.0.0.1
# Allow access to my cell phone
Require ip 98.97.34.23

Second entry is an example, change it to your IP address, or the IP address that your web server logged.

Save and close the file. You can add additional access as desired.

Step 8: Make Everyone Use the Front Door

First, let's force anyone visiting our web server to use the front door

cd /etc/apache2
sudo cp apache2.conf apache2.conf.bak 
sudo vi apache2.conf 

OR

sudo nano apache2.conf

Travel down the file until you reach this section where you can add redirects for 404 and 405 errors:

...

# AccessFileName: The name of the file to look for in each directory
# for additional configuration directives. See also the AllowOverride
# directive.
AccessFileName .htaccess

ErrorDocument 404 /
ErrorDocument 405 /

...

Save and close file.

Setup Access Lists

cd /var/www/html/
sudo vi .htaccess

# localhost
Require ip 127.0.0.1

Save and Close file.

Repeat for your admin directory

cd /var/www/html/admin/
sudo vi .htaccess


# localhost
Require ip 127.0.0.1

Save and Close file.

Step 9: Web Interface for Allowing Access

I'm sharing with you my simple web interface that I made for my hydroMazing Smart Garden System.

I wrote the basic interface using PHP to read and write files giving the user the ability to add or delete IP addresses from their .htaccess files.

Download the file and extract to your downloads directory and then copy them to your web server's base directory:

sudo cp -R /home/pi/downloads/*.php /var/www/html/

Change permissions:

sudo chmod -R www-data:www-data /var/www/html/*
sudo chown -R 755 /var/www/html/*.php

Wait! Not so fast!

We should protect the username and password with an SSL connection.

https://hallard.me/enable-ssl-for-apache-server-in-5-minutes/

Step 10: Build a Wall

Install the open-source firewall builder

Pop open a terminal from your Raspberry Pi’s desktop and type the following:

sudo apt-get install fwbuilder

After the installation has completed, you will have a new option under the Menu/Internet option from your desktop for the firewall builder GUI.

Add a new firewall and name it the same as your server.

Select the “web server” template to load default rules. Note that the default rules restrict your server from accessing the outside Internet. In order to allow access, you’ll need to add a rule. The easiest way to add a rule is to copy an existing rule that is similar to your needs.

Step 11: ​Compile and Install

We can build our firewall through this interface, but we won’t be able to install it because we won’t have sufficient permissions to write to the file system. Enter the following at a terminal window’s command line assuming you named your server the same as your DDNS name:

sudo mkdir /etc/fw 
sudo touch /etc/fw/servername.ddns.net.fw 
sudo chmod 777 /etc/fw/servername.ddns.net.fw

Now, you should be able to use the firewall builder program to compile and install the firewall. You can either restart the apache web server or simply reboot.

Thank you for taking the time to read my Instructable!

please follow me and learn much more at http://www.hydroMazing.com

IoT Builders Contest

Participated in the
IoT Builders Contest