- Introduction of the Home Automation project
- Part 2: Setting up the Raspberry Pi
- Part 3: Building the control box
- Part 4: Securing the software
- Part 5: Public access to the service
- Part 6: Setting up the app
Before making the Raspberry Pi publicly accessible, it is very important to secure the software against malicious users. Because of that this Post, Part 4 of the HomeAutomation Project, was created. If you have suggestions of how to secure the Raspberry Pi even better, feel free to add an comment at the end of the page.
Securing the OS
One of the biggest issues of the Raspbian OS’s security is the default pi user with the default password. Also the pi user has root rights without needing to type any password. As a result of these circumstances an attacker, who is able to log in, automatically has root rights on the system.
The following command changes the passwords of the root and pi users:
sudo passwd
sudo passwd pi
To enable password protection at using sudo remove /etc/sudoers.d/010_pi-nopasswd and set the defaults of sudo to the root password.
sudo rm /etc/sudoers.d/010_pi-nopasswd
sudo visudo
# add the following line to the file:
Defaults rootpw
Securing SSH
Some configurations can secure SSH connections. However these should anyways be allowed only in local networks. Add the lines to the SSH-config file and restart the service:
sudo nano /etc/ssh/sshd_config
# change these lines in the config file:
########################################
PermitRootLogin no
StrictModes yes
PubkeyAuthentication yes
ChallengeResponseAuthentication no
PasswordAuthentication no
PermitEmptyPasswords no
X11Forwarding no
########################################
# restart the SSH service
sudo service ssh restart
Configuring the firewall (IPTables)
The next step is to restrict the access only to the required ports. An easy way of achieving some results is to use IPTables. Be sure to follow these steps very carefully, as it is possible to lock yourself out of the system.
Create the iptables script, make it executable and open it for editing:
touch iptables.sh
sudo chmod +x iptables.sh
nano iptables.sh
After opening the file insert the code below. (modified from here)
#!/bin/sh
# iptables script
IPTABLES="/sbin/iptables"
echo "Loading Firewall ..."
# Purge/Flush
# ~~~~~~~~~~~
# delete all rules
sudo iptables -F
sudo iptables -t nat -F
sudo iptables -t mangle -F
# delete all rule chains
sudo iptables -X
sudo iptables -t nat -X
sudo iptables -t mangle -X
# Rules
# ~~~~~~
# IPv4 Default
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT
# allow traffic for the Loopback interface
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A OUTPUT -o lo -j ACCEPT
# allow outgoing traffic
sudo iptables -A OUTPUT -j ACCEPT
# allow ICMP response packets
sudo iptables -A INPUT -p icmp -m icmp --icmp-type echo-reply -j ACCEPT
sudo iptables -A INPUT -p icmp -m icmp --icmp-type echo-request -j ACCEPT
sudo iptables -A INPUT -p icmp -m icmp --icmp-type destination-unreachable -j ACCEPT
# accept all packets to an established TCP connection
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# allow SSH
sudo iptables -A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT
# allow webserver access (HTTP, HTTPS)
sudo iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 8080 -j ACCEPT
sudo iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
sudo iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 8443 -j ACCEPT
# reject all packets properly
sudo iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset
sudo iptables -A INPUT -j REJECT --reject-with icmp-port-unreachable
sudo iptables -A FORWARD -j REJECT
echo "... done!"
Now run the script:
sudo ./iptables.sh
If everything was successful, the SSH connection should remain. At the moment all changes to the iptables are lost at reboot. The following lines ensure the reloading of the iptables configurations at startup.
sudo /sbin/iptables-save > /home/pi/rules.v4
sudo nano /etc/rc.local
# add this line before exit 0
sudo iptables-restore < /home/pi/rules.v4
To check if everything works as intended, reboot the Raspberry Pi and list the IPTables rules.
sudo reboot
sudo iptables -L
Securing Apache2
The Apache2 webserver currently does not provide enough security by default. However some easy steps can be made to harden the webserver for public access. This guide will just provide the needed changes to the /etc/apache2/apache2.conf. If you want to read the explanaition follow the links at the end of this page.
sudo nano /etc/apache2/apache2.conf
####################################
# change these lines in the default config..
<Directory /var/www/>
Options None
AllowOverride None
Require all granted
</Directory>
# comment out these lines..
#<Directory /usr/share>
# AllowOverride None
# Require all granted
#</Directory>
# add these lines..
TraceEnable off
ServerTokens Prod
ServerSignature Off
After changing the configuration of Apache2 restart it:
sudo service apache2 restart
Remove unneeded examples from Tomcat:
sudo rm -R /opt/tomcat/latest/webapps/examples
Part 5: Public access to the service will show how to configure port forwarding and Dynamic DNS (DDNS) and the configuration of Let’s Encrypt to secure the communication.