zigford.org

About | Links | Scripts
Sharing linux/windows scripts and tips

Firewalld kernel requirements

March 06, 2020 — Jesse Harris

I wanted to work out the minimum kernel requirements to run Firewalld with nftables backend running in Gentoo. Here I've documented my findings.


Update 30th September 2021

Alex kindly wrote in to correct a few typos in this post. Many thanks Alex!

Update

After running with this config a couple of days I finally got to starting a vm under libvirtd which failed miserably. Additional modules required:

        CONFIG_NETFILTER_INGRESS=y
        CONFIG_NF_CONNTRACK_TFTP=m
        CONFIG_NF_NAT_TFTP=m
        CONFIG_NETFILTER_XT_NAT=m
        CONFIG_NETFILTER_XT_TARGET_MASQUERADE=m
        CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
        CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
        CONFIG_NETFILTER_XT_MATCH_STATE=m
        CONFIG_IP_NF_FILTER=m
        CONFIG_IP_NF_TARGET_REJECT=m
        CONFIG_IP_NF_NAT=m
        CONFIG_IP_NF_TARGET_MASQUERADE=m
        CONFIG_IP_NF_MANGLE=m
        CONFIG_IP6_NF_FILTER=m
        CONFIG_IP6_NF_TARGET_REJECT=m
        CONFIG_IP6_NF_MANGLE=m
        CONFIG_IP6_NF_NAT=m
        CONFIG_IP6_NF_TARGET_MASQUERADE=m

Original post

My laptop is running Gentoo with luks/dmcrypt encrypted root/home, btrfs hourly snapshots and backed up to an encrypted external drive, systemd and linux kernel 5.4. The last step in becoming a fully secure enterprise desktop is the firewall.

For a time I ran my own iptables script, but that quickly became difficult to manage when libvirtd (managing my VMs for KVM) would add rules overtop and make an ugly mess in the iptables.

nftables is the modern replacement to iptables and I had tried to merge firewalld onto my system in the past with horrible results. The problem has always being identifying the correct kernel configuration. Firewalld ebuild itself identifies a few components, but even those are not correct

Sometimes the wrong configuration combination would lead to the system not booting or nftables hanging. After much trial and error I've found the right combo. If you don't want to read about which config options solve which problem, I'll provide a list of all required configurations at the end.

The base

The following options got me a bootable kernel and firewalld attempting to start

        CONFIG_NETFILTER_ADVANCED=y
        CONFIG_NETFILTER_NETLINK=m
        CONFIG_NF_CONNTRACK=m
        CONFIG_NF_TABLES=m
        CONFIG_NFT_CT=m
        CONFIG_NF_DEFRAG_IPV4=m
        CONFIG_NF_DEFRAG_IPV6=m
        CONFIG_NF_CT_NETLINK=m
        CONFIG_NF_NAT=m
        CONFIG_NFT_NAT=m
        CONFIG_NETFILTER_XTABLES=m
        CONFIG_IP_SET=m
        CONFIG_IP_SET_MAX=256
        CONFIG_NF_TABLES_IPV4=y
        CONFIG_IP_NF_IPTABLES=m
        CONFIG_IP_NF_RAW=m
        CONFIG_IP_NF_SECURITY=m
        CONFIG_NF_TABLES_IPV6=y
        CONFIG_IP6_NF_IPTABLES=m
        CONFIG_IP6_NF_RAW=m
        CONFIG_IP6_NF_SECURITY=m

The errors

After booting up and starting firewalld, I checked the status of the service and was greeted with this:

ERROR: '/sbin/nft add chain inet firewalld raw_PREROUTING { type filter hook prerouting priority -290 ; }' \
    failed: Error: Could not process rule: Operation not supported

Which was solved with CONFIG_NF_TABLES_INET=y

After a kernel recompile and reboot, I checked the status of the firewalld service and found that the nft command had hung. It was stuck on the following command line:

/sbin/nft --echo --handle add rule inet firewalld filter_INPUT reject with icmpx type admin-prohibited

This took a lot of trial and error but boiled down to the following configurations:

        CONFIG_NFT_REJECT=m
        CONFIG_NFT_REJECT_INET=m
        CONFIG_NFT_REJECT_IPV4=m
        CONFIG_NF_REJECT_IPV4=m
        CONFIG_NFT_REJECT_IPV6=m
        CONFIG_NF_REJECT_IPV6=m

As the previous fix only required new modules, I was able to simple restart the service to see the next problem. Again, another hung nft command line:

/sbin/nft --echo --handle insert rule inet firewalld raw_PREROUTING meta nfproto ipv6 fib saddr . \
    iif oif missing drop

And again, hours of trial and error

        CONFIG_NFT_FIB=m
        CONFIG_NFT_FIB_INET=m
        CONFIG_NFT_FIB_IPV4=m
        CONFIG_NFT_FIB_IPV6=m

Again, restart the service to find another hung command line:

ERROR: '/sbin/nft insert rule inet firewalld raw_PREROUTING icmpv6 type \
    { nd-router-advert, nd-neighbor-solicit } accept

This time, a single module needed to be compiled: CONFIG_NF_TABLES_SET=m

Finally the last hang was the following command line:

/sbin/nft --echo --handle add rule inet firewalld filter_IN_home_allow udp dport 137 ct helper set \
    "helper-netbios-ns-udp"

This one took the longest to solve and contains the most configurations of any fix:

        CONFIG_NETFILTER_NETLINK_QUEUE=m
        CONFIG_NETFILTER_NETLINK_OSF=m
        CONFIG_NETFILTER_CONNCOUNT=m
        CONFIG_NF_CT_NETLINK_HELPER=m
        CONFIG_NETFILTER_NETLINK_GLUE_CT=y
        CONFIG_NF_NAT_REDIRECT=y
        CONFIG_NF_NAT_MASQUERADE=y
        CONFIG_NETFILTER_SYNPROXY=m
        CONFIG_NFT_COUNTER=m
        CONFIG_NFT_CONNLIMIT=m
        CONFIG_NFT_LOG=m
        CONFIG_NFT_LIMIT=m
        CONFIG_NFT_MASQ=m
        CONFIG_NFT_REDIR=m
        CONFIG_NFT_TUNNEL=m
        CONFIG_NFT_OBJREF=m
        CONFIG_NFT_QUEUE=m
        CONFIG_NFT_QUOTA=m
        CONFIG_NFT_COMPAT=m
        CONFIG_NFT_HASH=m
        CONFIG_NFT_XFRM=m
        CONFIG_NFT_SOCKET=m
        CONFIG_NFT_OSF=m
        CONFIG_NFT_TPROXY=m
        CONFIG_NFT_SYNPROXY=m
        CONFIG_NETFILTER_XT_CONNMARK=m
        CONFIG_NF_SOCKET_IPV4=m
        CONFIG_NF_TPROXY_IPV4=m
        CONFIG_NF_SOCKET_IPV6=m
        CONFIG_NF_TPROXY_IPV6=m

Some of those may not have been totally nessecary, but I was getting tired and just enabled the main nft modules.

The final total config

My complete kernel can be found here but here are the nftables bits in their entirity.

        CONFIG_NETFILTER_ADVANCED=y
        CONFIG_NETFILTER_NETLINK=m
        CONFIG_NF_CONNTRACK=m
        CONFIG_NF_TABLES=m
        CONFIG_NFT_CT=m
        CONFIG_NF_DEFRAG_IPV4=m
        CONFIG_NF_DEFRAG_IPV6=m
        CONFIG_NF_CT_NETLINK=m
        CONFIG_NF_NAT=m
        CONFIG_NFT_NET=m
        CONFIG_NETFILTER_XTABLES=m
        CONFIG_IP_SET=m
        CONFIG_IP_SET_MAX=256
        CONFIG_NF_TABLES_IPV4=y
        CONFIG_IP_NF_IPTABLES=m
        CONFIG_IP_NF_RAW=m
        CONFIG_IP_NF_SECURITY=m
        CONFIG_NF_TABLES_IPV6=y
        CONFIG_IP6_NF_IPTABLES=m
        CONFIG_IP6_NF_RAW=m
        CONFIG_IP6_NF_SECURITY=m
        CONFIG_NF_TABLES_INET=y
        CONFIG_NFT_REJECT=m
        CONFIG_NFT_REJECT_INET=m
        CONFIG_NFT_REJECT_IPV4=m
        CONFIG_NF_REJECT_IPV4=m
        CONFIG_NFT_REJECT_IPV6=m
        CONFIG_NF_REJECT_IPV6=m
        CONFIG_NFT_FIB=m
        CONFIG_NFT_FIB_INET=m
        CONFIG_NFT_FIB_IPV4=m
        CONFIG_NFT_FIB_IPV6=m
        CONFIG_NF_TABLES_SET=m
        CONFIG_NF_CONNTRACK_BROADCAST=m
        CONFIG_NF_CONNTRACK_NETBIOS=m

Note In my case I've configured many options as modules, but it should also be fine to include them in the kernel as =y

Tags: gentoo, linux, firewalld