nftables module: Add new module for nftables firewall settings
fixes #18842
This commit is contained in:
		
							parent
							
								
									b508c1b792
								
							
						
					
					
						commit
						e2c95b46e5
					
				@ -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
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										174
									
								
								nixos/modules/services/networking/nftables.nix
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										174
									
								
								nixos/modules/services/networking/nftables.nix
									
									
									
									
									
										Normal 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";
 | 
			
		||||
      };
 | 
			
		||||
    };
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user