Netfilter and iptables
Installing persistence
iptables
is installed by default. For rules to be persistent (automatically loaded) so they work after reboot, install iptables-persistent
:
$ sudo apt-get install iptables-persistent
[sudo] password for user:
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
netfilter-persistent
The following NEW packages will be installed:
iptables-persistent netfilter-persistent
0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
Need to get 18.9 kB of archives.
After this operation, 147 kB of additional disk space will be used.
Rules
Status command
To list rules -L showing interface name, rule options, TOS masks, packet and byte counters -n, and IP address and port in numeric format without using DNS to resolve names -v:
# iptables -L -n -v
With line numbers (important for deleting or inserting new rules into the firewall):
# iptables -n -L -v --line-numbers
To display INPUT or OUTPUT chain rules:
# iptables -L INPUT -n -v
# iptables -L OUTPUT -n -v --line-numbers
Deleting a rule
To delete line number 4 using -D to delete one or more rules from the selected chain:
# iptables -D INPUT 4
Inserting a rule
# iptables -L INPUT -n --line-numbers
Chain INPUT (policy DROP)
num target prot opt source destination
1 DROP all -- xxx.xxx.xxx.1 0.0.0.0/0
2 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state NEW,ESTABLISHED
Inserting a rule between 1 and 2:
# iptables -I INPUT 2 -s xxx.xxx.xxx.2 -j DROP
Gives:
# iptables -L INPUT -n --line-numbers
Chain INPUT (policy DROP)
num target prot opt source destination
1 DROP all -- xxx.xxx.xxx.1 0.0.0.0/0
2 DROP all -- xxx.xxx.xxx.2 0.0.0.0/0
3 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state NEW,ESTABLISHED
Saving the rules
For saving the rules so they can be loaded at every reboot (you need to have iptables-persistent installed)
# iptables-save > /etc/iptables/rules.v4
# ip6tables-save > /etc/iptables/rules.v6
Stop/Restart
Some distros like CentOS have installed a service called iptables
to start and stop the firewall and a configuration file to configure it. For all other distros, iptables
is a command, not a service.
Configuring iptables
To set it to deny everything except the bare minimum requirements that you need on your system(s) and only accept connections that have been explicitly allowed in the rules.
Localhost: $ sudo iptables -A INPUT -i lo -j ACCEPT
Accept data related to outbound connections your system has initiated (this includes apt mirrors):
$ sudo iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
You can set up tables for rules for traffic you wish to accept on your system from external connections:
# iptables -N accept_traffic
# iptables -A INPUT -j accept_traffic
You then can use it, for example on a server where you run SSH, with (change port to port you set):
# iptables -A accept_traffic -p tcp --dport 22 -j ACCEPT
The two most common cracks posted on the Ubuntu forums are ssh and vnc, both running with password authentication. This probably is true for all debian-based distro’s. You are recommended to secure ssh by using keys (and disabling password authentication) and either configuring iptables or using a service such as denyhosts or fail2ban.
To reject all traffic for which there are no rules set (the first way sends a Host Unreachable ICMP packet then terminates the connection, the second way simply ignores):
# iptables -A INPUT -j REJECT --reject-with icmp-host-unreachable
or:
# iptables -A INPUT -j DROP
Configuring ip6tables
To set it to deny everything except the bare minimum requirements that you need on your system(s) and only accept connections that have been explicitly allowed in the rules:
Localhost:
$ sudo ip6tables -A INPUT -i lo -j ACCEPT
Accepting data related to outbound connections your system has initiated:
$ sudo ip6tables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
Setting up a table:
# ip6tables -N accept_traffic
# ip6tables -A INPUT -j accept_traffic
Rejecting all traffic for which there are no rules set:
# ip6tables -A INPUT -j REJECT --reject-with icmp6-addr-unreachable
or
# ip6tables -A INPUT -j DROP
Usage examples
ICMP
For accepting “Time Exceeded” (necessary for time-restricted connection setups):
$ sudo iptables -A INPUT -p icmp -m icmp --icmp-type 11 -j ACCEPT
For accepting “Destination Unreachable”:
$ sudo iptables -A INPUT -p icmp -m icmp --icmp-type 3/4 -j ACCEPT
For accepting PING requests/responses (“Echo” ICMP, for keep-alive requests):
$ sudo iptables -A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
For IPv6 there are a kazillion ICMP requests so if you are not blocking IPv6, it is recommended to not block ICMP packets:
$ sudo ip6tables -A INPUT -p icmpv6 -j ACCEPT