From a34bfbab4cac9d7abcab88a47694e1cc32111dba Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 10 Apr 2014 14:23:38 +0200 Subject: [PATCH] Add option networking.nat.internalInterfaces This allows applying NAT to an interface, rather than an IP range. --- nixos/modules/services/networking/nat.nix | 55 +++++++++++++++++------ 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/nixos/modules/services/networking/nat.nix b/nixos/modules/services/networking/nat.nix index ce28f0188284..d684d8e31222 100644 --- a/nixos/modules/services/networking/nat.nix +++ b/nixos/modules/services/networking/nat.nix @@ -10,6 +10,8 @@ let cfg = config.networking.nat; + dest = if cfg.externalIP == null then "-j MASQUERADE" else "-j SNAT --to-source ${cfg.externalIP}"; + in { @@ -27,14 +29,27 @@ in ''; }; + networking.nat.internalInterfaces = mkOption { + type = types.listOf types.str; + default = []; + example = [ "eth0" ]; + description = + '' + The interfaces for which to perform NAT. Packets coming from + these interface and destined for the external interface will + be rewritten. + ''; + }; + networking.nat.internalIPs = mkOption { type = types.listOf types.str; - example = [ "192.168.1.0/24" ] ; + default = []; + example = [ "192.168.1.0/24" ]; description = '' The IP address ranges for which to perform NAT. Packets - coming from these networks and destined for the external - interface will be rewritten. + coming from these addresses (on any interface) and destined + for the external interface will be rewritten. ''; }; @@ -80,25 +95,37 @@ in preStart = '' + iptables -t nat -F PREROUTING iptables -t nat -F POSTROUTING iptables -t nat -X - '' - + (concatMapStrings (network: - '' - iptables -t nat -A POSTROUTING \ - -s ${network} -o ${cfg.externalInterface} \ - ${if cfg.externalIP == null - then "-j MASQUERADE" - else "-j SNAT --to-source ${cfg.externalIP}"} - '' - ) cfg.internalIPs) + - '' + + # We can't match on incoming interface in POSTROUTING, so + # mark packets coming from the external interfaces. + ${concatMapStrings (iface: '' + iptables -t nat -A PREROUTING \ + -i '${iface}' -j MARK --set-mark 1 + '') cfg.internalInterfaces} + + # NAT the marked packets. + ${optionalString (cfg.internalInterfaces != []) '' + iptables -t nat -A POSTROUTING -m mark --mark 1 \ + -o ${cfg.externalInterface} ${dest} + ''} + + # NAT packets coming from the internal IPs. + ${concatMapStrings (range: '' + iptables -t nat -A POSTROUTING \ + -s '${range}' -o ${cfg.externalInterface} ${dest}} + '') cfg.internalIPs} + echo 1 > /proc/sys/net/ipv4/ip_forward ''; postStop = '' + iptables -t nat -F PREROUTING iptables -t nat -F POSTROUTING + iptables -t nat -X ''; }; };