Skip to content

fix: detect a native nftables ruleset in the firewall policy checks - #366

Open
nicodarge wants to merge 1 commit into
ovh:masterfrom
nicodarge:fix_net_fw_default_policy_drop_nftables
Open

fix: detect a native nftables ruleset in the firewall policy checks#366
nicodarge wants to merge 1 commit into
ovh:masterfrom
nicodarge:fix_net_fw_default_policy_drop_nftables

Conversation

@nicodarge

Copy link
Copy Markdown
Contributor

Problem

net_fw_default_policy_drop (3.5.4.1.1) only read the iptables chains. A host that filters with nftables and does not have the iptables package installed at all was reported as having no default DROP policy, even with policy drop set on both the input and forward hooks.

While fixing it, three parsing defects showed up in the other nftables checks, which matched hook names with grep 'hook input' and awk '/hook input/,/}/':

  • The bridge and arp families were counted as IP filtering. nftables reuses the input, output and forward hook names in those families for a packet path that carries neither routed nor locally delivered IP traffic. A host whose IP traffic was not filtered at all could pass on the strength of a bridge policy.
  • A policy declared on a line of its own was missed. Only the type filter hook ... line was scanned, so the valid form below was read as the implicit accept, failing a compliant host:
    chain input {
        type filter hook input priority 0;
        policy drop;
    }
    
  • The chain body stopped at the first closing brace. A rule holding a brace of its own, such as tcp dport { 22, 80 } accept, truncated the body, hiding the rules that followed from nftables_loopback_is_configured and nftables_established_connections.

Change

Two helpers in lib/utils.sh, nft_ip_base_chains and nft_ip_hook_policies, now do the parsing for all six checks. They keep only the ip, ip6 and inet families, count braces to delimit a chain, treat a base chain declared without a policy as accept, and also understand the flat add chain ... syntax a hand-written persistent rules file may use.

For net_fw_default_policy_drop, a chain is compliant as soon as one of the two backends denies: an accept verdict does not end the traversal of a hook, so a single base chain set to drop is enough. Each ruleset is now read once per audit instead of once per assertion.

The addition to lib/utils.sh is purely additive, so no other script is affected.

Tests

tests/hardening/nftables_rules_permanent.sh was asserting on a file containing the literal lines hook input / hook output / hook forward, which only ever passed because of the awk range. It now uses a real ruleset, plus a bridge-only case that must fail.

net_fw_default_policy_drop, nftables_default_deny_policy and nftables_has_base_chains gained cases covering a bridge-only ruleset and a compliant IP one. They are guarded on nft list ruleset succeeding, since reading and writing a ruleset needs CAP_NET_ADMIN, which the test container does not have — they skip in CI and were run locally with the capability granted, on debian11, debian12 and debian13.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants