firewall & the GNU-Linux Pinguin: firewalls: where do thy go? and does thee protect from DDoS?
as always in software development and as always in GNU Linux, there is not “one” firewall system, no, there are many and it is an ongoing development to find “the best” solution:
it is said that when using “ip-sets” iptables and nftables achieve almost same performance (amounts of ips possible to block, without server becoming slow/unresponsive)
Redhat and nftables on DDoS “so the only thing to fall back to is establishing a blacklist for all the different source IP addresses” (src) (which is exactly what iptables + cron + autoban.sh a simple bash script does)
status quo: GNU Linux Versions and default-firewalls:
- Debian 11 default firewall is: bpfilter (but it might get removed from the kernel soon)
- Ubuntu 20 default firewall is: ufw (for managing netfilter)
- Fedora/RedHat/CentOS: firewalld (also for managing netfilter)
the #3rd concept: bpfilter
2018-02: “The Linux kernel currently supports two separate network packet-filtering mechanisms: iptables and nftables.
For the last few years, it has been generally assumed that nftables would eventually replace the older iptables implementation;
few people expected that the kernel developers would, instead, add a third packet filter.
But that would appear to be what is happening with the newly announced bpfilter mechanism.
Bpfilter may eventually replace both iptables and nftables, but there are a lot of questions that will need to be answered first.” (src: https://lwn.net/Articles/747551/)
an interesting concept: bptables, let the NETWORK CARD ITSELF do the filtering! (packages never reach the CPU) (Smart NIC such as the “Netronome Agilio CX SmartNIC” is a hardware-requirement)
they got even more videos: https://www.youtube.com/c/netronome/videos
(great, great, human brain has highest bandwidth capacity in the audio-visual sector so: always good to use the audio-visual input for documentation, only disadvantage: if something changes, the audio-video-documentation is hard to change (would have to be re-done or re-edited))
even faster X-D https://cilium.io/blog/2018/04/17/why-is-the-kernel-community-replacing-iptables/
and: will already established iptables scripts keep on working?
“We like iptables after all, this tool has been serving us (and will likely keep serving still for a while in many deployments) to filter out traffic on both per-packet and per-flow basis, log suspicious traffic activity, perform NAT and many other things.
It comes with more than a hundred of extensions that have been contributed along the last 15 years!.
Nevertheless, the iptables framework suffers from limitations that cannot be easily worked around:
- Avoid code duplication and inconsistencies:
- Many of the iptables extensions are protocol specific
- so there is no a consolidated way to match packet fields
- instead there is one extension for each protocol that it supports
- this bloats the codebase with very similar code to perform a similar task: payload matching
- Faster packet classification through enhanced generic set and map infrastructure
- Simplified dual stack IPv4/IPv6 administration, through the new inet family that allows you to register base chains that see both IPv4 and IPv6 traffic
- Better dynamic ruleset updates support
- Provide a Netlink API for third party applications, just as other Linux Networking and Netfilter subsystem do
- Address syntax inconsistencies and provide nicer and more compact syntax (aha aha X-D)
These, among other things not listed here, triggered the nftables development which was originally presented to the Netfilter community in the 6th Netfilter Workshop in Paris (2008, France).” (src: wiki.nftables.org)
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%)
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)
liked this article?
- only together we can create a truly free world
- plz support dwaves to keep it up & running!
- (yes the info on the internet is (mostly) free but beer is still not free (still have to work on that))
- really really hate advertisement
- contribute: whenever a solution was found, blog about it for others to find!
- talk about, recommend & link to this blog and articles
- thanks to all who contribute!