summary refs log tree commit diff
path: root/nixos/modules/services/networking/nftables.nix
diff options
context:
space:
mode:
authorJookia <166291@gmail.com>2016-09-22 15:45:42 +1000
committerJörg Thalheim <joerg@thalheim.io>2017-02-26 13:41:14 +0100
commite2c95b46e5fbd9f28cc7714802f9cd3b632fd979 (patch)
tree2dbcea239edee3277f4b44f54eaeb473ead57479 /nixos/modules/services/networking/nftables.nix
parentb508c1b7926bc8f63c70ca696dcb4e9dcddbd6ee (diff)
downloadnixpkgs-e2c95b46e5fbd9f28cc7714802f9cd3b632fd979.tar
nixpkgs-e2c95b46e5fbd9f28cc7714802f9cd3b632fd979.tar.gz
nixpkgs-e2c95b46e5fbd9f28cc7714802f9cd3b632fd979.tar.bz2
nixpkgs-e2c95b46e5fbd9f28cc7714802f9cd3b632fd979.tar.lz
nixpkgs-e2c95b46e5fbd9f28cc7714802f9cd3b632fd979.tar.xz
nixpkgs-e2c95b46e5fbd9f28cc7714802f9cd3b632fd979.tar.zst
nixpkgs-e2c95b46e5fbd9f28cc7714802f9cd3b632fd979.zip
nftables module: Add new module for nftables firewall settings
fixes #18842
Diffstat (limited to 'nixos/modules/services/networking/nftables.nix')
-rw-r--r--nixos/modules/services/networking/nftables.nix174
1 files changed, 174 insertions, 0 deletions
diff --git a/nixos/modules/services/networking/nftables.nix b/nixos/modules/services/networking/nftables.nix
new file mode 100644
index 00000000000..54cbba4937c
--- /dev/null
+++ b/nixos/modules/services/networking/nftables.nix
@@ -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";
+      };
+    };
+  };
+}