Introduction
Firewall is an important step in securing the server.
It decide the individual rules and policies that will enforce traffic restrictions to your network
Pre-requisites
- Ubuntu 20,04 server machine with root user
- Firewall policies
Step 1 – Installing Persistent Firewall
Installing iptables-persistent
package.
$ sudo apt update .... $ sudo apt install iptables-persistent
Select YES to save current rules.
Firewall policy and framework of Iptables
- IPv4 :
/etc/iptables/rules.v4
- IPv6 :
/etc/iptables/rules.v6
Step 2 – Setup Basic Firewall Policy
$ sudo nano /etc/iptables/rules.v4
IPv4 Output of the file
/etc/iptables/rules.v4
Output # Generated by iptables-save v1.8.4 on Tue Mar 1 19:03:10 2022 *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] COMMIT # Completed on Tue Mar 1 19:03:10 2022 ## Delete these contents and replace them with the following: ## *filter # Allow all outgoing, but drop incoming and forwarding packets by default :INPUT DROP [0:0] :FORWARD DROP [0:0] :OUTPUT ACCEPT [0:0] # Custom per-protocol chains :UDP - [0:0] :TCP - [0:0] :ICMP - [0:0] # Acceptable UDP traffic # Acceptable TCP traffic -A TCP -p tcp --dport 22 -j ACCEPT # Acceptable ICMP traffic # Boilerplate acceptance policy -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT -A INPUT -i lo -j ACCEPT # Drop invalid packets -A INPUT -m conntrack --ctstate INVALID -j DROP # Pass traffic to protocol-specific chains ## Only allow new connections (established and related should already be handled) ## For TCP, additionally only allow new SYN packets since that is the only valid ## method for establishing a new TCP connection -A INPUT -p udp -m conntrack --ctstate NEW -j UDP -A INPUT -p tcp --syn -m conntrack --ctstate NEW -j TCP -A INPUT -p icmp -m conntrack --ctstate NEW -j ICMP # Reject anything that's fallen through to this point ## Try to be protocol-specific w/ rejection message -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable -A INPUT -p tcp -j REJECT --reject-with tcp-reset -A INPUT -j REJECT --reject-with icmp-proto-unreachable # Commit the changes COMMIT *raw :PREROUTING ACCEPT [0:0] :OUTPUT ACCEPT [0:0] COMMIT *nat :PREROUTING ACCEPT [0:0] :INPUT ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :POSTROUTING ACCEPT [0:0] COMMIT *security :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] COMMIT *mangle :PREROUTING ACCEPT [0:0] :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :POSTROUTING ACCEPT [0:0] COMMIT
Step 3 – Testing Firewall Policy
IPv4 Testing
$ sudo iptables-restore -t /etc/iptables/rules.v4
IPv6 Testing
$ sudo nano /etc/iptables/rules.v6
IPv6 Output of the file
/etc/iptables/rules.v6
Output # Generated by ip6tables-save v1.8.4 on Tue Mar 1 19:03:10 2022 *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] COMMIT # Completed on Tue Mar 1 19:03:10 2022 ## You can block all IPv6 traffic by replacing the contents of the file with the following configuration: ## *filter :INPUT DROP [0:0] :FORWARD DROP [0:0] :OUTPUT DROP [0:0] COMMIT *raw :PREROUTING DROP [0:0] :OUTPUT DROP [0:0] COMMIT *nat :PREROUTING DROP [0:0] :INPUT DROP [0:0] :OUTPUT DROP [0:0] :POSTROUTING DROP [0:0] COMMIT *security :INPUT DROP [0:0] :FORWARD DROP [0:0] :OUTPUT DROP [0:0] COMMIT *mangle :PREROUTING DROP [0:0] :INPUT DROP [0:0] :FORWARD DROP [0:0] :OUTPUT DROP [0:0] :POSTROUTING DROP [0:0] COMMIT
Test IPv6 File
$ sudo ip6tables-restore -t /etc/iptables/rules.v6 .... $ sudo service netfilter-persistent reload
Output * Loading netfilter rules... run-parts: executing /usr/share/netfilter-persistent/plugins.d/15-ip4tables start run-parts: executing /usr/share/netfilter-persistent/plugins.d/25-ip6tables start [ OK ]
Verify the listing now
$ sudo iptables -S ..... Output -P INPUT DROP -P FORWARD DROP -P OUTPUT ACCEPT -N ICMP -N TCP -N UDP -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -m conntrack --ctstate INVALID -j DROP -A INPUT -p udp -m conntrack --ctstate NEW -j UDP -A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j TCP -A INPUT -p icmp -m conntrack --ctstate NEW -j ICMP -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable -A INPUT -p tcp -j REJECT --reject-with tcp-reset -A INPUT -j REJECT --reject-with icmp-proto-unreachable -A TCP -p tcp -m tcp --dport 22 -j ACCEPT
Verify IPv6 Tables
sudo ip6tables -S ..... Output -P INPUT DROP -P FORWARD DROP -P OUTPUT DROP
These firewall rules will be re-applied at each boot.
Step 4 – Implementing Firewall
The Firewall can be implemented using iptables command.
Reset the Firewall
$ sudo service netfilter-persistent flush
Now verify rules
sudo iptables -S .... Output -P INPUT ACCEPT -P FORWARD ACCEPT -P OUTPUT ACCEPT
Step 5 – Creating Protocol Iptables Chains
UDP Traffic
sudo iptables -N UDP
TCP Traffic
sudo iptables -N TCP
ICMP Traffic
sudo iptables -N ICMP
SSH Traffic Exception
sudo iptables -A TCP -p tcp --dport 22 -j ACCEPT
Step 6 – Iptables Accept and Deny Rules
First, create an exception to accept all traffic that is part of an established connection or is related to an established connection:
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
You’ll also want to allow all traffic originating on the local loopback interface.
sudo iptables -A INPUT -i lo -j ACCEPT
Finally, deny all invalid packets
sudo iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
Step 7 – Jump Rules to Protocol Chains
To direct traffic in the INPUT
chain into the appropriate protocol-specific chains.
UDP
traffic.
sudo iptables -A INPUT -p udp -m conntrack --ctstate NEW -j UDP
TCP
Traffic
sudo iptables -A INPUT -p tcp --syn -m conntrack --ctstate NEW -j TCP
ICMP
Traffic
sudo iptables -A INPUT -p icmp -m conntrack --ctstate NEW -j ICMP
Step 8 – Denying Rules to Chains
We can deny the traffic using the REJECT
target, which sends a response message to the client.
UDP
and ICMP
port message stating “port unreachable”
sudo iptables -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
TCP
Connection closed port
sudo iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset
ICMP
“Protocol Unreachable”
sudo iptables -A INPUT -j REJECT --reject-with icmp-proto-unreachable
Step 9 – Adjusting Policies
The last three rules you added should handle all remaining traffic in the INPUT
chain.
However, you should set the default policy to DROP
as a precaution.
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo ip6tables -P INPUT DROP
sudo ip6tables -P FORWARD DROP
sudo ip6tables -P OUTPUT DROP
Step 10 – Saving iptables Policies
Now our Firewall rules will make sure they block the unwanted traffic.
Once you’re satisfied that your rules are behaving correctly, you can save them so that they will be automatically applied to your system at boot.
Save your current rules (both IPv4 and IPv6)
sudo service netfilter-persistent save
This overwrite your /etc/iptables/rules.v4
and /etc/iptables/rules.v6
Finale
With this Firewall setup tutorial iptables rules directly into the configuration files.
Now this is a good starting Firewall Configuration.