Author: eelco
Date: Thu Mar 10 12:08:39 2011
New Revision: 26246
URL: https://svn.nixos.org/websvn/nix/?rev=26246&sc=1

Log:
* Add a module for doing Network Address Translation.

Added:
   nixos/trunk/modules/services/networking/nat.nix
Modified:
   nixos/trunk/modules/module-list.nix
   nixos/trunk/tests/nat.nix

Modified: nixos/trunk/modules/module-list.nix
==============================================================================
--- nixos/trunk/modules/module-list.nix Thu Mar 10 11:39:37 2011        (r26245)
+++ nixos/trunk/modules/module-list.nix Thu Mar 10 12:08:39 2011        (r26246)
@@ -99,6 +99,7 @@
   ./services/networking/gw6c.nix
   ./services/networking/ifplugd.nix
   ./services/networking/ircd-hybrid.nix
+  ./services/networking/nat.nix
   ./services/networking/ntpd.nix
   ./services/networking/openfire.nix
   ./services/networking/openvpn.nix

Added: nixos/trunk/modules/services/networking/nat.nix
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ nixos/trunk/modules/services/networking/nat.nix     Thu Mar 10 12:08:39 
2011        (r26246)
@@ -0,0 +1,95 @@
+# This module enables Network Address Translation (NAT).
+
+{ config, pkgs, ... }:
+
+with pkgs.lib;
+
+let
+
+  cfg = config.networking.nat;
+
+in
+
+{
+
+  ###### interface
+
+  options = {
+  
+    networking.nat.enable = mkOption {
+      default = false;
+      description =
+        ''
+          Whether to enable Network Address Translation (NAT).
+        '';
+    };
+  
+    networking.nat.internalIPs = mkOption {
+      example = "192.168.1.0/24";
+      description =
+        ''
+          The IP address range for which to perform NAT.  Packets
+          coming from these addresses and destined for the external
+          interface will be rewritten.
+        '';
+    };
+  
+    networking.nat.externalInterface = mkOption {
+      example = "eth1";
+      description =
+        ''
+          The name of the external network interface.
+        '';
+    };
+  
+    networking.nat.externalIP = mkOption {
+      default = "";
+      example = "203.0.113.123";
+      description =
+        ''
+          The public IP address to which packets from the local
+          network are to be rewritten.  If this is left empty, the
+          IP address associated with the external interface will be
+          used.
+        '';
+    };
+  
+  };
+
+
+  ###### implementation
+
+  config = mkIf config.networking.nat.enable {
+
+    environment.systemPackages = [ pkgs.iptables ];
+
+    jobs.nat =
+      { description = "Network Address Translation";
+
+        startOn = "started network-interfaces";
+
+        path = [ pkgs.iptables ];
+
+        preStart =
+          ''
+            iptables -t nat -F
+            iptables -t nat -X
+
+            iptables -t nat -A POSTROUTING \
+              -s ${cfg.internalIPs} -o ${cfg.externalInterface} \
+              ${if cfg.externalIP == ""
+                then "-j MASQUERADE"
+                else "-j SNAT --to-source ${cfg.externalIP}"}
+
+            echo 1 > /proc/sys/net/ipv4/ip_forward
+          '';
+
+        postStop =
+          ''
+            iptables -t nat -F
+          '';
+      };
+
+  };
+
+}

Modified: nixos/trunk/tests/nat.nix
==============================================================================
--- nixos/trunk/tests/nat.nix   Thu Mar 10 11:39:37 2011        (r26245)
+++ nixos/trunk/tests/nat.nix   Thu Mar 10 12:08:39 2011        (r26246)
@@ -19,7 +19,9 @@
       router = 
         { config, pkgs, ... }:
         { virtualisation.vlans = [ 2 1 ];
-          environment.systemPackages = [ pkgs.iptables ];
+          networking.nat.enable = true;
+          networking.nat.internalIPs = "192.168.1.0/24";
+          networking.nat.externalInterface = "eth1";
         };
 
       server = 
@@ -37,22 +39,25 @@
 
       # The router should have access to the server.
       $server->waitForJob("httpd");
-      $router->mustSucceed("curl --fail http://server/ >&2");
+      $router->succeed("curl --fail http://server/ >&2");
 
-      # But the client shouldn't be able to reach the server.
-      $client->mustFail("curl --fail --connect-timeout 5 http://server/ >&2");
+      # The client should be also able to connect via the NAT router.
+      $router->waitForJob("nat");
+      $client->succeed("curl --fail http://server/ >&2");
+      $client->succeed("ping -c 1 server >&2");
+      
+      # If we turn off NAT, the client shouldn't be able to reach the server.
+      $router->succeed("stop nat");
+      $client->fail("curl --fail --connect-timeout 5 http://server/ >&2");
+      $client->fail("ping -c 1 server >&2");
+
+      # And make sure that restarting the NAT job works.
+      $router->succeed("start nat");
+      $client->succeed("curl --fail http://server/ >&2");
+      $client->succeed("ping -c 1 server >&2");
 
-      # Enable NAT on the router.
-      $router->mustSucceed(
-          "iptables -t nat -F",
-          "iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -d 192.168.1.0/24 
-j ACCEPT",
-          "iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j SNAT "
-          . "--to-source 
${nodes.router.config.networking.ifaces.eth1.ipAddress}",
-          "echo 1 > /proc/sys/net/ipv4/ip_forward"
-      );
-
-      # Now the client should be able to connect.
-      $client->mustSucceed("curl --fail http://server/ >&2");
+      $client->succeed("ping -c 1 router >&2");
+      $router->succeed("ping -c 1 client >&2");
     '';
 
 }
_______________________________________________
nix-commits mailing list
[email protected]
http://mail.cs.uu.nl/mailman/listinfo/nix-commits

Reply via email to