From 328f8a6cba42deb0b3ac0e5f30818739497668d5 Mon Sep 17 00:00:00 2001 From: volth Date: Mon, 19 Feb 2018 01:29:51 +0000 Subject: [PATCH] nixos/nat: support nat reflection --- nixos/modules/services/networking/nat.nix | 33 ++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/nixos/modules/services/networking/nat.nix b/nixos/modules/services/networking/nat.nix index df4246d216d8..da3827c35e63 100644 --- a/nixos/modules/services/networking/nat.nix +++ b/nixos/modules/services/networking/nat.nix @@ -53,12 +53,36 @@ let -i ${cfg.externalInterface} -p ${fwd.proto} \ --dport ${builtins.toString fwd.sourcePort} \ -j DNAT --to-destination ${fwd.destination} + + ${concatMapStrings (loopbackip: + let + m = builtins.match "([0-9.]+):([0-9-]+)" fwd.destination; + destinationIP = if (m == null) then throw "bad ip:ports `${fwd.destination}'" else elemAt m 0; + destinationPorts = if (m == null) then throw "bad ip:ports `${fwd.destination}'" else elemAt m 1; + in '' + # Allow connections to ${loopbackip}:${toString fwd.sourcePort} from the host itself + iptables -w -t nat -A OUTPUT \ + -d ${loopbackip} -p ${fwd.proto} \ + --dport ${builtins.toString fwd.sourcePort} \ + -j DNAT --to-destination ${fwd.destination} + + # Allow connections to ${loopbackip}:${toString fwd.sourcePort} from other hosts behind NAT + iptables -w -t nat -A nixos-nat-pre \ + -d ${loopbackip} -p ${fwd.proto} \ + --dport ${builtins.toString fwd.sourcePort} \ + -j DNAT --to-destination ${fwd.destination} + + iptables -w -t nat -A nixos-nat-post \ + -d ${destinationIP} -p ${fwd.proto} \ + --dport ${destinationPorts} \ + -j SNAT --to-source ${loopbackip} + '') fwd.loopbackIPs} '') cfg.forwardPorts} ${optionalString (cfg.dmzHost != null) '' iptables -w -t nat -A nixos-nat-pre \ -i ${cfg.externalInterface} -j DNAT \ - --to-destination ${cfg.dmzHost} + --to-destination ${cfg.dmzHost} ''} ${cfg.extraCommands} @@ -152,6 +176,13 @@ in example = "udp"; description = "Protocol of forwarded connection"; }; + + loopbackIPs = mkOption { + type = types.listOf types.str; + default = []; + example = literalExample ''[ "55.1.2.3" ]''; + description = "Public IPs for NAT reflection; for connections to `loopbackip:sourcePort' from the host itself and from other hosts behind NAT"; + }; }; }); default = [];