Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nixos/nftables: check ruleset syntax during build #48201

Closed
wants to merge 1 commit into from

Conversation

lschuermann
Copy link
Member

Motivation for this change

The nftables ruleset syntax should be verified during build to avoid misconfiguration.

If the file is not syntactically valid, currently, the ruleset would be flushed without the new (incorrect) rules being applied, leaving the firewall in its default configuration (accept everything).
Apparently, nft has become clever enough to not overwrite the old ruleset in case of a syntax error. However, the system configuration is still built and applied.

Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nox --run "nox-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Fits CONTRIBUTING.md.

There are now two files with similar names: nftables-rules-checked and nftables-check. In my opinion, the nftables-check file (which is actually the service start script) has a pretty bad name. This could be changed to something more meaningful to avoid confusion.

# Check whether the file is syntactically valid
checkedRulesetFile = pkgs.runCommand "nftables-rules-checked"
{ src = cfg.rulesetFile; }
''${pkgs.nftables}/bin/nft -c -f "$src" && cp $src $out'';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this check attempt to resolve hostnames or network interfaces? This will not work inside sandboxes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also loading port/service names from /etc/protocol or /etc/services would be a problem.

Copy link
Member

@Mic92 Mic92 Oct 11, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It also requires root because it open a netlink connection.

$ cat foo.nft
  table inet filter {
    chain input {
      type filter hook input priority 0;
      ct state established,related accept
      iif lo accept
      # ssh
      tcp dport {22, 22022} accept
    }
  }
$ nft -c -f foo.nft
foo.nft:1:1-2: Error: Could not process rule: Operation not permitted
table inet filter {
^^
foo.nft:2:9-13: Error: Could not process rule: Operation not permitted
  chain input {
        ^^^^^
foo.nft:7:15-25: Error: Could not process rule: Operation not permitted
    tcp dport {22, 22022} accept
              ^^^^^^^^^^^
foo.nft:4:5-39: Error: Could not process rule: Operation not permitted
    ct state established,related accept
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
foo.nft:5:5-17: Error: Could not process rule: Operation not permitted
    iif lo accept
    ^^^^^^^^^^^^^
foo.nft:7:5-32: Error: Could not process rule: Operation not permitted
    tcp dport {22, 22022} accept
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, that really seems to be a deal-breaker. I'll check whether these problems can be avoided somehow. If not, we should do the check in the systemd start script at least, as trying to load a broken ruleset is not very elegant.

Copy link
Member

@Mic92 Mic92 Oct 11, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had a look at the source code: In the current state I don't how this can work without root, which we not have at build time.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this check attempt to resolve hostnames or network interfaces? This will not work inside sandboxes.

Also loading port/service names from /etc/protocol or /etc/services would be a problem.

I'd say that this isn't really an issue, as long as we would provide an option to disable the checks. Many people probably don't use these features.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, that really seems to be a deal-breaker.

It is. I could look into creating some nft -c alternative, that doesn't resolve protocols, domains and require a netlink connection, but this will have to wait for a few months. I'll reopen this PR as soon as I've figured something out.

Please excuse the broken PR. :(

@lschuermann lschuermann deleted the nftables-syntax-check branch October 14, 2018 09:24
@lschuermann lschuermann restored the nftables-syntax-check branch October 19, 2018 09:05
@lschuermann lschuermann deleted the nftables-syntax-check branch October 25, 2019 08:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants