aboutsummaryrefslogtreecommitdiff
path: root/nixpkgs/nixos/modules/services/networking/nftables.nix
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/nixos/modules/services/networking/nftables.nix')
-rw-r--r--nixpkgs/nixos/modules/services/networking/nftables.nix136
1 files changed, 136 insertions, 0 deletions
diff --git a/nixpkgs/nixos/modules/services/networking/nftables.nix b/nixpkgs/nixos/modules/services/networking/nftables.nix
new file mode 100644
index 00000000000..ad7c013a544
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/networking/nftables.nix
@@ -0,0 +1,136 @@
+{ 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.
+
+ Note that if you have Docker enabled you will not be able to use
+ nftables without intervention. Docker uses iptables internally to
+ setup NAT for containers. This module disables the ip_tables kernel
+ module, however Docker automatically loads the module. Please see [1]
+ for more information.
+
+ There are other programs that use iptables internally too, such as
+ libvirt.
+
+ [1]: https://github.com/NixOS/nixpkgs/issues/24318#issuecomment-289216273
+ '';
+ };
+ networking.nftables.ruleset = mkOption {
+ type = types.lines;
+ example = ''
+ # Check out https://wiki.nftables.org/ for better documentation.
+ # Table for both IPv4 and IPv6.
+ table inet filter {
+ # Block all incomming 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 icmp 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
+ }
+ }
+ '';
+ 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.runtimeShell} -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";
+ };
+ };
+ };
+}