Personal Web Server Raspberry Pi

raspberry pi

Project Description

"LAMP" web service stack consisting of free open source software.


Related Projects



Insert a micro SD card, then download and run this installer for your Operating System.


Insert the micro SD card into the pi and boot it up with a monitor and keyboard connected.

Go through the wizard and set the keyboard/language settings.

Change the default password; strive for length over complexity.

Connect to the wifi if the pi is not connected by an ethernet cable.

The wizard will update the system automatically.

(*Optional and potentially dangerous*) Open up a terminal and set the root password.

sudo passwd root

Go to the Configuration to customize the hostname and disallow auto-login and decide if you would like to enable SSH.

Reboot the pi for the changes to take affect.

Login only as root with auto-login disallowed.

Open up terminal and run the following commands to customize the username. The sudo -s tells the command to be ran in a new shell as the given user. The exec tells the shell to overwrite itself with the new process. This means the user is overwriting their shell with a new shell that has been created as a different user ( in this case root ). Then it modifies all the user to change from pi to the new custom username. Then change the group of every file/folder from pi to the new username.

exec sudo -s
usermod -l {newname} -d /home/{newname} -m pi
groupmod --new-name {newname} pi

( Optional/Better Security ) Turn off login for root by running this in terminal:

sudo passwd -l root


Create a group for sFTP users and setup their playground:

sudo addgroup exchangefiles
# Create the chroot directory
sudo mkdir /home/exchangefiles/
sudo chmod g+rx /home/exchangefiles/

# Create the group-writable directory
sudo mkdir -p /home/exchangefiles/files/
sudo chmod g+rwx /home/exchangefiles/files/

# Give them both to the new group.
sudo chgrp -R exchangefiles /home/exchangefiles/

Set a custom port for SSH and lock down privileges for SSH. Edit the configuration file:

sudo nano /etc/ssh/sshd_config

Change the Port number by uncommenting this line and setting your own number

#Port 22

Find the comment for built-in implementaiton and change the line below it:

# Enable to built-in implementation of SFTP.
Subsystem sftp internal-sftp

Add this section to lockdown privileges for anyone in the exchangefiles group.

Match Group exchangefiles
  # Force the connection to use SFTP and chroot to the required directory.
  ForceCommand internal-sftp
  ChrootDirectory /home/exchangefiles
  # Disable tunneling, authentication agent, TCP and X11 forwarding.
  PermitTunnel no
  AllowAgentForwarding no
  AllowTcpForwarding no
  X11Forwarding no

Add users to the group, set their password, and restart the ssh service for it to take effect.


sudo adduser --ingroup exchangefiles testfiles
sudo service ssh restart

Uncomplicated Fire Wall

Uncomplicated Fire Wall, ufw, provides a simpler interface than iptables for packet filtering and netfiltering.

Install ufw with the following commands

sudo apt install ufw

ufw is a fairly straightforward command line tool that needs to be run with superuser privileges; all commands are preceded with sudo. Use the option --dry-run with any ufw commands to view the results of the command without actually making any changes.

Run the following command to enable the firewall and ensure it starts up on boot:

sudo ufw enable

Here are examples commands for opening/closing ports and servfices:

sudo ufw allow 443
sudo ufw deny 22/tcp
sudo ufw allow ssh

This status command lists all current settings for the firewall:

sudo ufw status

Limit login attempts on ssh port using tcp. This command will deny connection if an IP address has attempted to connect six or more times in the last 30 seconds:

sudo ufw limit ssh/tcp

Deny access to port 30 from IP address

sudo ufw deny from port 30


Apache Web Server

Apache is a web server application that serves HTML files over HTTP/HTTPS.

Install Apache with the following command:

sudo apt install apache2 -y

Open a web browser and go to this URL:



http://{pi ip address}

Find out the Raspberry Pi’s IP address by using:

hostname -I

This default generated web page is an HTML file located at:


Add your user to the www-data group and grant the group access to change the content:


Design and build your new websites.


PHP: Hypertext Preprocessor

PHP is a preprocessor: it’s code that runs when the server receives a request for a web page via a web browser. This allows PHP to dynamically create different content under different circumstances.

Install the PHP package with the following command:

sudo apt-get install php -y

Install the latest version of the PHP module for Apache to allow processing PHP files with the following command:

sudo apt install php libapache2-mod-php -y

Test PHP functionality by adding the following command and saving an html file as .php

<?php echo "hello world"; ?>


<?php echo date('Y-m-d H:i:s'); ?>


<?php phpinfo(); ?>



MariaDB is a lightweight service that will host the database. MariaDB is a fork of MySQL.

Install MariaDB with the following command:

sudo apt install mariadb-server
sudo mysql_secure_installation

Then you can use mysql command for connecting:

mysql -root -p {PASSWORD}

Design, model, and build your datatables to use for applications.


Web Min

Webmin is a web-based interface for system administration for Apache, SQL, PHP, and system package upgrades.

Install the Webmin with the following commands:

sudo apt-get install perl libnet-ssleay-perl openssl libauthen-pam-perl libpam-runtime libio-pty-perl apt-show-versions python

Download the required deb file; update to the latest version by checking here


Run dpkg

sudo dpkg --install webmin_1.953_all.deb

Access Webmin by going to the Pi’s IP address followed by the port 10000. Find out the Raspberry Pi’s IP address by using:

hostname -I

Ignore the SSL Certificate error and login using your pi's root credentials.


Fail2ban improves security by blocking malicious connections to the server. Fail2ban scans log files looking for signs of potential attacks such as password failures, exploits, and more. It will automatically update the firewall to ban the offending IP address.

Install Fail2Ban with the following command:

sudo apt-get install fail2ban

Make a copy of the generated jail.config file for Fail2Ban to load:

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

Open up that new file to setup the local configuration:

sudo nano /etc/fail2ban/jail.local

This is a suggested configuration:

enabled = true
filter = sshd
port = ssh
banaction = iptables-multiport
bantime = -1
maxretry = 3
logpath = %(sshd_log)s
backend = %(sshd_backend)s

enabled = true
filter = apache-badbots

Save the file by pressing CTRL + X then Y and finally hit ENTER, then restart the service:

sudo service fail2ban restart

Those settings will help protect SSH and Apache Web Server.



Here are a few helpful tricks and security tips:

  • Change every default password
  • Create a new user and disable the default pi user
  • Change the default host name for network friendliness
  • Check for updates regularly
  • Enable SSH and use a custom port number
  • Update and upgrade often with sudo apt-get
  • Install OpenVPN
  • Schedule tasks with Cron
  • Buy a domain

Let's Encrypt

This piece of software is called “Cerbot”. Install it with the following command:

sudo apt-get install python-certbot-apache

Make sure port 80 and 443 are unblocked in ufw and external access is forwarded to the Pi's IP from the router. Replace the with the purchased domain name.

certbot certonly --standalone -d -d

Follow along with the prompts and enter requested details. It will proceed to grab the certificate from Let’s Encrypt and store it in the following folder:


Test your site using https.



Download and install the latest version of Node.js with the following command:

scurl -sL | sudo -E bash -

Then install using the following command:

sudo apt-get install -y nodejs

Check the version number of Node.js with this command:

node -v


** I recommend finishing the previous tab for Let's Encrypt otherwise the revese proxy will break their authentication **

Cloudflare, Inc. provides content-delivery-network services, DDoS mitigation, Internet security, and distributed domain-name-server services. Cloudflare's services sit between the end user and the hosting website's server, acting as a reverse proxy for websites. The site can be distributed among a pool of different servers all handling requests for the same site. In this case, a reverse proxy can provide a load balancing solution which will distribute the incoming traffic evenly among the different servers to prevent any single server from becoming overloaded. The website can be distributed on several servers around the globe and the reverse proxy will send clients to the server that’s geographically closest to them. This decreases the distances that requests and responses need to travel, minimizing load times.


© 2023 Techno Herder. All rights reserved.
Designed by Andrew Herd