Creating a Firewall

Now it’s time to set up a firewall to limit and block unwanted inbound traffic to your Pi. This step is optional, but we strongly recommend that you use the example below to block traffic to ports that are not commonly used. It’s a good way to deter would-be intruders! You can always modify the rules or disable the firewall later.

Here’s how to create a firewall on your Pi:

Check your Pi’s default firewall rules by entering the following command:

sudo iptables -L

Examine the output. If you haven’t implemented any firewall rules yet, you should see an empty ruleset, as shown below:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Create a file to hold your firewall rules by entering the following command:

sudo nano /etc/iptables.firewall.rules

Now it’s time to create some firewall rules. We’ve created some basic rules to get you started. Copy and paste the rules shown below in to the iptables.firewall.rules file you just created.

*filter

#  Allow all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
-A INPUT -i lo -j ACCEPT
-A INPUT -d 127.0.0.0/8 -j REJECT

#  Accept all established inbound connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

#  Allow all outbound traffic - you can modify this to only allow certain traffic
-A OUTPUT -j ACCEPT

#  Allow HTTP and HTTPS connections from anywhere (the normal ports for websites and SSL).
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT

# Allows SMTP access
-A INPUT -p tcp --dport 25 -j ACCEPT
-A INPUT -p tcp --dport 465 -j ACCEPT
-A INPUT -p tcp --dport 587 -j ACCEPT

# Allows pop and pops connections
# -A INPUT -p tcp --dport 110 -j ACCEPT
# -A INPUT -p tcp --dport 995 -j ACCEPT

# Allows imap and imaps connections
-A INPUT -p tcp --dport 143 -j ACCEPT
-A INPUT -p tcp --dport 993 -j ACCEPT

#  Allow SSH connections
#  The -dport number should be the same port number you set in sshd_config
-A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT

#  Allow ping
-A INPUT -p icmp --icmp-type echo-request -j ACCEPT

#  Log iptables denied calls
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

#  Drop all other inbound - default deny unless explicitly allowed policy
-A INPUT -j DROP
-A FORWARD -j DROP

COMMIT

Edit the rules as necessary. By default, the rules will allow traffic to the following services and ports: HTTP (80), HTTPS (443), SSH (22), and ping. I also added SMTP, Pop and IMAP as we need those later. All other ports will be blocked.

Save the changes to the firewall rules file by pressing Control-X, and then Y.

Activate the firewall rules by entering the following command:

sudo iptables-restore < /etc/iptables.firewall.rules

Recheck your Pi’s firewall rules by entering the following command:

sudo iptables -L

Examine the output. The new ruleset should look like the one shown below:

Chain INPUT (policy ACCEPT)
target     prot opt source     destination
ACCEPT     all  --  anywhere   anywhere            
REJECT     all  --  anywhere   loopback/8  reject-with icmp-port-unreachable
ACCEPT     all  --  anywhere   anywhere    state RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere   anywhere    tcp dpt:http
ACCEPT     tcp  --  anywhere   anywhere    tcp dpt:https
ACCEPT     tcp  --  anywhere   anywhere    tcp dpt:smtp
ACCEPT     tcp  --  anywhere   anywhere    tcp dpt:ssmtp
ACCEPT     tcp  --  anywhere   anywhere    tcp dpt:submission
ACCEPT     tcp  --  anywhere   anywhere    tcp dpt:imap2
ACCEPT     tcp  --  anywhere   anywhere    tcp dpt:imaps
ACCEPT     tcp  --  anywhere   anywhere    state NEW tcp dpt:ssh
ACCEPT     icmp --  anywhere   anywhere    icmp echo-request
LOG        all  --  anywhere   anywhere    limit: avg 5/min burst 5 LOG level debug prefix "iptables denied:"
DROP       all  --  anywhere   anywhere 

Chain FORWARD (policy ACCEPT)
target     prot opt source     destination
DROP       all  --  anywhere   anywhere

Chain OUTPUT (policy ACCEPT)
target     prot opt source     destination
ACCEPT     all  --  anywhere   anywhere

Now you need to ensure that the firewall rules are activated every time you restart your Pi.

Start by creating a new script with the following command:

sudo nano /etc/network/if-pre-up.d/firewall

Copy and paste the following lines in to the file you just created:

#!/bin/sh
/sbin/iptables-restore < /etc/iptables.firewall.rules

Press Control-X and then press Y to save the script. Set the script’s permissions by entering the following command:

sudo chmod +x /etc/network/if-pre-up.d/firewall

That’s it! Your firewall rules are in place and protecting your Pi. Remember, you’ll need to edit the firewall rules later if you install other software or services.

Installing and Configuring Fail2Ban

Fail2Ban is an application that prevents dictionary attacks on your server. When Fail2Ban detects multiple failed login attempts from the same IP address, it creates temporary firewall rules that block traffic from the attacker’s IP address. Attempted logins can be monitored on a variety of protocols, including SSH, HTTP, and SMTP. By default, Fail2Ban monitors SSH only.

Here’s how to install and configure Fail2Ban. Install Fail2Ban by entering the following command:

sudo apt-get install fail2ban

Fail2Ban is now installed and running on your Pi. It will monitor your log files for failed login attempts. After an IP address has exceeded the maximum number of authentication attempts, it will be blocked at the network level and the event will be logged in /var/log/fail2ban.log.