with all the benefits of nftables:

  • performance
  • an important question is: how well can nftables / firewalld shield against DDoS? (the developers need to consider this problem as “default” scenario, yes this is something one excepts a firewall at least can mitigate)
  • one can config the firewall/reload the rule-set without disconnecting existing connections

it has ONE BIG DISADVANTAGE: imho nftables is too complicated and basically can not be handled without firewalld.

the developers of nftables and firewalld themselves should provide a “basic setup script” that when run – will implement basic things like:

  • block all connections except ssh

and then in a wizard like style:

  • “do you want to allow outgoing ntp (timeserver) connections to (ip-of-timeserver-here) (ntp port 68)?”
  • “do you want to allow incoming ssh connections?”
  • “do you want to block all IPs with more than 3 failed ssh logins for 3 days?”
    • (YESSSS! DEFINATELY! 🙂
    • CentOS8
  • “max connetions per ip: do you want to rate-limit incoming ssh connections to 3 concurrent connections per ip?”
  • “max connections within a minute: do you want to rate-limit incoming ssh connections to 10 new connections within 1 min?”
  • “do you want to allow incoming http? (webserver)”
  • “max connetions per ip: do you want to rate-limit incoming http to 10 concurrent connections per ip?”
  • “max connections within a minute: do you want to rate-limit incoming http to 30 new connections within 1 min?”
  • “do you want to allow https? (ssl(tls) to webserver)”
  • “max connetions per ip: do you want to rate-limit incoming https to 10 concurrent connections per ip?”
  • “max connections within a minute: do you want to rate-limit incoming https to 30 new connections within 1 min?”

what shall a firewall do?: “let good packets go through and keep the bad ones out”

(from the article: firewall-wont-save-you-from-the-next-ddos-attack – that is why data center operaters need the best equipment in this field they can get… (or even write their own (Open Source!) one’s? to protect the users of their datacenters clients from DDoS which almost terroristic attacks because they are also bad for the environment (use a lot of resource/burn a lot of energy/megawatts)).

Anti-DDoS iptables vs nftables discussion on serverfault.com

still rate-limiting (only allow like 10x https connections per ip) can help.

NEVER EVER EVER USE THE WORD “EASY” IN ONE’S ARTICLE!

UNLESS ONE KNOWS HOW TO WRITE A KERNEL DRIVER IN BINARY 0100110010001 CODE! (LINUS TORVALDS SAYS ITS EASY!)

ONE WILL DEMOTIVATE ANYONE WHO CAN NOT WRITE KERNEL DRIVERS IN BINARY 0100110010001 CODE! (ALMOST 99.9%)

KEEP IT UNIX STYLE: K.I.S.S.!

THE BEST WAY FOR MICROSOFT TO DESTROY LINUX AND OPEN SOURCE IS TO MAKE IT SO COMPLICATED, NOBODY CAN AND WILL USE IT (SAME ADOPTION RATE THAN WINDOWS 10 of 0%, it seems one is not alone)

IF MANKIND HATE NFTABLES AND SYSTEMD, IT IS NOT THE FAULT OF MANKIND BUT THE DEVELOPERS THAT DID NOT KISS ENOUGH!

(have no trouble with systemd… because all one wants to do is autostart something here and there… yes and even this has become more complicated from sysvinit to systemd, so one understands all the systemd haters… is this the MICROSOFT CONSPIRACY IN ACTION? or just plain ol’ mankind being stupid and developers being ignorant about user’s needs (a SPECIALTY of MICROSOFT, WIN11 will be EVEN WORSE INTUITIV IN USE THAN WIN10 EVER WAS! HURRAY! (WE WILL COMPLETELY MESS UP ALL THE MENUES THE MICROSOFTIES JUST HAVE GOT USED TO IN A “SHORT” 10 YEAR TRANSITION PERIOD… NOW THEY FINALLY KNOW HOW TO OPEN AND SAVE DOCUMENTS…. AGAIN!))

this is my second take on nftables… and imho will just uninstall it and go back to iptables… seriously who has time for this?

or maybe: the time of low level firewall building are over… and everyone… use firewalld aka the tool that controls the tool that controls the tool or one will never get anything done.

One can even install it under Debian.

once more have to give credits to Linus Torvalds: one hates changes too.

have good backups of one’s remote system before messing with the firewall!

While nftables (unlike iptables) does not disconnect existing connections during reload, it might still lock one out.

 

# tested on
hostnamectl 
   Static hostname: cyclos-dev.info
    Virtualization: kvm
  Operating System: https://www.centos.org/CentOS Linux 8 (Core)
       CPE OS Name: cpe:/o:centos:centos:8
            Kernel: Linux 4.X
      Architecture: x86-64

# list all tables
nft list tables
table ip filter
table ip6 filter
table bridge filter
table ip security
table ip raw
table ip mangle
table ip nat
table ip6 security
table ip6 raw
table ip6 mangle
table ip6 nat
table bridge nat
table inet firewalld
table ip firewalld
table ip6 firewalld

# delete all rules that belong to table foo
# will not flush sets defined within that table
nft flush table ip foo

# delete table foo
nft delete table ip foo

# as in iptables
# one attaches rules to chains
# however in contrary to iptables
# nftables infrastructure comes with no predefined chains
# so one needs to register base chains first
# before one can add rules (this allows very flexible configurations)
nft add chain ip foo input { type filter hook input priority 0 \; }
# this time: semicolon not optional when run in bash
# command registers the input chain "foo"
# that it attached to the input hook so it will see packets that are addressed to the local processes
# order of chains is important:
# if one has several chains in the input hook
# one can decide which one sees packets before another

# create basic chains
nft add table ip filter
nft add chain ip filter input { type filter hook input priority 0 \; }
nft add chain ip filter output { type filter hook output priority 0 \; }

# one can start attaching rules to these two base chains
# note: one do not need the forward chain in this case since it is not a router

# ... ok cut the crap, just ignore all stuff above about nftables and study firewalld:

systemctl list-unit-files|grep firewall
firewalld.service                            enabled

# probably already running
systemctl start firewalld
firewall-cmd --state
running

firewall-cmd --get-default-zone
public

firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens3
  sources: 
  services: cockpit dhcpv6-client http https ssh
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 

firewall-cmd --get-services

RH-Satellite-6 amanda-client amanda-k5-client amqp amqps apcupsd audit bacula bacula-client bgp bitcoin bitcoin-rpc bitcoin-testnet bitcoin-testnet-rpc ceph ceph-mon cfengine cockpit condor-collector ctdb dhcp dhcpv6 dhcpv6-client distcc dns docker-registry docker-swarm dropbox-lansync elasticsearch etcd-client etcd-server finger freeipa-ldap freeipa-ldaps freeipa-replication freeipa-trust ftp ganglia-client ganglia-master git gre high-availability http https imap imaps ipp ipp-client ipsec irc ircs iscsi-target isns jenkins kadmin kerberos kibana klogin kpasswd kprop kshell ldap ldaps libvirt libvirt-tls lightning-network llmnr managesieve matrix mdns minidlna mongodb mosh mountd mqtt mqtt-tls ms-wbt mssql murmur mysql nfs nfs3 nmea-0183 nrpe ntp nut openvpn ovirt-imageio ovirt-storageconsole ovirt-vmconsole plex pmcd pmproxy pmwebapi pmwebapis pop3 pop3s postgresql privoxy proxy-dhcp ptp pulseaudio puppetmaster quassel radius redis rpc-bind rsh rsyncd rtsp salt-master samba samba-client samba-dc sane sip sips slp smtp smtp-submission smtps snmp snmptrap spideroak-lansync squid ssh steam-streaming svdrp svn syncthing syncthing-gui synergy syslog syslog-tls telnet tftp tftp-client tinc tor-socks transmission-client upnp-client vdsm vnc-server wbem-http wbem-https wsman wsmans xdmcp xmpp-bosh xmpp-client xmpp-local xmpp-server zabbix-agent zabbix-server

# allow those services
firewall-cmd --add-service="ssh" --permanent
firewall-cmd --add-service="http" --permanent
firewall-cmd --add-service="https" --permanent
firewall-cmd --reload

# DDoS mitigation for webservers
# block all IPs with more than 30 new connections during 1 minute (60 seconds) to port 80
# src: https://www.certdepot.net/rhel7-mitigate-http-attacks/)
echo "options xt_recent ip_pkt_list_tot=30" > /etc/modprobe.d/xt.conf
modprobe xt_recent
firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT_direct 0 -p tcp --dport 80 -m state --state NEW -m recent --set;
firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT_direct 1 -p tcp --dport 80 -m state --state NEW -m recent --update --seconds 60 --hitcount 30 -j REJECT --reject-with tcp-reset;

# allow only 1 new connection to 443 per second?
firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT_direct 0 -p tcp --dport 443 -m state --state NEW -m recent --set;
firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT_direct 1 -p tcp --dport 443 -m state --state NEW -m recent --update --seconds 60 --hitcount 60 -j REJECT --reject-with tcp-reset;
firewall-cmd --reload;

# lets see if this works for ssh as well
# block all IPs with more than 30 new connections during 1 minute (60 seconds) to port 22
firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT_direct 0 -p tcp --dport 22 -m state --state NEW -m recent --set;
firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT_direct 1 -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 30 -j REJECT --reject-with tcp-reset;
firewall-cmd --reload;

# wtf is this? just print me all pages of the bible in binary will ya?
nft list ruleset
table ip filter {
	chain INPUT {
		type filter hook input priority 0; policy accept;
	}

	chain FORWARD {
		type filter hook forward priority 0; policy accept;
	}

	chain OUTPUT {
		type filter hook output priority 0; policy accept;
	}
}
table ip6 filter {
	chain INPUT {
		type filter hook input priority 0; policy accept;
	}

	chain FORWARD {
		type filter hook forward priority 0; policy accept;
	}

	chain OUTPUT {
		type filter hook output priority 0; policy accept;
	}
}
table bridge filter {
	chain INPUT {
		type filter hook input priority -200; policy accept;
	}

	chain FORWARD {
		type filter hook forward priority -200; policy accept;
	}

	chain OUTPUT {
		type filter hook output priority -200; policy accept;
	}
}
table ip security {
	chain INPUT {
		type filter hook input priority 150; policy accept;
	}

	chain FORWARD {
		type filter hook forward priority 150; policy accept;
	}

	chain OUTPUT {
		type filter hook output priority 150; policy accept;
	}
}
table ip raw {
	chain PREROUTING {
		type filter hook prerouting priority -300; policy accept;
	}

	chain OUTPUT {
		type filter hook output priority -300; policy accept;
	}
}
table ip mangle {
	chain PREROUTING {
		type filter hook prerouting priority -150; policy accept;
	}

	chain INPUT {
		type filter hook input priority -150; policy accept;
	}

	chain FORWARD {
		type filter hook forward priority -150; policy accept;
	}

	chain OUTPUT {
		type route hook output priority -150; policy accept;
	}

	chain POSTROUTING {
		type filter hook postrouting priority -150; policy accept;
	}
}
table ip nat {
	chain PREROUTING {
		type nat hook prerouting priority -100; policy accept;
	}

	chain INPUT {
		type nat hook input priority 100; policy accept;
	}

	chain POSTROUTING {
		type nat hook postrouting priority 100; policy accept;
	}

	chain OUTPUT {
		type nat hook output priority -100; policy accept;
	}
}
table ip6 security {
	chain INPUT {
		type filter hook input priority 150; policy accept;
	}

	chain FORWARD {
		type filter hook forward priority 150; policy accept;
	}

	chain OUTPUT {
		type filter hook output priority 150; policy accept;
	}
}
table ip6 raw {
	chain PREROUTING {
		type filter hook prerouting priority -300; policy accept;
	}

	chain OUTPUT {
		type filter hook output priority -300; policy accept;
	}
}
table ip6 mangle {
	chain PREROUTING {
		type filter hook prerouting priority -150; policy accept;
	}

	chain INPUT {
		type filter hook input priority -150; policy accept;
	}

	chain FORWARD {
		type filter hook forward priority -150; policy accept;
	}

	chain OUTPUT {
		type route hook output priority -150; policy accept;
	}

	chain POSTROUTING {
		type filter hook postrouting priority -150; policy accept;
	}
}
table ip6 nat {
	chain PREROUTING {
		type nat hook prerouting priority -100; policy accept;
	}

	chain INPUT {
		type nat hook input priority 100; policy accept;
	}

	chain POSTROUTING {
		type nat hook postrouting priority 100; policy accept;
	}

	chain OUTPUT {
		type nat hook output priority -100; policy accept;
	}
}
table bridge nat {
	chain PREROUTING {
		type filter hook prerouting priority -300; policy accept;
	}

	chain OUTPUT {
		type filter hook output priority 100; policy accept;
	}

	chain POSTROUTING {
		type filter hook postrouting priority 300; policy accept;
	}
}
table inet firewalld {
	chain raw_PREROUTING {
		type filter hook prerouting priority -290; policy accept;
		icmpv6 type { nd-router-advert, nd-neighbor-solicit } accept
		meta nfproto ipv6 fib saddr . iif oif missing drop
		jump raw_PREROUTING_ZONES_SOURCE
		jump raw_PREROUTING_ZONES
	}

	chain raw_PREROUTING_ZONES_SOURCE {
	}

	chain raw_PREROUTING_ZONES {
		iifname "ens3" goto raw_PRE_public
		goto raw_PRE_public
	}

	chain mangle_PREROUTING {
		type filter hook prerouting priority -140; policy accept;
		jump mangle_PREROUTING_ZONES_SOURCE
		jump mangle_PREROUTING_ZONES
	}

	chain mangle_PREROUTING_ZONES_SOURCE {
	}

	chain mangle_PREROUTING_ZONES {
		iifname "ens3" goto mangle_PRE_public
		goto mangle_PRE_public
	}

	chain filter_INPUT {
		type filter hook input priority 10; policy accept;
		ct state established,related accept
		iifname "lo" accept
		jump filter_INPUT_ZONES_SOURCE
		jump filter_INPUT_ZONES
		ct state invalid drop
		reject with icmpx type admin-prohibited
	}

	chain filter_FORWARD {
		type filter hook forward priority 10; policy accept;
		ct state established,related accept
		iifname "lo" accept
		ip6 daddr { ::/96, ::ffff:0.0.0.0/96, 2002::/24, 2002:a00::/24, 2002:7f00::/24, 2002:a9fe::/32, 2002:ac10::/28, 2002:c0a8::/32, 2002:e000::/19 } reject with icmpv6 type addr-unreachable
		jump filter_FORWARD_IN_ZONES_SOURCE
		jump filter_FORWARD_IN_ZONES
		jump filter_FORWARD_OUT_ZONES_SOURCE
		jump filter_FORWARD_OUT_ZONES
		ct state invalid drop
		reject with icmpx type admin-prohibited
	}

	chain filter_OUTPUT {
		type filter hook output priority 10; policy accept;
		oifname "lo" accept
		ip6 daddr { ::/96, ::ffff:0.0.0.0/96, 2002::/24, 2002:a00::/24, 2002:7f00::/24, 2002:a9fe::/32, 2002:ac10::/28, 2002:c0a8::/32, 2002:e000::/19 } reject with icmpv6 type addr-unreachable
	}

	chain filter_INPUT_ZONES_SOURCE {
	}

	chain filter_INPUT_ZONES {
		iifname "ens3" goto filter_IN_public
		goto filter_IN_public
	}

	chain filter_FORWARD_IN_ZONES_SOURCE {
	}

	chain filter_FORWARD_IN_ZONES {
		iifname "ens3" goto filter_FWDI_public
		goto filter_FWDI_public
	}

	chain filter_FORWARD_OUT_ZONES_SOURCE {
	}

	chain filter_FORWARD_OUT_ZONES {
		oifname "ens3" goto filter_FWDO_public
		goto filter_FWDO_public
	}

	chain raw_PRE_public {
		jump raw_PRE_public_pre
		jump raw_PRE_public_log
		jump raw_PRE_public_deny
		jump raw_PRE_public_allow
		jump raw_PRE_public_post
	}

	chain raw_PRE_public_pre {
	}

	chain raw_PRE_public_log {
	}

	chain raw_PRE_public_deny {
	}

	chain raw_PRE_public_allow {
	}

	chain raw_PRE_public_post {
	}

	chain filter_IN_public {
		jump filter_IN_public_pre
		jump filter_IN_public_log
		jump filter_IN_public_deny
		jump filter_IN_public_allow
		jump filter_IN_public_post
		meta l4proto { icmp, ipv6-icmp } accept
	}

	chain filter_IN_public_pre {
	}

	chain filter_IN_public_log {
	}

	chain filter_IN_public_deny {
	}

	chain filter_IN_public_allow {
		tcp dport ssh ct state new,untracked accept
		ip6 daddr fe80::/64 udp dport dhcpv6-client ct state new,untracked accept
		tcp dport 9090 ct state new,untracked accept
	}

	chain filter_IN_public_post {
	}

	chain filter_FWDI_public {
		jump filter_FWDI_public_pre
		jump filter_FWDI_public_log
		jump filter_FWDI_public_deny
		jump filter_FWDI_public_allow
		jump filter_FWDI_public_post
		meta l4proto { icmp, ipv6-icmp } accept
	}

	chain filter_FWDI_public_pre {
	}

	chain filter_FWDI_public_log {
	}

	chain filter_FWDI_public_deny {
	}

	chain filter_FWDI_public_allow {
	}

	chain filter_FWDI_public_post {
	}

	chain mangle_PRE_public {
		jump mangle_PRE_public_pre
		jump mangle_PRE_public_log
		jump mangle_PRE_public_deny
		jump mangle_PRE_public_allow
		jump mangle_PRE_public_post
	}

	chain mangle_PRE_public_pre {
	}

	chain mangle_PRE_public_log {
	}

	chain mangle_PRE_public_deny {
	}

	chain mangle_PRE_public_allow {
	}

	chain mangle_PRE_public_post {
	}

	chain filter_FWDO_public {
		jump filter_FWDO_public_pre
		jump filter_FWDO_public_log
		jump filter_FWDO_public_deny
		jump filter_FWDO_public_allow
		jump filter_FWDO_public_post
	}

	chain filter_FWDO_public_pre {
	}

	chain filter_FWDO_public_log {
	}

	chain filter_FWDO_public_deny {
	}

	chain filter_FWDO_public_allow {
	}

	chain filter_FWDO_public_post {
	}
}
table ip firewalld {
	chain nat_PREROUTING {
		type nat hook prerouting priority -90; policy accept;
		jump nat_PREROUTING_ZONES_SOURCE
		jump nat_PREROUTING_ZONES
	}

	chain nat_PREROUTING_ZONES_SOURCE {
	}

	chain nat_PREROUTING_ZONES {
		iifname "ens3" goto nat_PRE_public
		goto nat_PRE_public
	}

	chain nat_POSTROUTING {
		type nat hook postrouting priority 110; policy accept;
		jump nat_POSTROUTING_ZONES_SOURCE
		jump nat_POSTROUTING_ZONES
	}

	chain nat_POSTROUTING_ZONES_SOURCE {
	}

	chain nat_POSTROUTING_ZONES {
		oifname "ens3" goto nat_POST_public
		goto nat_POST_public
	}

	chain nat_PRE_public {
		jump nat_PRE_public_pre
		jump nat_PRE_public_log
		jump nat_PRE_public_deny
		jump nat_PRE_public_allow
		jump nat_PRE_public_post
	}

	chain nat_PRE_public_pre {
	}

	chain nat_PRE_public_log {
	}

	chain nat_PRE_public_deny {
	}

	chain nat_PRE_public_allow {
	}

	chain nat_PRE_public_post {
	}

	chain nat_POST_public {
		jump nat_POST_public_pre
		jump nat_POST_public_log
		jump nat_POST_public_deny
		jump nat_POST_public_allow
		jump nat_POST_public_post
	}

	chain nat_POST_public_pre {
	}

	chain nat_POST_public_log {
	}

	chain nat_POST_public_deny {
	}

	chain nat_POST_public_allow {
	}

	chain nat_POST_public_post {
	}
}
table ip6 firewalld {
	chain nat_PREROUTING {
		type nat hook prerouting priority -90; policy accept;
		jump nat_PREROUTING_ZONES_SOURCE
		jump nat_PREROUTING_ZONES
	}

	chain nat_PREROUTING_ZONES_SOURCE {
	}

	chain nat_PREROUTING_ZONES {
		iifname "ens3" goto nat_PRE_public
		goto nat_PRE_public
	}

	chain nat_POSTROUTING {
		type nat hook postrouting priority 110; policy accept;
		jump nat_POSTROUTING_ZONES_SOURCE
		jump nat_POSTROUTING_ZONES
	}

	chain nat_POSTROUTING_ZONES_SOURCE {
	}

	chain nat_POSTROUTING_ZONES {
		oifname "ens3" goto nat_POST_public
		goto nat_POST_public
	}

	chain nat_PRE_public {
		jump nat_PRE_public_pre
		jump nat_PRE_public_log
		jump nat_PRE_public_deny
		jump nat_PRE_public_allow
		jump nat_PRE_public_post
	}

	chain nat_PRE_public_pre {
	}

	chain nat_PRE_public_log {
	}

	chain nat_PRE_public_deny {
	}

	chain nat_PRE_public_allow {
	}

	chain nat_PRE_public_post {
	}

	chain nat_POST_public {
		jump nat_POST_public_pre
		jump nat_POST_public_log
		jump nat_POST_public_deny
		jump nat_POST_public_allow
		jump nat_POST_public_post
	}

	chain nat_POST_public_pre {
	}

	chain nat_POST_public_log {
	}

	chain nat_POST_public_deny {
	}

	chain nat_POST_public_allow {
	}

	chain nat_POST_public_post {
	}
}

Links:

src: https://wiki.nftables.org/wiki-nftables/index.php/Configuring_tables

https://wiki.nftables.org/wiki-nftables/index.php/Configuring_chains

faster higher wider X-D https://www.zevenet.com/blog/nftables-load-balancing-10x-faster-lvs/

tweets:

https://twitter.com/search?q=%23Nftables

videos:

2016: Workshop Getting a Practical Grasp of nftables – Pablo Neira Ayuso

bad audio but at least in ENGLISH: nftables: The ultimate packet classifier for GNU/Linux – Barcelona Free Software why something new?

nftables – the evolution of linux firewalls – in Portugese? (GUYS! ENGLISH!!! DAMN IT! X-D)

admin