Ingress chain
The ingress chain needs to know the name of the device that it’s filtering. Currently the tables generated by nftfw are essentially device independent, and this makes them easy to drop in and use without any specific hardware configuration. That being said, on my systems I change nftfw_init.nft to include some ingress filtering, but have not published it as ‘standard’ because it complicates matters. Sometimes simple systems that work are better than complicated ones that need a lot of understanding from users.
Here’s the code I put at the top of my nftfw_init.nft
:
# DDOS hardening
# From https://blog.samuel.domains/blog/security/nftables-hardening-rules-and-good-practices
table netdev filter {
# set to look for BOGONS, ie packets from outside that use
# public local ip address range
# may need adjustment if the router uses an internal address
# often 192.168.1.0/24
set ipv4_bogons {
type ipv4_addr
flags interval
elements = {
0.0.0.0/8,
10.0.0.0/8,
100.64.0.0/10,
127.0.0.0/8,
169.254.0.0/16,
172.16.0.0/12,
192.0.0.0/24,
192.0.2.0/24,
192.168.0.0/16,
198.18.0.0/15,
198.51.100.0/24,
203.0.113.0/24,
224.0.0.0/3
}
}
# chain looking at packets directly from the device
# the eth0 here should be replaced by your WAN connection device
# this table looks at both ipv4 and ipv6 packets
chain ingress {
type filter hook ingress device eth0 priority -500;
# IP fragments
# not sure about this so it's just counted for now
ip frag-off & 0x1fff != 0 counter
# Track bogons
ip saddr @ipv4_bogons meta protocol ip counter drop
# TCP XMAS attack
tcp flags & (fin|syn|rst|psh|ack|urg) == fin|syn|rst|psh|ack|urg counter drop
# TCP NULL
tcp flags & (fin|syn|rst|psh|ack|urg) == 0x0 counter drop
# TCP MSS
tcp flags syn tcp option maxseg size 1-535 meta protocol ip counter drop
}
}
table inet mangle {
chain prerouting {
type filter hook prerouting priority -150;
# CT INVALID
ct state invalid counter drop
# TCP SYN (CT NEW)
tcp flags & (fin|syn|rst|ack) != syn ct state new counter drop
}
}
You have to add the name of the device you are filtering, and on a home network you may need to adjust the bogons code to remove any public address range you are using.
Whitelisting sets
I think that this would be possible using the extant blacknets system, assuming that you don’t want to use that. Caveat: I’ve not tried this.
The current lookup chain generated for blacknets is:
chain blacknets {
ip saddr @blacknets_set counter jump dropcounter
}
You are whitelisting and will want to drop the packet if the ip is not in the set, so you need:
chain blacknets {
ip saddr != @blacknets_set counter jump dropcounter
}
All blacknets files are used to create a single set, so this will work.
Rules are generated by small shell scripts in rule.d. Currently the config.ini file is telling the system to use the standard ‘drop’ rule for blacknets.
So copy the current drop.sh to say exclude.sh and change
if [ "$IPS" != "" ]; then
IPSWITHDIRECTION="$PROTO $ADDRCMD $IPS"
fi
to
if [ "$IPS" != "" ]; then
IPSWITHDIRECTION="$PROTO $ADDRCMD != $IPS"
fi
Check that your script is syntactically OK by running it through bash.
Now alter config.ini to change the blacknets setting:
;incoming = accept
;outgoing = reject
;whitelist = accept
;blacklist = drop
blacknets = exclude
and I think that would do it.
Thanks
For the comments.