| 
									
										
										
										
											2011-07-05 12:51:46 +00:00
										 |  |  |  | /* This module enables a simple firewall.
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |    The firewall can be customised in arbitrary ways by setting | 
					
						
							|  |  |  |  |    ‘networking.firewall.extraCommands’.  For modularity, the firewall | 
					
						
							|  |  |  |  |    uses several chains: | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |    - ‘nixos-fw-input’ is the main chain for input packet processing. | 
					
						
							| 
									
										
										
										
											2011-09-14 18:20:50 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-05 12:51:46 +00:00
										 |  |  |  |    - ‘nixos-fw-log-refuse’ and ‘nixos-fw-refuse’ are called for | 
					
						
							|  |  |  |  |      refused packets.  (The former jumps to the latter after logging | 
					
						
							|  |  |  |  |      the packet.)  If you want additional logging, or want to accept | 
					
						
							|  |  |  |  |      certain packets anyway, you can insert rules at the start of | 
					
						
							|  |  |  |  |      these chain. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |    - ‘nixos-fw-accept’ is called for accepted packets.  If you want | 
					
						
							|  |  |  |  |      additional logging, or want to reject certain packets anyway, you | 
					
						
							|  |  |  |  |      can insert rules at the start of this chain. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | */ | 
					
						
							| 
									
										
										
										
											2011-09-14 18:20:50 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-14 16:26:48 +02:00
										 |  |  |  | { config, lib, pkgs, ... }: | 
					
						
							| 
									
										
										
										
											2009-09-29 14:21:56 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-14 16:26:48 +02:00
										 |  |  |  | with lib; | 
					
						
							| 
									
										
										
										
											2009-07-24 23:12:52 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | let | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-29 14:21:56 +00:00
										 |  |  |  |   cfg = config.networking.firewall; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-05 12:51:46 +00:00
										 |  |  |  |   helpers = | 
					
						
							|  |  |  |  |     ''
 | 
					
						
							|  |  |  |  |       # Helper command to manipulate both the IPv4 and IPv6 tables. | 
					
						
							|  |  |  |  |       ip46tables() { | 
					
						
							| 
									
										
										
										
											2014-04-11 16:29:45 +02:00
										 |  |  |  |         iptables -w "$@" | 
					
						
							| 
									
										
										
										
											2012-09-18 17:20:46 -04:00
										 |  |  |  |         ${optionalString config.networking.enableIPv6 ''
 | 
					
						
							| 
									
										
										
										
											2014-04-11 16:29:45 +02:00
										 |  |  |  |           ip6tables -w "$@" | 
					
						
							| 
									
										
										
										
											2012-09-18 17:20:46 -04:00
										 |  |  |  |         ''}
 | 
					
						
							| 
									
										
										
										
											2011-07-05 12:51:46 +00:00
										 |  |  |  |       } | 
					
						
							|  |  |  |  |     '';
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-12 13:09:19 +02:00
										 |  |  |  |   kernelPackages = config.boot.kernelPackages; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-12 16:02:52 +02:00
										 |  |  |  |   kernelHasRPFilter = kernelPackages.kernel.features.netfilterRPFilter or false; | 
					
						
							|  |  |  |  |   kernelCanDisableHelpers = kernelPackages.kernel.features.canDisableNetfilterConntrackHelpers or false; | 
					
						
							| 
									
										
										
										
											2012-10-12 13:16:33 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-24 23:12:52 +00:00
										 |  |  |  | in | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   ###### interface | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   options = { | 
					
						
							| 
									
										
										
										
											2011-09-14 18:20:50 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-29 14:21:56 +00:00
										 |  |  |  |     networking.firewall.enable = mkOption { | 
					
						
							| 
									
										
										
										
											2013-10-30 17:37:45 +01:00
										 |  |  |  |       type = types.bool; | 
					
						
							| 
									
										
										
										
											2014-04-08 09:42:05 +02:00
										 |  |  |  |       default = true; | 
					
						
							| 
									
										
										
										
											2009-07-26 21:27:35 +00:00
										 |  |  |  |       description = | 
					
						
							|  |  |  |  |         ''
 | 
					
						
							| 
									
										
										
										
											2011-03-10 09:39:17 +00:00
										 |  |  |  |           Whether to enable the firewall.  This is a simple stateful | 
					
						
							|  |  |  |  |           firewall that blocks connection attempts to unauthorised TCP | 
					
						
							|  |  |  |  |           or UDP ports on this machine.  It does not affect packet | 
					
						
							|  |  |  |  |           forwarding. | 
					
						
							| 
									
										
										
										
											2009-07-26 21:27:35 +00:00
										 |  |  |  |         '';
 | 
					
						
							|  |  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2011-09-14 18:20:50 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-29 14:21:56 +00:00
										 |  |  |  |     networking.firewall.logRefusedConnections = mkOption { | 
					
						
							| 
									
										
										
										
											2013-10-30 17:37:45 +01:00
										 |  |  |  |       type = types.bool; | 
					
						
							| 
									
										
										
										
											2009-09-29 14:21:56 +00:00
										 |  |  |  |       default = true; | 
					
						
							|  |  |  |  |       description = | 
					
						
							|  |  |  |  |         ''
 | 
					
						
							|  |  |  |  |           Whether to log rejected or dropped incoming connections. | 
					
						
							|  |  |  |  |         '';
 | 
					
						
							|  |  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2011-09-14 18:20:50 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-29 14:21:56 +00:00
										 |  |  |  |     networking.firewall.logRefusedPackets = mkOption { | 
					
						
							| 
									
										
										
										
											2013-10-30 17:37:45 +01:00
										 |  |  |  |       type = types.bool; | 
					
						
							| 
									
										
										
										
											2011-07-05 12:54:50 +00:00
										 |  |  |  |       default = false; | 
					
						
							| 
									
										
										
										
											2009-09-29 14:21:56 +00:00
										 |  |  |  |       description = | 
					
						
							|  |  |  |  |         ''
 | 
					
						
							|  |  |  |  |           Whether to log all rejected or dropped incoming packets. | 
					
						
							|  |  |  |  |           This tends to give a lot of log messages, so it's mostly | 
					
						
							|  |  |  |  |           useful for debugging. | 
					
						
							|  |  |  |  |         '';
 | 
					
						
							|  |  |  |  |     }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-05 12:51:46 +00:00
										 |  |  |  |     networking.firewall.logRefusedUnicastsOnly = mkOption { | 
					
						
							| 
									
										
										
										
											2013-10-30 17:37:45 +01:00
										 |  |  |  |       type = types.bool; | 
					
						
							| 
									
										
										
										
											2011-07-05 12:51:46 +00:00
										 |  |  |  |       default = true; | 
					
						
							|  |  |  |  |       description = | 
					
						
							|  |  |  |  |         ''
 | 
					
						
							|  |  |  |  |           If <option>networking.firewall.logRefusedPackets</option> | 
					
						
							|  |  |  |  |           and this option are enabled, then only log packets | 
					
						
							|  |  |  |  |           specifically directed at this machine, i.e., not broadcasts | 
					
						
							|  |  |  |  |           or multicasts. | 
					
						
							|  |  |  |  |         '';
 | 
					
						
							|  |  |  |  |     }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-29 14:21:56 +00:00
										 |  |  |  |     networking.firewall.rejectPackets = mkOption { | 
					
						
							| 
									
										
										
										
											2013-10-30 17:37:45 +01:00
										 |  |  |  |       type = types.bool; | 
					
						
							| 
									
										
										
										
											2009-09-29 14:21:56 +00:00
										 |  |  |  |       default = false; | 
					
						
							|  |  |  |  |       description = | 
					
						
							|  |  |  |  |         ''
 | 
					
						
							|  |  |  |  |           If set, forbidden packets are rejected rather than dropped | 
					
						
							| 
									
										
										
										
											2013-08-10 21:07:13 +00:00
										 |  |  |  |           (ignored).  This means that an ICMP "port unreachable" error | 
					
						
							| 
									
										
										
										
											2009-09-29 14:21:56 +00:00
										 |  |  |  |           message is sent back to the client.  Rejecting packets makes | 
					
						
							|  |  |  |  |           port scanning somewhat easier. | 
					
						
							|  |  |  |  |         '';
 | 
					
						
							|  |  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2011-09-14 18:20:50 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-20 17:51:44 -04:00
										 |  |  |  |     networking.firewall.trustedInterfaces = mkOption { | 
					
						
							| 
									
										
										
										
											2013-03-14 17:09:21 +01:00
										 |  |  |  |       type = types.listOf types.string; | 
					
						
							| 
									
										
										
										
											2012-09-20 17:51:44 -04:00
										 |  |  |  |       description = | 
					
						
							|  |  |  |  |         ''
 | 
					
						
							|  |  |  |  |           Traffic coming in from these interfaces will be accepted | 
					
						
							|  |  |  |  |           unconditionally. | 
					
						
							|  |  |  |  |         '';
 | 
					
						
							|  |  |  |  |     }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-29 14:21:56 +00:00
										 |  |  |  |     networking.firewall.allowedTCPPorts = mkOption { | 
					
						
							| 
									
										
										
										
											2009-07-24 23:12:52 +00:00
										 |  |  |  |       default = []; | 
					
						
							| 
									
										
										
										
											2011-03-09 16:37:16 +00:00
										 |  |  |  |       example = [ 22 80 ]; | 
					
						
							| 
									
										
										
										
											2013-03-14 17:09:21 +01:00
										 |  |  |  |       type = types.listOf types.int; | 
					
						
							| 
									
										
										
										
											2009-07-24 23:12:52 +00:00
										 |  |  |  |       description = | 
					
						
							|  |  |  |  |         ''
 | 
					
						
							|  |  |  |  |           List of TCP ports on which incoming connections are | 
					
						
							|  |  |  |  |           accepted. | 
					
						
							|  |  |  |  |         '';
 | 
					
						
							|  |  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2011-09-14 18:20:50 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-19 05:19:19 -06:00
										 |  |  |  |     networking.firewall.allowedTCPPortRanges = mkOption { | 
					
						
							|  |  |  |  |       default = []; | 
					
						
							|  |  |  |  |       example = [ { from = 8999; to = 9003; } ]; | 
					
						
							|  |  |  |  |       type = types.listOf (types.attrsOf types.int); | 
					
						
							|  |  |  |  |       description = | 
					
						
							|  |  |  |  |         ''
 | 
					
						
							|  |  |  |  |           A range of TCP ports on which incoming connections are | 
					
						
							|  |  |  |  |           accepted. | 
					
						
							|  |  |  |  |         '';
 | 
					
						
							|  |  |  |  |     }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-09 16:37:16 +00:00
										 |  |  |  |     networking.firewall.allowedUDPPorts = mkOption { | 
					
						
							|  |  |  |  |       default = []; | 
					
						
							|  |  |  |  |       example = [ 53 ]; | 
					
						
							| 
									
										
										
										
											2013-03-14 17:09:21 +01:00
										 |  |  |  |       type = types.listOf types.int; | 
					
						
							| 
									
										
										
										
											2011-03-09 16:37:16 +00:00
										 |  |  |  |       description = | 
					
						
							|  |  |  |  |         ''
 | 
					
						
							|  |  |  |  |           List of open UDP ports. | 
					
						
							|  |  |  |  |         '';
 | 
					
						
							|  |  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2011-09-14 18:20:50 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-19 05:19:19 -06:00
										 |  |  |  |     networking.firewall.allowedUDPPortRanges = mkOption { | 
					
						
							|  |  |  |  |       default = []; | 
					
						
							|  |  |  |  |       example = [ { from = 60000; to = 61000; } ]; | 
					
						
							|  |  |  |  |       type = types.listOf (types.attrsOf types.int); | 
					
						
							|  |  |  |  |       description = | 
					
						
							|  |  |  |  |         ''
 | 
					
						
							|  |  |  |  |           Range of open UDP ports. | 
					
						
							|  |  |  |  |         '';
 | 
					
						
							|  |  |  |  |     }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-09 15:28:47 +00:00
										 |  |  |  |     networking.firewall.allowPing = mkOption { | 
					
						
							|  |  |  |  |       default = false; | 
					
						
							|  |  |  |  |       type = types.bool; | 
					
						
							|  |  |  |  |       description = | 
					
						
							|  |  |  |  |         ''
 | 
					
						
							| 
									
										
										
										
											2011-03-11 11:08:16 +00:00
										 |  |  |  |           Whether to respond to incoming ICMPv4 echo requests | 
					
						
							|  |  |  |  |           ("pings").  ICMPv6 pings are always allowed because the | 
					
						
							|  |  |  |  |           larger address space of IPv6 makes network scanning much | 
					
						
							|  |  |  |  |           less effective. | 
					
						
							| 
									
										
										
										
											2011-03-09 15:28:47 +00:00
										 |  |  |  |         '';
 | 
					
						
							|  |  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2011-09-14 18:20:50 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-14 14:55:30 -04:00
										 |  |  |  |     networking.firewall.pingLimit = mkOption { | 
					
						
							|  |  |  |  |       default = null; | 
					
						
							|  |  |  |  |       type = types.nullOr (types.separatedString " "); | 
					
						
							|  |  |  |  |       description = | 
					
						
							|  |  |  |  |         ''
 | 
					
						
							|  |  |  |  |           If pings are allowed, this allows setting rate limits | 
					
						
							|  |  |  |  |           on them. If non-null, this option should be in the form | 
					
						
							|  |  |  |  |           of flags like "-limit 1/minute -limit-burst 5" | 
					
						
							|  |  |  |  |         '';
 | 
					
						
							|  |  |  |  |     }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-12 13:09:19 +02:00
										 |  |  |  |     networking.firewall.checkReversePath = mkOption { | 
					
						
							|  |  |  |  |       default = kernelHasRPFilter; | 
					
						
							|  |  |  |  |       type = types.bool; | 
					
						
							|  |  |  |  |       description = | 
					
						
							|  |  |  |  |         ''
 | 
					
						
							|  |  |  |  |           Performs a reverse path filter test on a packet. | 
					
						
							|  |  |  |  |           If a reply to the packet would not be sent via the same interface | 
					
						
							|  |  |  |  |           that the packet arrived on, it is refused. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |           If using asymmetric routing or other complicated routing, | 
					
						
							|  |  |  |  |           disable this setting and setup your own counter-measures. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |           (needs kernel 3.3+) | 
					
						
							|  |  |  |  |         '';
 | 
					
						
							|  |  |  |  |     }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-12 13:16:33 +02:00
										 |  |  |  |     networking.firewall.connectionTrackingModules = mkOption { | 
					
						
							|  |  |  |  |       default = [ "ftp" ]; | 
					
						
							|  |  |  |  |       example = [ "ftp" "irc" "sane" "sip" "tftp" "amanda" "h323" "netbios_sn" "pptp" "snmp" ]; | 
					
						
							| 
									
										
										
										
											2013-03-14 17:09:21 +01:00
										 |  |  |  |       type = types.listOf types.string; | 
					
						
							| 
									
										
										
										
											2012-10-12 13:16:33 +02:00
										 |  |  |  |       description = | 
					
						
							|  |  |  |  |         ''
 | 
					
						
							|  |  |  |  |           List of connection-tracking helpers that are auto-loaded. | 
					
						
							|  |  |  |  |           The complete list of possible values is given in the example. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-10 21:07:13 +00:00
										 |  |  |  |           As helpers can pose as a security risk, it is advised to | 
					
						
							| 
									
										
										
										
											2012-10-12 13:16:33 +02:00
										 |  |  |  |           set this to an empty list and disable the setting | 
					
						
							|  |  |  |  |           networking.firewall.autoLoadConntrackHelpers | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |           Loading of helpers is recommended to be done through the new | 
					
						
							|  |  |  |  |           CT target. More info: | 
					
						
							|  |  |  |  |           https://home.regit.org/netfilter-en/secure-use-of-helpers/ | 
					
						
							|  |  |  |  |         '';
 | 
					
						
							|  |  |  |  |     }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     networking.firewall.autoLoadConntrackHelpers = mkOption { | 
					
						
							|  |  |  |  |       default = true; | 
					
						
							|  |  |  |  |       type = types.bool; | 
					
						
							|  |  |  |  |       description = | 
					
						
							|  |  |  |  |         ''
 | 
					
						
							|  |  |  |  |           Whether to auto-load connection-tracking helpers. | 
					
						
							|  |  |  |  |           See the description at networking.firewall.connectionTrackingModules | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |           (needs kernel 3.5+) | 
					
						
							|  |  |  |  |         '';
 | 
					
						
							|  |  |  |  |     }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-11 13:04:17 +00:00
										 |  |  |  |     networking.firewall.extraCommands = mkOption { | 
					
						
							| 
									
										
										
										
											2013-10-30 17:37:45 +01:00
										 |  |  |  |       type = types.lines; | 
					
						
							| 
									
										
										
										
											2011-03-11 13:04:17 +00:00
										 |  |  |  |       default = ""; | 
					
						
							|  |  |  |  |       example = "iptables -A INPUT -p icmp -j ACCEPT"; | 
					
						
							|  |  |  |  |       description = | 
					
						
							|  |  |  |  |         ''
 | 
					
						
							|  |  |  |  |           Additional shell commands executed as part of the firewall | 
					
						
							|  |  |  |  |           initialisation script.  These are executed just before the | 
					
						
							|  |  |  |  |           final "reject" firewall rule is added, so they can be used | 
					
						
							|  |  |  |  |           to allow packets that would otherwise be refused. | 
					
						
							|  |  |  |  |         '';
 | 
					
						
							|  |  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2011-09-14 18:20:50 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-24 23:12:52 +00:00
										 |  |  |  |   }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   ###### implementation | 
					
						
							| 
									
										
										
										
											2009-07-26 21:27:35 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-31 13:26:06 +01:00
										 |  |  |  |   # FIXME: Maybe if `enable' is false, the firewall should still be | 
					
						
							|  |  |  |  |   # built but not started by default? | 
					
						
							| 
									
										
										
										
											2011-03-10 09:39:17 +00:00
										 |  |  |  |   config = mkIf cfg.enable { | 
					
						
							| 
									
										
										
										
											2009-07-24 23:12:52 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-20 17:51:44 -04:00
										 |  |  |  |     networking.firewall.trustedInterfaces = [ "lo" ]; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-09 12:28:44 +00:00
										 |  |  |  |     environment.systemPackages = [ pkgs.iptables ]; | 
					
						
							| 
									
										
										
										
											2009-07-24 23:12:52 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-12 13:16:33 +02:00
										 |  |  |  |     boot.kernelModules = map (x: "nf_conntrack_${x}") cfg.connectionTrackingModules; | 
					
						
							|  |  |  |  |     boot.extraModprobeConfig = optionalString (!cfg.autoLoadConntrackHelpers) ''
 | 
					
						
							|  |  |  |  |       options nf_conntrack nf_conntrack_helper=0 | 
					
						
							|  |  |  |  |     '';
 | 
					
						
							| 
									
										
										
										
											2011-03-11 13:34:17 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-12 13:09:19 +02:00
										 |  |  |  |     assertions = [ { assertion = ! cfg.checkReversePath || kernelHasRPFilter; | 
					
						
							| 
									
										
										
										
											2012-10-12 13:16:33 +02:00
										 |  |  |  |                      message = "This kernel does not support rpfilter"; } | 
					
						
							|  |  |  |  |                    { assertion = cfg.autoLoadConntrackHelpers || kernelCanDisableHelpers; | 
					
						
							|  |  |  |  |                      message = "This kernel does not support disabling conntrack helpers"; } | 
					
						
							|  |  |  |  |                  ]; | 
					
						
							| 
									
										
										
										
											2011-03-11 13:34:17 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-19 23:02:59 +02:00
										 |  |  |  |     systemd.services.firewall = | 
					
						
							| 
									
										
										
										
											2013-01-10 13:59:41 +01:00
										 |  |  |  |       { description = "Firewall"; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-19 23:02:59 +02:00
										 |  |  |  |         wantedBy = [ "network.target" ]; | 
					
						
							|  |  |  |  |         after = [ "network-interfaces.target" "systemd-modules-load.service" ]; | 
					
						
							| 
									
										
										
										
											2009-07-26 21:27:35 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-09 12:28:44 +00:00
										 |  |  |  |         path = [ pkgs.iptables ]; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-19 23:02:59 +02:00
										 |  |  |  |         # FIXME: this module may also try to load kernel modules, but | 
					
						
							|  |  |  |  |         # containers don't have CAP_SYS_MODULE. So the host system had | 
					
						
							|  |  |  |  |         # better have all necessary modules already loaded. | 
					
						
							|  |  |  |  |         unitConfig.ConditionCapability = "CAP_NET_ADMIN"; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         serviceConfig.Type = "oneshot"; | 
					
						
							|  |  |  |  |         serviceConfig.RemainAfterExit = true; | 
					
						
							| 
									
										
										
										
											2014-04-17 18:10:20 +02:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-19 23:02:59 +02:00
										 |  |  |  |         script = | 
					
						
							| 
									
										
										
										
											2009-07-24 23:12:52 +00:00
										 |  |  |  |           ''
 | 
					
						
							| 
									
										
										
										
											2011-07-05 12:51:46 +00:00
										 |  |  |  |             ${helpers} | 
					
						
							| 
									
										
										
										
											2011-03-09 14:41:48 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-05 12:51:46 +00:00
										 |  |  |  |             # Flush the old firewall rules.  !!! Ideally, updating the | 
					
						
							|  |  |  |  |             # firewall would be atomic.  Apparently that's possible | 
					
						
							|  |  |  |  |             # with iptables-restore. | 
					
						
							| 
									
										
										
										
											2013-09-10 15:06:28 +02:00
										 |  |  |  |             ip46tables -D INPUT -j nixos-fw 2> /dev/null || true | 
					
						
							| 
									
										
										
										
											2011-07-05 12:51:46 +00:00
										 |  |  |  |             for chain in nixos-fw nixos-fw-accept nixos-fw-log-refuse nixos-fw-refuse FW_REFUSE; do | 
					
						
							| 
									
										
										
										
											2013-09-10 15:06:28 +02:00
										 |  |  |  |               ip46tables -F "$chain" 2> /dev/null || true | 
					
						
							|  |  |  |  |               ip46tables -X "$chain" 2> /dev/null || true | 
					
						
							| 
									
										
										
										
											2011-07-05 12:51:46 +00:00
										 |  |  |  |             done | 
					
						
							| 
									
										
										
										
											2011-03-09 15:11:01 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-05 12:51:46 +00:00
										 |  |  |  |             # The "nixos-fw-accept" chain just accepts packets. | 
					
						
							|  |  |  |  |             ip46tables -N nixos-fw-accept | 
					
						
							|  |  |  |  |             ip46tables -A nixos-fw-accept -j ACCEPT | 
					
						
							| 
									
										
										
										
											2011-03-09 15:11:01 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-05 12:51:46 +00:00
										 |  |  |  |             # The "nixos-fw-refuse" chain rejects or drops packets. | 
					
						
							|  |  |  |  |             ip46tables -N nixos-fw-refuse | 
					
						
							| 
									
										
										
										
											2011-09-14 18:20:50 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-12 11:25:57 +00:00
										 |  |  |  |             ${if cfg.rejectPackets then ''
 | 
					
						
							|  |  |  |  |               # Send a reset for existing TCP connections that we've | 
					
						
							|  |  |  |  |               # somehow forgotten about.  Send ICMP "port unreachable" | 
					
						
							|  |  |  |  |               # for everything else. | 
					
						
							| 
									
										
										
										
											2011-07-05 12:51:46 +00:00
										 |  |  |  |               ip46tables -A nixos-fw-refuse -p tcp ! --syn -j REJECT --reject-with tcp-reset | 
					
						
							|  |  |  |  |               ip46tables -A nixos-fw-refuse -j REJECT | 
					
						
							| 
									
										
										
										
											2011-04-12 11:25:57 +00:00
										 |  |  |  |             '' else '' | 
					
						
							| 
									
										
										
										
											2011-07-05 12:51:46 +00:00
										 |  |  |  |               ip46tables -A nixos-fw-refuse -j DROP | 
					
						
							| 
									
										
										
										
											2011-04-12 11:25:57 +00:00
										 |  |  |  |             ''}
 | 
					
						
							| 
									
										
										
										
											2011-03-09 15:11:01 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-24 23:12:52 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-05 12:51:46 +00:00
										 |  |  |  |             # The "nixos-fw-log-refuse" chain performs logging, then | 
					
						
							|  |  |  |  |             # jumps to the "nixos-fw-refuse" chain. | 
					
						
							|  |  |  |  |             ip46tables -N nixos-fw-log-refuse | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             ${optionalString cfg.logRefusedConnections ''
 | 
					
						
							|  |  |  |  |               ip46tables -A nixos-fw-log-refuse -p tcp --syn -j LOG --log-level info --log-prefix "rejected connection: " | 
					
						
							|  |  |  |  |             ''}
 | 
					
						
							|  |  |  |  |             ${optionalString (cfg.logRefusedPackets && !cfg.logRefusedUnicastsOnly) ''
 | 
					
						
							|  |  |  |  |               ip46tables -A nixos-fw-log-refuse -m pkttype --pkt-type broadcast \ | 
					
						
							|  |  |  |  |                 -j LOG --log-level info --log-prefix "rejected broadcast: " | 
					
						
							|  |  |  |  |               ip46tables -A nixos-fw-log-refuse -m pkttype --pkt-type multicast \ | 
					
						
							|  |  |  |  |                 -j LOG --log-level info --log-prefix "rejected multicast: " | 
					
						
							|  |  |  |  |             ''}
 | 
					
						
							|  |  |  |  |             ip46tables -A nixos-fw-log-refuse -m pkttype ! --pkt-type unicast -j nixos-fw-refuse | 
					
						
							|  |  |  |  |             ${optionalString cfg.logRefusedPackets ''
 | 
					
						
							|  |  |  |  |               ip46tables -A nixos-fw-log-refuse \ | 
					
						
							|  |  |  |  |                 -j LOG --log-level info --log-prefix "rejected packet: " | 
					
						
							|  |  |  |  |             ''}
 | 
					
						
							|  |  |  |  |             ip46tables -A nixos-fw-log-refuse -j nixos-fw-refuse | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             # The "nixos-fw" chain does the actual work. | 
					
						
							|  |  |  |  |             ip46tables -N nixos-fw | 
					
						
							| 
									
										
										
										
											2011-09-14 18:20:50 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-12 13:09:19 +02:00
										 |  |  |  |             # Perform a reverse-path test to refuse spoofers | 
					
						
							|  |  |  |  |             # For now, we just drop, as the raw table doesn't have a log-refuse yet | 
					
						
							|  |  |  |  |             ${optionalString (kernelHasRPFilter && cfg.checkReversePath) ''
 | 
					
						
							| 
									
										
										
										
											2013-09-10 14:58:12 +02:00
										 |  |  |  |               if ! ip46tables -A PREROUTING -t raw -m rpfilter --invert -j DROP; then | 
					
						
							|  |  |  |  |                 echo "<2>failed to initialise rpfilter support" >&2 | 
					
						
							|  |  |  |  |               fi | 
					
						
							| 
									
										
										
										
											2012-10-12 13:09:19 +02:00
										 |  |  |  |             ''}
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-20 17:51:44 -04:00
										 |  |  |  |             # Accept all traffic on the trusted interfaces. | 
					
						
							|  |  |  |  |             ${flip concatMapStrings cfg.trustedInterfaces (iface: ''
 | 
					
						
							|  |  |  |  |               ip46tables -A nixos-fw -i ${iface} -j nixos-fw-accept | 
					
						
							|  |  |  |  |             '')}
 | 
					
						
							| 
									
										
										
										
											2009-07-24 23:12:52 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |             # Accept packets from established or related connections. | 
					
						
							| 
									
										
										
										
											2011-07-05 12:51:46 +00:00
										 |  |  |  |             ip46tables -A nixos-fw -m conntrack --ctstate ESTABLISHED,RELATED -j nixos-fw-accept | 
					
						
							| 
									
										
										
										
											2009-07-24 23:12:52 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-09 14:41:48 +00:00
										 |  |  |  |             # Accept connections to the allowed TCP ports. | 
					
						
							| 
									
										
										
										
											2009-09-29 14:21:56 +00:00
										 |  |  |  |             ${concatMapStrings (port: | 
					
						
							| 
									
										
										
										
											2009-07-24 23:12:52 +00:00
										 |  |  |  |                 ''
 | 
					
						
							| 
									
										
										
										
											2011-07-05 12:51:46 +00:00
										 |  |  |  |                   ip46tables -A nixos-fw -p tcp --dport ${toString port} -j nixos-fw-accept | 
					
						
							| 
									
										
										
										
											2009-07-24 23:12:52 +00:00
										 |  |  |  |                 ''
 | 
					
						
							| 
									
										
										
										
											2011-03-10 09:39:17 +00:00
										 |  |  |  |               ) cfg.allowedTCPPorts | 
					
						
							| 
									
										
										
										
											2009-07-24 23:12:52 +00:00
										 |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-19 05:19:19 -06:00
										 |  |  |  |             # Accept connections to the allowed TCP port ranges. | 
					
						
							|  |  |  |  |             ${concatMapStrings (rangeAttr: | 
					
						
							|  |  |  |  |                 let range = toString rangeAttr.from + ":" + toString rangeAttr.to; in | 
					
						
							|  |  |  |  |                 ''
 | 
					
						
							|  |  |  |  |                   ip46tables -A nixos-fw -p tcp --dport ${range} -j nixos-fw-accept | 
					
						
							|  |  |  |  |                 ''
 | 
					
						
							|  |  |  |  |               ) cfg.allowedTCPPortRanges | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-09 16:37:16 +00:00
										 |  |  |  |             # Accept packets on the allowed UDP ports. | 
					
						
							|  |  |  |  |             ${concatMapStrings (port: | 
					
						
							|  |  |  |  |                 ''
 | 
					
						
							| 
									
										
										
										
											2011-07-05 12:51:46 +00:00
										 |  |  |  |                   ip46tables -A nixos-fw -p udp --dport ${toString port} -j nixos-fw-accept | 
					
						
							| 
									
										
										
										
											2011-03-09 16:37:16 +00:00
										 |  |  |  |                 ''
 | 
					
						
							| 
									
										
										
										
											2011-03-10 09:39:17 +00:00
										 |  |  |  |               ) cfg.allowedUDPPorts | 
					
						
							| 
									
										
										
										
											2011-03-09 16:37:16 +00:00
										 |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-19 05:19:19 -06:00
										 |  |  |  |             # Accept packets on the allowed UDP port ranges. | 
					
						
							|  |  |  |  |             ${concatMapStrings (rangeAttr: | 
					
						
							|  |  |  |  |                 let range = toString rangeAttr.from + ":" + toString rangeAttr.to; in | 
					
						
							|  |  |  |  |                 ''
 | 
					
						
							|  |  |  |  |                   ip46tables -A nixos-fw -p udp --dport ${range} -j nixos-fw-accept | 
					
						
							|  |  |  |  |                 ''
 | 
					
						
							|  |  |  |  |               ) cfg.allowedUDPPortRanges | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-09 14:41:48 +00:00
										 |  |  |  |             # Accept IPv4 multicast.  Not a big security risk since | 
					
						
							| 
									
										
										
										
											2009-08-10 18:25:09 +00:00
										 |  |  |  |             # probably nobody is listening anyway. | 
					
						
							| 
									
										
										
										
											2011-07-05 12:51:46 +00:00
										 |  |  |  |             #iptables -A nixos-fw -d 224.0.0.0/4 -j nixos-fw-accept | 
					
						
							| 
									
										
										
										
											2009-08-10 18:25:09 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-11 11:08:16 +00:00
										 |  |  |  |             # Optionally respond to ICMPv4 pings. | 
					
						
							| 
									
										
										
										
											2011-03-09 15:28:47 +00:00
										 |  |  |  |             ${optionalString cfg.allowPing ''
 | 
					
						
							| 
									
										
										
										
											2014-04-11 16:29:45 +02:00
										 |  |  |  |               iptables -w -A nixos-fw -p icmp --icmp-type echo-request ${optionalString (cfg.pingLimit != null) | 
					
						
							| 
									
										
										
										
											2014-03-14 14:55:30 -04:00
										 |  |  |  |                 "-m limit ${cfg.pingLimit} " | 
					
						
							|  |  |  |  |               }-j nixos-fw-accept | 
					
						
							| 
									
										
										
										
											2011-03-09 15:28:47 +00:00
										 |  |  |  |             ''}
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-11 11:08:16 +00:00
										 |  |  |  |             # Accept all ICMPv6 messages except redirects and node | 
					
						
							|  |  |  |  |             # information queries (type 139).  See RFC 4890, section | 
					
						
							|  |  |  |  |             # 4.4. | 
					
						
							| 
									
										
										
										
											2012-10-19 15:21:06 -04:00
										 |  |  |  |             ${optionalString config.networking.enableIPv6 ''
 | 
					
						
							|  |  |  |  |               ip6tables -A nixos-fw -p icmpv6 --icmpv6-type redirect -j DROP | 
					
						
							|  |  |  |  |               ip6tables -A nixos-fw -p icmpv6 --icmpv6-type 139 -j DROP | 
					
						
							|  |  |  |  |               ip6tables -A nixos-fw -p icmpv6 -j nixos-fw-accept | 
					
						
							|  |  |  |  |             ''}
 | 
					
						
							| 
									
										
										
										
											2011-03-11 11:08:16 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-11 13:04:17 +00:00
										 |  |  |  |             ${cfg.extraCommands} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-09 15:11:01 +00:00
										 |  |  |  |             # Reject/drop everything else. | 
					
						
							| 
									
										
										
										
											2011-07-05 12:51:46 +00:00
										 |  |  |  |             ip46tables -A nixos-fw -j nixos-fw-log-refuse | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             # Enable the firewall. | 
					
						
							|  |  |  |  |             ip46tables -A INPUT -j nixos-fw | 
					
						
							| 
									
										
										
										
											2009-07-24 23:12:52 +00:00
										 |  |  |  |           '';
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         postStop = | 
					
						
							|  |  |  |  |           ''
 | 
					
						
							| 
									
										
										
										
											2011-07-05 12:51:46 +00:00
										 |  |  |  |             ${helpers} | 
					
						
							|  |  |  |  |             ip46tables -D INPUT -j nixos-fw || true | 
					
						
							|  |  |  |  |             #ip46tables -P INPUT ACCEPT | 
					
						
							| 
									
										
										
										
											2011-03-09 12:28:44 +00:00
										 |  |  |  |           '';
 | 
					
						
							| 
									
										
										
										
											2009-07-24 23:12:52 +00:00
										 |  |  |  |       }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | } |