···
ip46tables -A nixos-fw -m conntrack --ctstate ESTABLISHED,RELATED -j nixos-fw-accept
# Accept connections to the allowed TCP ports.
+
${concatStrings (mapAttrsToList (iface: cfg:
+
concatMapStrings (port:
+
ip46tables -A nixos-fw -p tcp --dport ${toString port} -j nixos-fw-accept ${optionalString (iface != "default") "-i ${iface}"}
# Accept connections to the allowed TCP port ranges.
+
${concatStrings (mapAttrsToList (iface: cfg:
+
concatMapStrings (rangeAttr:
let range = toString rangeAttr.from + ":" + toString rangeAttr.to; in
+
ip46tables -A nixos-fw -p tcp --dport ${range} -j nixos-fw-accept ${optionalString (iface != "default") "-i ${iface}"}
) cfg.allowedTCPPortRanges
# Accept packets on the allowed UDP ports.
+
${concatStrings (mapAttrsToList (iface: cfg:
+
concatMapStrings (port:
+
ip46tables -A nixos-fw -p udp --dport ${toString port} -j nixos-fw-accept ${optionalString (iface != "default") "-i ${iface}"}
# Accept packets on the allowed UDP port ranges.
+
${concatStrings (mapAttrsToList (iface: cfg:
+
concatMapStrings (rangeAttr:
let range = toString rangeAttr.from + ":" + toString rangeAttr.to; in
+
ip46tables -A nixos-fw -p udp --dport ${range} -j nixos-fw-accept ${optionalString (iface != "default") "-i ${iface}"}
) cfg.allowedUDPPortRanges
# Accept IPv4 multicast. Not a big security risk since
# probably nobody is listening anyway.
···
+
allowedTCPPorts = mkOption {
type = types.listOf types.int;
List of TCP ports on which incoming connections are
+
allowedTCPPortRanges = mkOption {
type = types.listOf (types.attrsOf types.int);
example = [ { from = 8999; to = 9003; } ];
A range of TCP ports on which incoming connections are
+
allowedUDPPorts = mkOption {
type = types.listOf types.int;
···
+
allowedUDPPortRanges = mkOption {
type = types.listOf (types.attrsOf types.int);
example = [ { from = 60000; to = 61000; } ];
···
+
networking.firewall = {
+
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
+
logRefusedConnections = mkOption {
+
Whether to log rejected or dropped incoming connections.
+
logRefusedPackets = mkOption {
+
Whether to log all rejected or dropped incoming packets.
+
This tends to give a lot of log messages, so it's mostly
+
logRefusedUnicastsOnly = mkOption {
+
If <option>networking.firewall.logRefusedPackets</option>
+
and this option are enabled, then only log packets
+
specifically directed at this machine, i.e., not broadcasts
+
rejectPackets = mkOption {
+
If set, refused packets are rejected rather than dropped
+
(ignored). This means that an ICMP "port unreachable" error
+
message is sent back to the client (or a TCP RST packet in
+
case of an existing connection). Rejecting packets makes
+
port scanning somewhat easier.
+
trustedInterfaces = mkOption {
+
type = types.listOf types.str;
+
example = [ "enp0s2" ];
+
Traffic coming in from these interfaces will be accepted
+
unconditionally. Traffic from the loopback (lo) interface
+
will always be accepted.
+
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
+
type = types.nullOr (types.separatedString " ");
+
example = "--limit 1/minute --limit-burst 5";
+
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"
+
checkReversePath = mkOption {
+
type = types.either types.bool (types.enum ["strict" "loose"]);
+
default = kernelHasRPFilter;
+
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, set
+
this option to loose mode or disable it and setup your own
+
This option can be either true (or "strict"), "loose" (only
+
drop the packet if the source address is not reachable via any
+
interface) or false. Defaults to the value of
+
logReversePathDrops = mkOption {
+
Logs dropped packets failing the reverse path filter test if
+
the option networking.firewall.checkReversePath is enabled.
+
connectionTrackingModules = mkOption {
+
type = types.listOf types.str;
+
example = [ "ftp" "irc" "sane" "sip" "tftp" "amanda" "h323" "netbios_sn" "pptp" "snmp" ];
+
List of connection-tracking helpers that are auto-loaded.
+
The complete list of possible values is given in the example.
+
As helpers can pose as a security risk, it is advised to
+
set this to an empty list and disable the setting
+
networking.firewall.autoLoadConntrackHelpers unless you
+
know what you are doing. Connection tracking is disabled
+
Loading of helpers is recommended to be done through the
+
https://home.regit.org/netfilter-en/secure-use-of-helpers/
+
autoLoadConntrackHelpers = mkOption {
+
Whether to auto-load connection-tracking helpers.
+
See the description at networking.firewall.connectionTrackingModules
+
extraCommands = mkOption {
+
example = "iptables -A INPUT -p icmp -j ACCEPT";
+
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.
+
extraPackages = mkOption {
+
type = types.listOf types.package;
+
example = literalExample "[ pkgs.ipset ]";
+
Additional packages to be included in the environment of the system
+
as well as the path of networking.firewall.extraCommands.
+
extraStopCommands = mkOption {
+
example = "iptables -P INPUT ACCEPT";
+
Additional shell commands executed as part of the firewall
+
shutdown script. These are executed just after the removal
+
of the NixOS input rule, or if the service enters a failed
+
interfaces = mkOption {
+
default = mapAttrs (name: value: cfg."${name}") commonOptions;
+
type = with types; attrsOf (submodule [ { options = commonOptions; } ]);
+
Interface-specific open ports. Setting this value will override
+
all values of the <literal>networking.firewall.allowed*</literal>