Skip to content

Commit

Permalink
networking/nftables: add .tables property and disable ruleset flushin…
Browse files Browse the repository at this point in the history
…g by default

This allows for other unmanaged tables to co-exist peacefully on the os,
by having the nixos-managed tables be re-created atomically and the other
tables will simply be left untouched.
  • Loading branch information
mkg20001 committed Dec 26, 2022
1 parent e91a59e commit 2020012
Showing 1 changed file with 93 additions and 1 deletion.
94 changes: 93 additions & 1 deletion nixos/modules/services/networking/nftables.nix
Expand Up @@ -2,6 +2,35 @@
with lib;
let
cfg = config.networking.nftables;

tableSubmodule = { name, ... }: {
options = {
enable = mkOption {
type = types.bool;
default = true;
description = lib.mdDoc "Enable this table.";
};

name = mkOption {
type = types.str;
description = lib.mdDoc "Table name.";
};

content = mkOption {
type = types.lines;
description = lib.mdDoc "The table content.";
};

family = mkOption {
description = lib.mdDoc "Table family.";
type = types.enum [ "ip" "ip6" "inet" "arp" "bridge" "netdev" ];
};
};

config = {
name = mkDefault name;
};
};
in
{
###### interface
Expand Down Expand Up @@ -90,6 +119,62 @@ in
This option conflicts with ruleset and nftables based firewall.
'';
};
networking.nftables.tables = mkOption {
type = types.attrsOf (types.submodule tableSubmodule);

default = {};

description = lib.mdDoc ''
Tables to be added to ruleset.
Tables will be added together with delete statements to clean up the table before every update.
'';

example = {
filter = {
family = "inet";
content = ''
# Check out https://wiki.nftables.org/ for better documentation.
# Table for both IPv4 and IPv6.
# Block all incoming connections traffic except SSH and "ping".
chain input {
type filter hook input priority 0;
# accept any localhost traffic
iifname lo accept
# accept traffic originated from us
ct state {established, related} accept
# ICMP
# routers may also want: mld-listener-query, nd-router-solicit
ip6 nexthdr icmpv6 icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept
ip protocol icmp icmp type { destination-unreachable, router-advertisement, time-exceeded, parameter-problem } accept
# allow "ping"
ip6 nexthdr icmpv6 icmpv6 type echo-request accept
ip protocol icmp icmp type echo-request accept
# accept SSH connections (required for a server)
tcp dport 22 accept
# count and drop any other traffic
counter drop
}
# Allow all outgoing connections.
chain output {
type filter hook output priority 0;
accept
}
chain forward {
type filter hook forward priority 0;
accept
}
'';
};
};
};
};

###### implementation
Expand All @@ -105,9 +190,16 @@ in
wantedBy = [ "multi-user.target" ];
reloadIfChanged = true;
serviceConfig = let
enabledTables = filterAttrs (_: table: table.enable) cfg.tables;
rulesScript = pkgs.writeScript "nftables-rules" ''
#! ${pkgs.nftables}/bin/nft -f
flush ruleset
${concatStringsSep "\n" (mapAttrsToList (_: table: ''
table ${table.family} ${table.name}
delete table ${table.family} ${table.name}
table ${table.family} ${table.name} {
${table.content}
}
'') enabledTables)}
${if cfg.rulesetFile != null then ''
include "${cfg.rulesetFile}"
'' else cfg.ruleset}
Expand Down

0 comments on commit 2020012

Please sign in to comment.