9 cfg = config.networking.firewall;
11 canonicalizePortList = ports: lib.unique (builtins.sort builtins.lessThan ports);
14 allowedTCPPorts = lib.mkOption {
15 type = lib.types.listOf lib.types.port;
17 apply = canonicalizePortList;
23 List of TCP ports on which incoming connections are
28 allowedTCPPortRanges = lib.mkOption {
29 type = lib.types.listOf (lib.types.attrsOf lib.types.port);
38 A range of TCP ports on which incoming connections are
43 allowedUDPPorts = lib.mkOption {
44 type = lib.types.listOf lib.types.port;
46 apply = canonicalizePortList;
49 List of open UDP ports.
53 allowedUDPPortRanges = lib.mkOption {
54 type = lib.types.listOf (lib.types.attrsOf lib.types.port);
63 Range of open UDP ports.
74 networking.firewall = {
75 enable = lib.mkOption {
76 type = lib.types.bool;
79 Whether to enable the firewall. This is a simple stateful
80 firewall that blocks connection attempts to unauthorised TCP
81 or UDP ports on this machine.
85 package = lib.mkOption {
86 type = lib.types.package;
87 default = if config.networking.nftables.enable then pkgs.nftables else pkgs.iptables;
88 defaultText = lib.literalExpression ''if config.networking.nftables.enable then "pkgs.nftables" else "pkgs.iptables"'';
89 example = lib.literalExpression "pkgs.iptables-legacy";
91 The package to use for running the firewall service.
95 logRefusedConnections = lib.mkOption {
96 type = lib.types.bool;
99 Whether to log rejected or dropped incoming connections.
100 Note: The logs are found in the kernel logs, i.e. dmesg
105 logRefusedPackets = lib.mkOption {
106 type = lib.types.bool;
109 Whether to log all rejected or dropped incoming packets.
110 This tends to give a lot of log messages, so it's mostly
111 useful for debugging.
112 Note: The logs are found in the kernel logs, i.e. dmesg
117 logRefusedUnicastsOnly = lib.mkOption {
118 type = lib.types.bool;
121 If {option}`networking.firewall.logRefusedPackets`
122 and this option are enabled, then only log packets
123 specifically directed at this machine, i.e., not broadcasts
128 rejectPackets = lib.mkOption {
129 type = lib.types.bool;
132 If set, refused packets are rejected rather than dropped
133 (ignored). This means that an ICMP "port unreachable" error
134 message is sent back to the client (or a TCP RST packet in
135 case of an existing connection). Rejecting packets makes
136 port scanning somewhat easier.
140 trustedInterfaces = lib.mkOption {
141 type = lib.types.listOf lib.types.str;
143 example = [ "enp0s2" ];
145 Traffic coming in from these interfaces will be accepted
146 unconditionally. Traffic from the loopback (lo) interface
147 will always be accepted.
151 allowPing = lib.mkOption {
152 type = lib.types.bool;
155 Whether to respond to incoming ICMPv4 echo requests
156 ("pings"). ICMPv6 pings are always allowed because the
157 larger address space of IPv6 makes network scanning much
162 pingLimit = lib.mkOption {
163 type = lib.types.nullOr (lib.types.separatedString " ");
165 example = "--limit 1/minute --limit-burst 5";
167 If pings are allowed, this allows setting rate limits on them.
169 For the iptables based firewall, it should be set like
170 "--limit 1/minute --limit-burst 5".
172 For the nftables based firewall, it should be set like
173 "2/second" or "1/minute burst 5 packets".
177 checkReversePath = lib.mkOption {
178 type = lib.types.either lib.types.bool (
185 defaultText = lib.literalMD "`true` except if the iptables based firewall is in use and the kernel lacks rpfilter support";
188 Performs a reverse path filter test on a packet. If a reply
189 to the packet would not be sent via the same interface that
190 the packet arrived on, it is refused.
192 If using asymmetric routing or other complicated routing, set
193 this option to loose mode or disable it and setup your own
196 This option can be either true (or "strict"), "loose" (only
197 drop the packet if the source address is not reachable via any
202 logReversePathDrops = lib.mkOption {
203 type = lib.types.bool;
206 Logs dropped packets failing the reverse path filter test if
207 the option networking.firewall.checkReversePath is enabled.
211 filterForward = lib.mkOption {
212 type = lib.types.bool;
215 Enable filtering in IP forwarding.
217 This option only works with the nftables based firewall.
221 connectionTrackingModules = lib.mkOption {
222 type = lib.types.listOf lib.types.str;
237 List of connection-tracking helpers that are auto-loaded.
238 The complete list of possible values is given in the example.
240 As helpers can pose as a security risk, it is advised to
241 set this to an empty list and disable the setting
242 networking.firewall.autoLoadConntrackHelpers unless you
243 know what you are doing. Connection tracking is disabled
246 Loading of helpers is recommended to be done through the
247 CT target. More info:
248 https://home.regit.org/netfilter-en/secure-use-of-helpers/
252 autoLoadConntrackHelpers = lib.mkOption {
253 type = lib.types.bool;
256 Whether to auto-load connection-tracking helpers.
257 See the description at networking.firewall.connectionTrackingModules
263 extraPackages = lib.mkOption {
264 type = lib.types.listOf lib.types.package;
266 example = lib.literalExpression "[ pkgs.ipset ]";
268 Additional packages to be included in the environment of the system
269 as well as the path of networking.firewall.extraCommands.
273 interfaces = lib.mkOption {
275 type = with lib.types; attrsOf (submodule [ { options = commonOptions; } ]);
277 Interface-specific open ports.
281 allInterfaces = lib.mkOption {
285 default = lib.mapAttrs (name: value: cfg.${name}) commonOptions;
287 type = with lib.types; attrsOf (submodule [ { options = commonOptions; } ]);
296 config = lib.mkIf cfg.enable {
300 assertion = cfg.filterForward -> config.networking.nftables.enable;
301 message = "filterForward only works with the nftables based firewall";
305 cfg.autoLoadConntrackHelpers -> lib.versionOlder config.boot.kernelPackages.kernel.version "6";
306 message = "conntrack helper autoloading has been removed from kernel 6.0 and newer";
310 networking.firewall.trustedInterfaces = [ "lo" ];
312 environment.systemPackages = [
314 pkgs.nixos-firewall-tool
315 ] ++ cfg.extraPackages;
318 (lib.optional cfg.autoLoadConntrackHelpers "nf_conntrack")
319 ++ map (x: "nf_conntrack_${x}") cfg.connectionTrackingModules;
320 boot.extraModprobeConfig = lib.optionalString cfg.autoLoadConntrackHelpers ''
321 options nf_conntrack nf_conntrack_helper=1