1 { config, lib, pkgs, ... }:
4 cfg = config.networking.firewall;
7 ports: lib.unique (builtins.sort builtins.lessThan ports);
10 allowedTCPPorts = lib.mkOption {
11 type = lib.types.listOf lib.types.port;
13 apply = canonicalizePortList;
16 List of TCP ports on which incoming connections are
21 allowedTCPPortRanges = lib.mkOption {
22 type = lib.types.listOf (lib.types.attrsOf lib.types.port);
24 example = [{ from = 8999; to = 9003; }];
26 A range of TCP ports on which incoming connections are
31 allowedUDPPorts = lib.mkOption {
32 type = lib.types.listOf lib.types.port;
34 apply = canonicalizePortList;
37 List of open UDP ports.
41 allowedUDPPortRanges = lib.mkOption {
42 type = lib.types.listOf (lib.types.attrsOf lib.types.port);
44 example = [{ from = 60000; to = 61000; }];
46 Range of open UDP ports.
57 networking.firewall = {
58 enable = lib.mkOption {
59 type = lib.types.bool;
62 Whether to enable the firewall. This is a simple stateful
63 firewall that blocks connection attempts to unauthorised TCP
64 or UDP ports on this machine.
68 package = lib.mkOption {
69 type = lib.types.package;
70 default = if config.networking.nftables.enable then pkgs.nftables else pkgs.iptables;
71 defaultText = lib.literalExpression ''if config.networking.nftables.enable then "pkgs.nftables" else "pkgs.iptables"'';
72 example = lib.literalExpression "pkgs.iptables-legacy";
74 The package to use for running the firewall service.
78 logRefusedConnections = lib.mkOption {
79 type = lib.types.bool;
82 Whether to log rejected or dropped incoming connections.
83 Note: The logs are found in the kernel logs, i.e. dmesg
88 logRefusedPackets = lib.mkOption {
89 type = lib.types.bool;
92 Whether to log all rejected or dropped incoming packets.
93 This tends to give a lot of log messages, so it's mostly
95 Note: The logs are found in the kernel logs, i.e. dmesg
100 logRefusedUnicastsOnly = lib.mkOption {
101 type = lib.types.bool;
104 If {option}`networking.firewall.logRefusedPackets`
105 and this option are enabled, then only log packets
106 specifically directed at this machine, i.e., not broadcasts
111 rejectPackets = lib.mkOption {
112 type = lib.types.bool;
115 If set, refused packets are rejected rather than dropped
116 (ignored). This means that an ICMP "port unreachable" error
117 message is sent back to the client (or a TCP RST packet in
118 case of an existing connection). Rejecting packets makes
119 port scanning somewhat easier.
123 trustedInterfaces = lib.mkOption {
124 type = lib.types.listOf lib.types.str;
126 example = [ "enp0s2" ];
128 Traffic coming in from these interfaces will be accepted
129 unconditionally. Traffic from the loopback (lo) interface
130 will always be accepted.
134 allowPing = lib.mkOption {
135 type = lib.types.bool;
138 Whether to respond to incoming ICMPv4 echo requests
139 ("pings"). ICMPv6 pings are always allowed because the
140 larger address space of IPv6 makes network scanning much
145 pingLimit = lib.mkOption {
146 type = lib.types.nullOr (lib.types.separatedString " ");
148 example = "--limit 1/minute --limit-burst 5";
150 If pings are allowed, this allows setting rate limits on them.
152 For the iptables based firewall, it should be set like
153 "--limit 1/minute --limit-burst 5".
155 For the nftables based firewall, it should be set like
156 "2/second" or "1/minute burst 5 packets".
160 checkReversePath = lib.mkOption {
161 type = lib.types.either lib.types.bool (lib.types.enum [ "strict" "loose" ]);
163 defaultText = lib.literalMD "`true` except if the iptables based firewall is in use and the kernel lacks rpfilter support";
166 Performs a reverse path filter test on a packet. If a reply
167 to the packet would not be sent via the same interface that
168 the packet arrived on, it is refused.
170 If using asymmetric routing or other complicated routing, set
171 this option to loose mode or disable it and setup your own
174 This option can be either true (or "strict"), "loose" (only
175 drop the packet if the source address is not reachable via any
180 logReversePathDrops = lib.mkOption {
181 type = lib.types.bool;
184 Logs dropped packets failing the reverse path filter test if
185 the option networking.firewall.checkReversePath is enabled.
189 filterForward = lib.mkOption {
190 type = lib.types.bool;
193 Enable filtering in IP forwarding.
195 This option only works with the nftables based firewall.
199 connectionTrackingModules = lib.mkOption {
200 type = lib.types.listOf lib.types.str;
202 example = [ "ftp" "irc" "sane" "sip" "tftp" "amanda" "h323" "netbios_sn" "pptp" "snmp" ];
204 List of connection-tracking helpers that are auto-loaded.
205 The complete list of possible values is given in the example.
207 As helpers can pose as a security risk, it is advised to
208 set this to an empty list and disable the setting
209 networking.firewall.autoLoadConntrackHelpers unless you
210 know what you are doing. Connection tracking is disabled
213 Loading of helpers is recommended to be done through the
214 CT target. More info:
215 https://home.regit.org/netfilter-en/secure-use-of-helpers/
219 autoLoadConntrackHelpers = lib.mkOption {
220 type = lib.types.bool;
223 Whether to auto-load connection-tracking helpers.
224 See the description at networking.firewall.connectionTrackingModules
230 extraPackages = lib.mkOption {
231 type = lib.types.listOf lib.types.package;
233 example = lib.literalExpression "[ pkgs.ipset ]";
235 Additional packages to be included in the environment of the system
236 as well as the path of networking.firewall.extraCommands.
240 interfaces = lib.mkOption {
242 type = with lib.types; attrsOf (submodule [{ options = commonOptions; }]);
244 Interface-specific open ports.
248 allInterfaces = lib.mkOption {
251 default = { default = lib.mapAttrs (name: value: cfg.${name}) commonOptions; } // cfg.interfaces;
252 type = with lib.types; attrsOf (submodule [{ options = commonOptions; }]);
262 config = lib.mkIf cfg.enable {
266 assertion = cfg.filterForward -> config.networking.nftables.enable;
267 message = "filterForward only works with the nftables based firewall";
270 assertion = cfg.autoLoadConntrackHelpers -> lib.versionOlder config.boot.kernelPackages.kernel.version "6";
271 message = "conntrack helper autoloading has been removed from kernel 6.0 and newer";
275 networking.firewall.trustedInterfaces = [ "lo" ];
277 environment.systemPackages = [ cfg.package ] ++ cfg.extraPackages;
279 boot.kernelModules = (lib.optional cfg.autoLoadConntrackHelpers "nf_conntrack")
280 ++ map (x: "nf_conntrack_${x}") cfg.connectionTrackingModules;
281 boot.extraModprobeConfig = lib.optionalString cfg.autoLoadConntrackHelpers ''
282 options nf_conntrack nf_conntrack_helper=1