at 25.11-pre 9.7 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7let 8 9 cfg = config.networking.firewall; 10 11 canonicalizePortList = ports: lib.unique (builtins.sort builtins.lessThan ports); 12 13 commonOptions = { 14 allowedTCPPorts = lib.mkOption { 15 type = lib.types.listOf lib.types.port; 16 default = [ ]; 17 apply = canonicalizePortList; 18 example = [ 19 22 20 80 21 ]; 22 description = '' 23 List of TCP ports on which incoming connections are 24 accepted. 25 ''; 26 }; 27 28 allowedTCPPortRanges = lib.mkOption { 29 type = lib.types.listOf (lib.types.attrsOf lib.types.port); 30 default = [ ]; 31 example = [ 32 { 33 from = 8999; 34 to = 9003; 35 } 36 ]; 37 description = '' 38 A range of TCP ports on which incoming connections are 39 accepted. 40 ''; 41 }; 42 43 allowedUDPPorts = lib.mkOption { 44 type = lib.types.listOf lib.types.port; 45 default = [ ]; 46 apply = canonicalizePortList; 47 example = [ 53 ]; 48 description = '' 49 List of open UDP ports. 50 ''; 51 }; 52 53 allowedUDPPortRanges = lib.mkOption { 54 type = lib.types.listOf (lib.types.attrsOf lib.types.port); 55 default = [ ]; 56 example = [ 57 { 58 from = 60000; 59 to = 61000; 60 } 61 ]; 62 description = '' 63 Range of open UDP ports. 64 ''; 65 }; 66 }; 67 68in 69 70{ 71 72 options = { 73 74 networking.firewall = { 75 enable = lib.mkOption { 76 type = lib.types.bool; 77 default = true; 78 description = '' 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. 82 ''; 83 }; 84 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"; 90 description = '' 91 The package to use for running the firewall service. 92 ''; 93 }; 94 95 logRefusedConnections = lib.mkOption { 96 type = lib.types.bool; 97 default = true; 98 description = '' 99 Whether to log rejected or dropped incoming connections. 100 Note: The logs are found in the kernel logs, i.e. dmesg 101 or journalctl -k. 102 ''; 103 }; 104 105 logRefusedPackets = lib.mkOption { 106 type = lib.types.bool; 107 default = false; 108 description = '' 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 113 or journalctl -k. 114 ''; 115 }; 116 117 logRefusedUnicastsOnly = lib.mkOption { 118 type = lib.types.bool; 119 default = true; 120 description = '' 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 124 or multicasts. 125 ''; 126 }; 127 128 rejectPackets = lib.mkOption { 129 type = lib.types.bool; 130 default = false; 131 description = '' 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. 137 ''; 138 }; 139 140 trustedInterfaces = lib.mkOption { 141 type = lib.types.listOf lib.types.str; 142 default = [ ]; 143 example = [ "enp0s2" ]; 144 description = '' 145 Traffic coming in from these interfaces will be accepted 146 unconditionally. Traffic from the loopback (lo) interface 147 will always be accepted. 148 ''; 149 }; 150 151 allowPing = lib.mkOption { 152 type = lib.types.bool; 153 default = true; 154 description = '' 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 158 less effective. 159 ''; 160 }; 161 162 pingLimit = lib.mkOption { 163 type = lib.types.nullOr (lib.types.separatedString " "); 164 default = null; 165 example = "--limit 1/minute --limit-burst 5"; 166 description = '' 167 If pings are allowed, this allows setting rate limits on them. 168 169 For the iptables based firewall, it should be set like 170 "--limit 1/minute --limit-burst 5". 171 172 For the nftables based firewall, it should be set like 173 "2/second" or "1/minute burst 5 packets". 174 ''; 175 }; 176 177 checkReversePath = lib.mkOption { 178 type = lib.types.either lib.types.bool ( 179 lib.types.enum [ 180 "strict" 181 "loose" 182 ] 183 ); 184 default = true; 185 defaultText = lib.literalMD "`true` except if the iptables based firewall is in use and the kernel lacks rpfilter support"; 186 example = "loose"; 187 description = '' 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. 191 192 If using asymmetric routing or other complicated routing, set 193 this option to loose mode or disable it and setup your own 194 counter-measures. 195 196 This option can be either true (or "strict"), "loose" (only 197 drop the packet if the source address is not reachable via any 198 interface) or false. 199 ''; 200 }; 201 202 logReversePathDrops = lib.mkOption { 203 type = lib.types.bool; 204 default = false; 205 description = '' 206 Logs dropped packets failing the reverse path filter test if 207 the option networking.firewall.checkReversePath is enabled. 208 ''; 209 }; 210 211 filterForward = lib.mkOption { 212 type = lib.types.bool; 213 default = false; 214 description = '' 215 Enable filtering in IP forwarding. 216 217 This option only works with the nftables based firewall. 218 ''; 219 }; 220 221 connectionTrackingModules = lib.mkOption { 222 type = lib.types.listOf lib.types.str; 223 default = [ ]; 224 example = [ 225 "ftp" 226 "irc" 227 "sane" 228 "sip" 229 "tftp" 230 "amanda" 231 "h323" 232 "netbios_sn" 233 "pptp" 234 "snmp" 235 ]; 236 description = '' 237 List of connection-tracking helpers that are auto-loaded. 238 The complete list of possible values is given in the example. 239 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 244 by default. 245 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/> 249 ''; 250 }; 251 252 autoLoadConntrackHelpers = lib.mkOption { 253 type = lib.types.bool; 254 default = false; 255 description = '' 256 Whether to auto-load connection-tracking helpers. 257 See the description at networking.firewall.connectionTrackingModules 258 259 (needs kernel 3.5+) 260 ''; 261 }; 262 263 extraPackages = lib.mkOption { 264 type = lib.types.listOf lib.types.package; 265 default = [ ]; 266 example = lib.literalExpression "[ pkgs.ipset ]"; 267 description = '' 268 Additional packages to be included in the environment of the system 269 as well as the path of networking.firewall.extraCommands. 270 ''; 271 }; 272 273 interfaces = lib.mkOption { 274 default = { }; 275 type = with lib.types; attrsOf (submodule [ { options = commonOptions; } ]); 276 description = '' 277 Interface-specific open ports. 278 ''; 279 }; 280 281 allInterfaces = lib.mkOption { 282 internal = true; 283 visible = false; 284 default = { 285 default = lib.mapAttrs (name: value: cfg.${name}) commonOptions; 286 } // cfg.interfaces; 287 type = with lib.types; attrsOf (submodule [ { options = commonOptions; } ]); 288 description = '' 289 All open ports. 290 ''; 291 }; 292 } // commonOptions; 293 294 }; 295 296 config = lib.mkIf cfg.enable { 297 298 assertions = [ 299 { 300 assertion = cfg.filterForward -> config.networking.nftables.enable; 301 message = "filterForward only works with the nftables based firewall"; 302 } 303 { 304 assertion = 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"; 307 } 308 ]; 309 310 networking.firewall.trustedInterfaces = [ "lo" ]; 311 312 environment.systemPackages = [ 313 cfg.package 314 pkgs.nixos-firewall-tool 315 ] ++ cfg.extraPackages; 316 317 boot.kernelModules = 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 322 ''; 323 324 }; 325 326}