A firewall filters network traffic, which is transmitted in packets.
The network packet filter is configured with rules.
The basics of these filter rules are explained here.
On Debian, iptables-restore is called on boot by installing the following package:
apt install iptables-persistent
We set the default policy of the INPUT chain to DROP and
specify some rules, which are applied from top to bottom:
lo are accepted.ESTABLISHED connections or RELATED packets are accepted.ping requests) is allowed./etc/iptables/rules.v4*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
-A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 8 --rttl --name SSH -j DROP
-A INPUT -p tcp --dport 22 -j ACCEPT
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT
COMMIT
Load the IPv4 rules from file:
iptables-restore < /etc/iptables/rules.v4
Verify the loaded IPv4 rules:
iptables -L
The PREROUTING chain is used for port forwarding.
The rule in the POSTROUTING chain translates the source address of outgoing packets.
The reply will be forwarded by translating the destination address of incoming packets.
This is what ordinary IPv4 routers do.
Rules for the nat table are part of the iptables rules:
/etc/iptables/rules.v4*filter
#...
COMMIT
*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.0.100:80
-A POSTROUTING -s 192.168.0.0/255.255.255.0 -o ppp0 -j MASQUERADE
COMMIT
Forwarding of IPv4 packets needs to be enabled in the kernel.
An interface for modifying kernel parameters is the proc file system.
echo 1 > /proc/sys/net/ipv4/ip_forward
A simplified command line tool for the proc file system is sysctl.
To make the change persistent over reboots, edit the following file:
/etc/sysctl.conf#...
# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1
#...
For IPv6, the following rules need to be added:
/etc/iptables/rules.v6*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmpv6 -j ACCEPT
-A INPUT -p udp -s fe80::/10 --dport 546 -j ACCEPT
-A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
-A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 8 --rttl --name SSH -j DROP
-A INPUT -p tcp --dport 22 -j ACCEPT
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT
COMMIT
Load the IPv6 rules from file:
ip6tables-restore < /etc/iptables/rules.v6
Verify the loaded IPv6 rules:
ip6tables -L
nftables is the successor of {ip,ip6,arp,eb}tables.
There is only one ruleset needed to cover IPv4 and IPv6.
The table ip contains chains with rules for IPv4.
The contained chain input filters incoming packets.
All accepted IPv4 packets are marked with 0x34414343 ("4ACC"):
The table ip6 contains chains with rules for IPv6.
The contained chain input filters incoming packets.
All accepted IPv6 packets are marked with 0x36414343 ("6ACC"):
The table inet contains chains with rules for IPv4 and IPv6.
The contained chain input accepts the following incoming packets:
0x34414343 (from table ip) are accepted.0x36414343 (from table ip6) are accepted./etc/nftables.conf#!/usr/sbin/nft -f
flush ruleset
table ip filter {
set ipv4_ssh_meter {
type ipv4_addr
flags dynamic,timeout
timeout 10m
}
chain input {
type filter hook input priority -10;
meta l4proto icmp counter meta mark set 0x34414343 accept
tcp dport 22 ct state new update @ipv4_ssh_meter { ip saddr limit rate 12/minute } counter meta mark set 0x34414343 accept
}
}
table ip6 filter {
set ipv6_ssh_meter {
type ipv6_addr
flags dynamic,timeout
timeout 10m
}
chain input {
type filter hook input priority -10;
meta l4proto ipv6-icmp counter meta mark set 0x36414343 accept
ip6 saddr fe80::/10 udp dport 546 counter meta mark set 0x36414343 accept
tcp dport 22 ct state new update @ipv6_ssh_meter { ip6 saddr limit rate 12/minute } counter meta mark set 0x36414343 accept
}
}
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
iifname "lo" counter accept
ct state established,related counter accept
meta mark 0x34414343 counter accept
meta mark 0x36414343 counter accept
tcp dport 80 counter accept
tcp dport 443 counter accept
}
}
Load the ruleset from file:
nft -f /etc/nftables.conf
Verify the loaded ruleset:
nft list ruleset
systemctl enable nftables.service