about summary refs log tree commit diff
path: root/nixos/modules/services/networking/cjdns.nix
diff options
context:
space:
mode:
authorEmery Hemingway <emery@vfemail.net>2014-10-21 13:16:04 -0400
committerEmery Hemingway <emery@vfemail.net>2014-10-21 13:16:04 -0400
commita3338abcfe3a05ab5d1f4b7f7619e50f24652929 (patch)
treed16610f257262c76aa46ba53587ecd8a208f1d74 /nixos/modules/services/networking/cjdns.nix
parent70e057788623556cfeabb9fd16404538c72fe4ac (diff)
downloadnixlib-a3338abcfe3a05ab5d1f4b7f7619e50f24652929.tar
nixlib-a3338abcfe3a05ab5d1f4b7f7619e50f24652929.tar.gz
nixlib-a3338abcfe3a05ab5d1f4b7f7619e50f24652929.tar.bz2
nixlib-a3338abcfe3a05ab5d1f4b7f7619e50f24652929.tar.lz
nixlib-a3338abcfe3a05ab5d1f4b7f7619e50f24652929.tar.xz
nixlib-a3338abcfe3a05ab5d1f4b7f7619e50f24652929.tar.zst
nixlib-a3338abcfe3a05ab5d1f4b7f7619e50f24652929.zip
cjdns: add peer hostnames to extraHosts, option for external config
Diffstat (limited to 'nixos/modules/services/networking/cjdns.nix')
-rw-r--r--nixos/modules/services/networking/cjdns.nix194
1 files changed, 115 insertions, 79 deletions
diff --git a/nixos/modules/services/networking/cjdns.nix b/nixos/modules/services/networking/cjdns.nix
index 7192b8b7a0e0..9888419309c1 100644
--- a/nixos/modules/services/networking/cjdns.nix
+++ b/nixos/modules/services/networking/cjdns.nix
@@ -4,8 +4,46 @@ with lib;
 
 let
 
+  pkg = pkgs.cjdns;
+
   cfg = config.services.cjdns;
 
+  connectToSubmodule =
+  { options, ... }:
+  { options =
+    { password = mkOption {
+      type = types.str;
+      description = "Authorized password to the opposite end of the tunnel.";
+      };
+      publicKey = mkOption {
+        type = types.str;
+        description = "Public key at the opposite end of the tunnel.";
+      };
+      hostname = mkOption {
+        default = "";
+        example = "foobar.hype";
+        type = types.str;
+        description = "Optional hostname to add to /etc/hosts; prevents reverse lookup failures.";
+      };
+    };
+  };
+
+  peers = mapAttrsToList (n: v: v) (cfg.ETHInterface.connectTo // cfg.UDPInterface.connectTo);
+
+  pubs  = toString (map (p: if p.hostname == "" then "" else p.publicKey) peers);
+  hosts = toString (map (p: if p.hostname == "" then "" else p.hostname)  peers);
+
+  cjdnsHosts =
+    if hosts != "" then
+      import (pkgs.stdenv.mkDerivation {
+        name = "cjdns-hosts";
+        builder = ./cjdns-hosts.sh;
+
+        inherit (pkgs) cjdns;
+        inherit pubs hosts;
+      })
+    else "";
+
   # would be nice to  merge 'cfg' with a //,
   # but the json nesting is wacky.
   cjdrouteConf = builtins.toJSON ( {
@@ -44,7 +82,7 @@ in
 
       enable = mkOption {
         type = types.bool;
-	default = false;
+        default = false;
         description = ''
           Whether to enable the cjdns network encryption
           and routing engine. A file at /etc/cjdns.keys will
@@ -53,84 +91,80 @@ in
         '';
       };
 
+      confFile = mkOption {
+        type = types.str;
+        default = "";
+        example = "/etc/cjdroute.conf";
+        description = ''
+          Ignore all other cjdns options and load configuration from this file.
+        '';
+      };
+
       authorizedPasswords = mkOption {
         type = types.listOf types.str;
-	default = [ ];
-	example = [
+        default = [ ];
+        example = [
           "snyrfgkqsc98qh1y4s5hbu0j57xw5s0"
-	  "z9md3t4p45mfrjzdjurxn4wuj0d8swv"
-	  "49275fut6tmzu354pq70sr5b95qq0vj"
+          "z9md3t4p45mfrjzdjurxn4wuj0d8swv"
+          "49275fut6tmzu354pq70sr5b95qq0vj"
         ];
-	description = ''
-	  Any remote cjdns nodes that offer these passwords on 
-	  connection will be allowed to route through this node.
+        description = ''
+          Any remote cjdns nodes that offer these passwords on 
+          connection will be allowed to route through this node.
         '';
       };
     
       admin = {
         bind = mkOption {
           type = types.string;
-	  default = "127.0.0.1:11234";
-	  description = ''
+          default = "127.0.0.1:11234";
+          description = ''
             Bind the administration port to this address and port.
-	  '';
+          '';
         };
       };
 
       UDPInterface = {
         bind = mkOption {
           type = types.string;
-	  default = "";
+          default = "";
           example = "192.168.1.32:43211";
           description = ''
-	    Address and port to bind UDP tunnels to.
-	  '';
- 	};
+            Address and port to bind UDP tunnels to.
+          '';
+         };
         connectTo = mkOption {
-          type = types.attrsOf ( types.submodule (
-	    { options, ... }:
-            { options = {
-                # TODO make host an option, and add it to networking.extraHosts
-                password = mkOption {
-                  type = types.str;
-                  description = "Authorized password to the opposite end of the tunnel.";
-                };
-                publicKey = mkOption {
-                  type = types.str;
-                  description = "Public key at the opposite end of the tunnel.";
-                };
-              };
-            }
-          ));
-	  default = { };
+          type = types.attrsOf ( types.submodule ( connectToSubmodule ) );
+          default = { };
           example = {
             "192.168.1.1:27313" = {
-	      password = "5kG15EfpdcKNX3f2GSQ0H1HC7yIfxoCoImnO5FHM";
+              hostname = "homer.hype";
+              password = "5kG15EfpdcKNX3f2GSQ0H1HC7yIfxoCoImnO5FHM";
               publicKey = "371zpkgs8ss387tmr81q04mp0hg1skb51hw34vk1cq644mjqhup0.k";
             };
           };
           description = ''
-	    Credentials for making UDP tunnels.
-	  '';
-	};
+            Credentials for making UDP tunnels.
+          '';
+        };
       };
 
       ETHInterface = {
         bind = mkOption {
-	  default = "";
-	  example = "eth0";
-	  description = ''
-	    Bind to this device for native ethernet operation.
-	  '';
-        };
+        default = "";
+        example = "eth0";
+        description = ''
+          Bind to this device for native ethernet operation.
+        '';
+      };
 
         beacon = mkOption {
-	  type = types.int;
+          type = types.int;
           default = 2;
           description = ''
             Auto-connect to other cjdns nodes on the same network.
             Options:
-	      0: Disabled.
+              0: Disabled.
               1: Accept beacons, this will cause cjdns to accept incoming
                  beacon messages and try connecting to the sender.
               2: Accept and send beacons, this will cause cjdns to broadcast
@@ -142,32 +176,20 @@ in
         };
 
         connectTo = mkOption {
-          type = types.attrsOf ( types.submodule (
-	    { options, ... }:
-            { options = {
-                password = mkOption {
-                  type = types.str;
-                  description = "Authorized password to the opposite end of the tunnel.";
-                };
-                publicKey = mkOption {
-                  type = types.str;
-                  description = "Public key at the opposite end of the tunnel.";
-                };
-              };
-            }
-          ));
-	  default = { };
+          type = types.attrsOf ( types.submodule ( connectToSubmodule ) );
+          default = { };
           example = {
             "01:02:03:04:05:06" = {
-	      password = "5kG15EfpdcKNX3f2GSQ0H1HC7yIfxoCoImnO5FHM";
+              hostname = "homer.hype";
+              password = "5kG15EfpdcKNX3f2GSQ0H1HC7yIfxoCoImnO5FHM";
               publicKey = "371zpkgs8ss387tmr81q04mp0hg1skb51hw34vk1cq644mjqhup0.k";
             };
           };
-	  description = ''
-	    Credentials for connecting look similar to UDP credientials
+          description = ''
+            Credentials for connecting look similar to UDP credientials
             except they begin with the mac address.
-	  '';
-	};
+          '';
+        };
       };
 
     };
@@ -185,34 +207,48 @@ in
       wantedBy = [ "multi-user.target" ];
       after = [ "network-interfaces.target" ];
 
-      script = ''
-        source /etc/cjdns.keys
-        echo '${cjdrouteConf}' | sed \
-	  -e "s/@CJDNS_ADMIN_PASSWORD@/$CJDNS_ADMIN_PASSWORD/g" \
-          -e "s/@CJDNS_PRIVATE_KEY@/$CJDNS_PRIVATE_KEY/g" \
-            | ${pkgs.cjdns}/bin/cjdroute
-      '';
+      script = (
+        if cfg.confFile != "" then "${pkg}/bin/cjdroute < ${cfg.confFile}" else
+          ''
+            source /etc/cjdns.keys
+            echo '${cjdrouteConf}' | sed \
+                -e "s/@CJDNS_ADMIN_PASSWORD@/$CJDNS_ADMIN_PASSWORD/g" \
+                -e "s/@CJDNS_PRIVATE_KEY@/$CJDNS_PRIVATE_KEY/g" \
+                | ${pkg}/bin/cjdroute
+         ''
+      );
 
       serviceConfig = {
         Type = "forking";
-	Restart = "on-failure";
+        Restart = "on-failure";
       };
     };
 
-    system.activationScripts.cjdns = ''
+    system.activationScripts.cjdns = if (cfg.confFile == "") then "" else ''
+      cjdnsWriteKeys() {
+        private=$1
+        ipv6=$2
+        public=$3
+
+        echo "CJDNS_PRIVATE_KEY=$1" >> /etc/cjdns.keys
+        echo -e "CJDNS_IPV6=$2\nCJDNS_PUBLIC_KEY=$3" > /etc/cjdns.public
+
+        chmod 600 /etc/cjdns.keys
+        chmod 444 /etc/cjdns.public
+      }
+
       grep -q "CJDNS_PRIVATE_KEY=" /etc/cjdns.keys || \
-        echo "CJDNS_PRIVATE_KEY=$(${pkgs.cjdns}/bin/makekey)" \
-	  >> /etc/cjdns.keys
+          cjdnsWriteKeys $(${pkg}/bin/makekeys)
 
       grep -q "CJDNS_ADMIN_PASSWORD=" /etc/cjdns.keys || \
-        echo "CJDNS_ADMIN_PASSWORD=$(${pkgs.coreutils}/bin/head -c 96 /dev/urandom | ${pkgs.coreutils}/bin/tr -dc A-Za-z0-9)" \
-	  >> /etc/cjdns.keys
-
-      chmod 600 /etc/cjdns.keys
+          echo "CJDNS_ADMIN_PASSWORD=$(${pkgs.coreutils}/bin/head -c 96 /dev/urandom | ${pkgs.coreutils}/bin/tr -dc A-Za-z0-9)" \
+          >> /etc/cjdns.keys
     '';
 
+    networking.extraHosts = "${cjdnsHosts}";
+
     assertions = [
-      { assertion = ( cfg.ETHInterface.bind != "" || cfg.UDPInterface.bind != "" );
+      { assertion = ( cfg.ETHInterface.bind != "" || cfg.UDPInterface.bind != "" || cfg.confFile == "" );
         message = "Neither cjdns.ETHInterface.bind nor cjdns.UDPInterface.bind defined.";
       }
       { assertion = config.networking.enableIPv6;