nftables module: Add new module for nftables firewall settings

fixes #18842
This commit is contained in:
Jookia 2016-09-22 15:45:42 +10:00 committed by Jörg Thalheim
parent b508c1b792
commit e2c95b46e5
No known key found for this signature in database
GPG Key ID: CA4106B8D7CC79FA
2 changed files with 175 additions and 0 deletions

View File

@ -427,6 +427,7 @@
./services/networking/namecoind.nix
./services/networking/nat.nix
./services/networking/networkmanager.nix
./services/networking/nftables.nix
./services/networking/ngircd.nix
./services/networking/nix-serve.nix
./services/networking/nntp-proxy.nix

View File

@ -0,0 +1,174 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.networking.nftables;
in
{
###### interface
options = {
networking.nftables.enable = mkOption {
type = types.bool;
default = false;
description =
''
Whether to enable nftables. nftables is a Linux-based packet
filtering framework intended to replace frameworks like iptables.
This conflicts with the standard networking firewall, so make sure to
disable it before using nftables.
'';
};
networking.nftables.ruleset = mkOption {
type = types.lines;
default =
''
table inet filter {
# Block all IPv4/IPv6 input traffic except SSH.
chain input {
type filter hook input priority 0;
ct state invalid reject
ct state {established, related} accept
iifname lo accept
tcp dport 22 accept
reject
}
# Allow anything in.
chain output {
type filter hook output priority 0;
ct state invalid reject
ct state {established, related} accept
oifname lo accept
accept
}
chain forward {
type filter hook forward priority 0;
accept
}
}
'';
example =
''
# Check out http://wiki.nftables.org/ for better documentation.
define LAN = 192.168.0.1/24
# Handle IPv4 traffic.
table ip filter {
chain input {
type filter hook input priority 0;
# Handle existing connections.
ct state invalid reject
ct state {established, related} accept
# Allow loopback for applications.
iifname lo accept
# Allow people to ping us on LAN.
ip protocol icmp ip daddr $LAN accept
# Allow SSH over LAN.
tcp dport 22 ip daddr $LAN accept
# Reject all other output traffic.
reject
}
chain output {
type filter hook output priority 0;
# Handle existing connections.
ct state invalid reject
ct state {established, related} accept
# Allow loopback for applications.
oifname lo accept
# Allow the Tor user to run its daemon,
# but only on WAN in case of compromise.
skuid tor ip daddr != $LAN accept
# Allowing pinging others on LAN.
ip protocol icmp ip daddr $LAN accept
# Reject all other output traffic.
reject
}
chain forward {
type filter hook forward priority 0;
reject
}
}
# Block all IPv6 traffic.
table ip6 filter {
chain input {
type filter hook input priority 0;
reject
}
chain output {
type filter hook output priority 0;
reject
}
chain forward {
type filter hook forward priority 0;
reject
}
}
'';
description =
''
The ruleset to be used with nftables. Should be in a format that
can be loaded using "/bin/nft -f". The ruleset is updated atomically.
'';
};
networking.nftables.rulesetFile = mkOption {
type = types.path;
default = pkgs.writeTextFile {
name = "nftables-rules";
text = cfg.ruleset;
};
description =
''
The ruleset file to be used with nftables. Should be in a format that
can be loaded using "nft -f". The ruleset is updated atomically.
'';
};
};
###### implementation
config = mkIf cfg.enable {
assertions = [{
assertion = config.networking.firewall.enable == false;
message = "You can not use nftables with services.networking.firewall.";
}];
boot.blacklistedKernelModules = [ "ip_tables" ];
environment.systemPackages = [ pkgs.nftables ];
systemd.services.nftables = {
description = "nftables firewall";
before = [ "network-pre.target" ];
wants = [ "network-pre.target" ];
wantedBy = [ "multi-user.target" ];
reloadIfChanged = true;
serviceConfig = let
rulesScript = pkgs.writeScript "nftables-rules" ''
#! ${pkgs.nftables}/bin/nft -f
flush ruleset
include "${cfg.rulesetFile}"
'';
checkScript = pkgs.writeScript "nftables-check" ''
#! ${pkgs.stdenv.shell} -e
if $(${pkgs.kmod}/bin/lsmod | grep -q ip_tables); then
echo "Unload ip_tables before using nftables!" 1>&2
exit 1
else
${rulesScript}
fi
'';
in {
Type = "oneshot";
RemainAfterExit = true;
ExecStart = checkScript;
ExecReload = checkScript;
ExecStop = "${pkgs.nftables}/bin/nft flush ruleset";
};
};
};
}