The following firewall template can be used to restrict both inbound and outbound traffic.
It is assumed that allow NTP, DNS, HTTP and HTTPS traffic outbound should be allowed. Inbound SSH, HTTP and HTTPS traffic will be allowed.
#!/usr/sbin/nft -f
## Clear/flush all existing rules
flush ruleset
# Main inet family filtering table
table inet filter {
# Rules for forwarded traffic
chain forward {
type filter hook forward priority 0; policy drop
## Log any unmatched traffic but rate limit logging to a maximum of 60 messages/minute
## The default policy will be applied to unmatched traffic
limit rate 60/minute burst 100 packets \
log prefix "Forward - Drop: " \
comment "Log any unmatched traffic"
## Count the unmatched traffic
counter \
comment "Count any unmatched traffic"
}
# Rules for input traffic
chain input {
type filter hook input priority 0; policy drop
## Permit inbound traffic to loopback interface
iif lo \
accept \
comment "Permit all traffic in from loopback interface"
## Permit established and related connections
ct state established,related \
counter \
accept \
comment "Permit established/related connections"
## Log and drop new TCP non-SYN packets
tcp flags != syn ct state new \
limit rate 100/minute burst 150 packets \
log prefix "IN - New !SYN: " \
comment "Rate limit logging for new connections that do not have the SYN TCP flag set"
tcp flags != syn ct state new \
counter \
drop \
comment "Drop new connections that do not have the SYN TCP flag set"
## Log and drop TCP packets with invalid fin/syn flag set
tcp flags & (fin|syn) == (fin|syn) \
limit rate 100/minute burst 150 packets \
log prefix "IN - TCP FIN|SIN: " \
comment "Rate limit logging for TCP packets with invalid fin/syn flag set"
tcp flags & (fin|syn) == (fin|syn) \
counter \
drop \
comment "Drop TCP packets with invalid fin/syn flag set"
## Log and drop TCP packets with invalid syn/rst flag set
tcp flags & (syn|rst) == (syn|rst) \
limit rate 100/minute burst 150 packets \
log prefix "IN - TCP SYN|RST: " \
comment "Rate limit logging for TCP packets with invalid syn/rst flag set"
tcp flags & (syn|rst) == (syn|rst) \
counter \
drop \
comment "Drop TCP packets with invalid syn/rst flag set"
## Log and drop invalid TCP flags
tcp flags & (fin|syn|rst|psh|ack|urg) < (fin) \
limit rate 100/minute burst 150 packets \
log prefix "IN - FIN:" \
comment "Rate limit logging for invalid TCP flags (fin|syn|rst|psh|ack|urg) < (fin)"
tcp flags & (fin|syn|rst|psh|ack|urg) < (fin) \
counter \
drop \
comment "Drop TCP packets with flags (fin|syn|rst|psh|ack|urg) < (fin)"
## Log and drop invalid TCP flags
tcp flags & (fin|syn|rst|psh|ack|urg) == (fin|psh|urg) \
limit rate 100/minute burst 150 packets \
log prefix "IN - FIN|PSH|URG:" \
comment "Rate limit logging for invalid TCP flags (fin|syn|rst|psh|ack|urg) == (fin|psh|urg)"
tcp flags & (fin|syn|rst|psh|ack|urg) == (fin|psh|urg) \
counter \
drop \
comment "Drop TCP packets with flags (fin|syn|rst|psh|ack|urg) == (fin|psh|urg)"
## Drop traffic with invalid connection state
ct state invalid \
limit rate 100/minute burst 150 packets \
log flags all prefix "IN - Invalid: " \
comment "Rate limit logging for traffic with invalid connection state"
ct state invalid \
counter \
drop \
comment "Drop traffic with invalid connection state"
## Permit IPv4 ping/ping responses but rate limit to 2000 PPS
ip protocol icmp icmp type { echo-reply, echo-request } \
limit rate 2000/second \
counter \
accept \
comment "Permit inbound IPv4 echo (ping) limited to 2000 PPS"
## Permit all other inbound IPv4 ICMP
ip protocol icmp \
counter \
accept \
comment "Permit all other IPv4 ICMP"
## Permit IPv6 ping/ping responses but rate limit to 2000 PPS
icmpv6 type { echo-reply, echo-request } \
limit rate 2000/second \
counter \
accept \
comment "Permit inbound IPv6 echo (ping) limited to 2000 PPS"
## Permit all other inbound IPv6 ICMP
meta l4proto { icmpv6 } \
counter \
accept \
comment "Permit all other IPv6 ICMP"
## Permit inbound traceroute UDP ports but limit to 500 PPS
udp dport 33434-33524 \
limit rate 500/second \
counter \
accept \
comment "Permit inbound UDP traceroute limited to 500 PPS"
## Permit inbound SSH
tcp dport ssh ct state new \
counter \
accept \
comment "Permit inbound SSH connections"
## Permit inbound HTTP and HTTPS
tcp dport { http, https } ct state new \
counter \
accept \
comment "Permit inbound HTTP and HTTPS connections"
## Log any unmatched traffic but rate limit logging to a maximum of 60 messages/minute
## The default policy will be applied to unmatched traffic
limit rate 60/minute burst 100 packets \
log prefix "IN - Drop: " \
comment "Log any unmatched traffic"
## Count the unmatched traffic
counter \
comment "Count any unmatched traffic"
}
# Rules for output traffic
chain output {
type filter hook output priority 0; policy drop
## Permit outbound traffic to loopback interface
oif lo \
accept \
comment "Permit all traffic out to loopback interface"
## Permit established and related connections
ct state established,related \
counter \
accept \
comment "Permit established/related connections"
## Drop traffic with invalid connection state
ct state invalid \
limit rate 100/minute burst 150 packets \
log flags all prefix "OUT - Invalid: " \
comment "Rate limit logging for traffic with invalid connection state"
ct state invalid \
counter \
drop \
comment "Drop traffic with invalid connection state"
## Permit IPv4 ping/ping responses but rate limit to 2000 PPS
ip protocol icmp icmp type { echo-reply, echo-request } \
limit rate 2000/second \
counter \
accept \
comment "Permit outbound IPv4 echo (ping) limited to 2000 PPS"
## Permit all other outbound IPv4 ICMP
ip protocol icmp \
counter \
accept \
comment "Permit all other IPv4 ICMP"
## Permit IPv6 ping/ping responses but rate limit to 2000 PPS
icmpv6 type { echo-reply, echo-request } \
limit rate 2000/second \
counter \
accept \
comment "Permit outbound IPv6 echo (ping) limited to 2000 PPS"
## Permit all other outbound IPv6 ICMP
meta l4proto { icmpv6 } \
counter \
accept \
comment "Permit all other IPv6 ICMP"
## Permit outbound traceroute UDP ports but limit to 500 PPS
udp dport 33434-33524 \
limit rate 500/second \
counter \
accept \
comment "Permit outbound UDP traceroute limited to 500 PPS"
## Allow outbound HTTP and HTTPS connections
tcp dport { http, https } ct state new \
counter \
accept \
comment "Permit outbound HTTP and HTTPS connections"
## Permit outbound DNS requests
meta l4proto { tcp, udp } th dport 53 \
counter \
accept \
comment "Permit outbound TCP and UDP DNS requests"
## Allow outbound NTP requests
udp dport 123 \
counter \
accept \
comment "Permit outbound NTP requests"
## Log any unmatched traffic but rate limit logging to a maximum of 60 messages/minute
## The default policy will be applied to unmatched traffic
limit rate 60/minute burst 100 packets \
log prefix "OUT - Drop: " \
comment "Log any unmatched traffic"
## Count the unmatched traffic
counter \
comment "Count any unmatched traffic"
}
}