From 6a43d512918e6449cb55fd10cdf7baf634e0ed87 Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Mon, 15 Sep 2014 21:29:46 -0700 Subject: [PATCH 1/2] nixos/firewall: Support extraStopCommands --- nixos/modules/services/networking/firewall.nix | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/nixos/modules/services/networking/firewall.nix b/nixos/modules/services/networking/firewall.nix index b97ec8b4d43a..eaf48b9c6e5b 100644 --- a/nixos/modules/services/networking/firewall.nix +++ b/nixos/modules/services/networking/firewall.nix @@ -240,6 +240,18 @@ in ''; }; + networking.firewall.extraStopCommands = mkOption { + type = types.lines; + default = ""; + example = "iptables -P INPUT ACCEPT"; + description = + '' + Additional shell commands executed as part of the firewall + shutdown script. These are executed just after the removal + of the nixos input rule. + ''; + }; + }; @@ -432,6 +444,7 @@ in '' ${helpers} ip46tables -D INPUT -j nixos-fw || true + ${cfg.extraStopCommands} ''; }; From 1321fd175d850052b6e76ed5724d30d7716c1bda Mon Sep 17 00:00:00 2001 From: "William A. Kennington III" Date: Mon, 15 Sep 2014 19:03:47 -0700 Subject: [PATCH 2/2] nixos/nat: Leverage firewall module --- nixos/modules/services/networking/nat.nix | 114 ++++++++++++---------- 1 file changed, 63 insertions(+), 51 deletions(-) diff --git a/nixos/modules/services/networking/nat.nix b/nixos/modules/services/networking/nat.nix index 4a4c06503c29..35e376e7b3a6 100644 --- a/nixos/modules/services/networking/nat.nix +++ b/nixos/modules/services/networking/nat.nix @@ -12,6 +12,41 @@ let dest = if cfg.externalIP == null then "-j MASQUERADE" else "-j SNAT --to-source ${cfg.externalIP}"; + flushNat = '' + iptables -w -t nat -F PREROUTING + iptables -w -t nat -F POSTROUTING + iptables -w -t nat -X + ''; + + setupNat = '' + # We can't match on incoming interface in POSTROUTING, so + # mark packets coming from the external interfaces. + ${concatMapStrings (iface: '' + iptables -w -t nat -A PREROUTING \ + -i '${iface}' -j MARK --set-mark 1 + '') cfg.internalInterfaces} + + # NAT the marked packets. + ${optionalString (cfg.internalInterfaces != []) '' + iptables -w -t nat -A POSTROUTING -m mark --mark 1 \ + -o ${cfg.externalInterface} ${dest} + ''} + + # NAT packets coming from the internal IPs. + ${concatMapStrings (range: '' + iptables -w -t nat -A POSTROUTING \ + -s '${range}' -o ${cfg.externalInterface} ${dest} + '') cfg.internalIPs} + + # NAT from external ports to internal ports. + ${concatMapStrings (fwd: '' + iptables -w -t nat -A PREROUTING \ + -i ${cfg.externalInterface} -p tcp \ + --dport ${builtins.toString fwd.sourcePort} \ + -j DNAT --to-destination ${fwd.destination} + '') cfg.forwardPorts} + ''; + in { @@ -109,57 +144,34 @@ in environment.systemPackages = [ pkgs.iptables ]; - boot.kernelModules = [ "nf_nat_ftp" ]; - - jobs.nat = - { description = "Network Address Translation"; - - startOn = "started network-interfaces"; - - path = [ pkgs.iptables ]; - - preStart = - '' - iptables -w -t nat -F PREROUTING - iptables -w -t nat -F POSTROUTING - iptables -w -t nat -X - - # We can't match on incoming interface in POSTROUTING, so - # mark packets coming from the external interfaces. - ${concatMapStrings (iface: '' - iptables -w -t nat -A PREROUTING \ - -i '${iface}' -j MARK --set-mark 1 - '') cfg.internalInterfaces} - - # NAT the marked packets. - ${optionalString (cfg.internalInterfaces != []) '' - iptables -w -t nat -A POSTROUTING -m mark --mark 1 \ - -o ${cfg.externalInterface} ${dest} - ''} - - # NAT packets coming from the internal IPs. - ${concatMapStrings (range: '' - iptables -w -t nat -A POSTROUTING \ - -s '${range}' -o ${cfg.externalInterface} ${dest} - '') cfg.internalIPs} - - # NAT from external ports to internal ports. - ${concatMapStrings (fwd: '' - iptables -w -t nat -A PREROUTING \ - -i ${cfg.externalInterface} -p tcp \ - --dport ${builtins.toString fwd.sourcePort} \ - -j DNAT --to-destination ${fwd.destination} - '') cfg.forwardPorts} - - echo 1 > /proc/sys/net/ipv4/ip_forward - ''; - - postStop = - '' - iptables -w -t nat -F PREROUTING - iptables -w -t nat -F POSTROUTING - iptables -w -t nat -X - ''; + boot = { + kernelModules = [ "nf_nat_ftp" ]; + kernel.sysctl = mkOverride 99 { + "net.ipv4.conf.all.forwarding" = true; + "net.ipv4.conf.default.forwarding" = true; }; + }; + + networking.firewall = mkIf config.networking.firewall.enable { + extraCommands = mkMerge [ (mkBefore flushNat) setupNat ]; + extraStopCommands = flushNat; + }; + + systemd.services = mkIf (!config.networking.firewall.enable) { nat = { + description = "Network Address Translation"; + wantedBy = [ "network.target" ]; + after = [ "network-interfaces.target" "systemd-modules-load.service" ]; + path = [ pkgs.iptables ]; + unitConfig.ConditionCapability = "CAP_NET_ADMIN"; + + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + + script = flushNat + setupNat; + + postStop = flushNat; + }; }; }; }