summaryrefslogtreecommitdiffstats
path: root/nixos
diff options
context:
space:
mode:
authorEmery Hemingway <emery@vfemail.net>2014-10-26 15:15:48 -0400
committerAristid Breitkreuz <aristidb@gmail.com>2014-11-08 23:39:02 +0100
commit67a2a58314274ec5865d49198700eefd2c1a22a9 (patch)
treeb0a17f20908bef5ec22877fd1cffe7224f4155ea /nixos
parent9b4ba66ac3d1ac3dba325fcb1db45c8f7a57e103 (diff)
cjdns: service tweaks, new NixOS test
Diffstat (limited to 'nixos')
-rw-r--r--nixos/modules/services/networking/cjdns.nix48
-rw-r--r--nixos/release.nix1
-rw-r--r--nixos/tests/cjdns.nix123
3 files changed, 148 insertions, 24 deletions
diff --git a/nixos/modules/services/networking/cjdns.nix b/nixos/modules/services/networking/cjdns.nix
index 9888419309c1..be0acb27324a 100644
--- a/nixos/modules/services/networking/cjdns.nix
+++ b/nixos/modules/services/networking/cjdns.nix
@@ -204,8 +204,29 @@ in
systemd.services.cjdns = {
description = "encrypted networking for everybody";
- wantedBy = [ "multi-user.target" ];
- after = [ "network-interfaces.target" ];
+ wantedBy = [ "network.target" ];
+ after = [ "networkSetup.service" "network-interfaces.target" ];
+
+ preStart = if cfg.confFile != "" then "" else ''
+ [ -e /etc/cjdns.keys ] && source /etc/cjdns.keys
+
+ if [ -z "$CJDNS_PRIVATE_KEY" ]; then
+ shopt -s lastpipe
+ ${pkg}/bin/makekeys | { read private ipv6 public; }
+
+ umask 0077
+ echo "CJDNS_PRIVATE_KEY=$private" >> /etc/cjdns.keys
+ echo -e "CJDNS_IPV6=$ipv6\nCJDNS_PUBLIC_KEY=$public" > /etc/cjdns.public
+
+ chmod 600 /etc/cjdns.keys
+ chmod 444 /etc/cjdns.public
+ fi
+
+ if [ -z "$CJDNS_ADMIN_PASSWORD" ]; then
+ echo "CJDNS_ADMIN_PASSWORD=$(${pkgs.coreutils}/bin/head -c 96 /dev/urandom | ${pkgs.coreutils}/bin/tr -dc A-Za-z0-9)" \
+ >> /etc/cjdns.keys
+ fi
+ '';
script = (
if cfg.confFile != "" then "${pkg}/bin/cjdroute < ${cfg.confFile}" else
@@ -224,27 +245,6 @@ in
};
};
- 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 || \
- 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
- '';
-
networking.extraHosts = "${cjdnsHosts}";
assertions = [
@@ -258,4 +258,4 @@ in
};
-} \ No newline at end of file
+}
diff --git a/nixos/release.nix b/nixos/release.nix
index cb79dd3a226b..5a89b38acc77 100644
--- a/nixos/release.nix
+++ b/nixos/release.nix
@@ -235,6 +235,7 @@ in rec {
tests.avahi = callTest tests/avahi.nix {};
tests.bittorrent = callTest tests/bittorrent.nix {};
tests.blivet = callTest tests/blivet.nix {};
+ tests.cjdns = callTest tests/cjdns.nix {};
tests.containers = callTest tests/containers.nix {};
tests.firefox = callTest tests/firefox.nix {};
tests.firewall = callTest tests/firewall.nix {};
diff --git a/nixos/tests/cjdns.nix b/nixos/tests/cjdns.nix
new file mode 100644
index 000000000000..7bb3863c683f
--- /dev/null
+++ b/nixos/tests/cjdns.nix
@@ -0,0 +1,123 @@
+let
+ carolKey = "2d2a338b46f8e4a8c462f0c385b481292a05f678e19a2b82755258cf0f0af7e2";
+ carolPubKey = "n932l3pjvmhtxxcdrqq2qpw5zc58f01vvjx01h4dtd1bb0nnu2h0.k";
+ carolPassword = "678287829ce4c67bc8b227e56d94422ee1b85fa11618157b2f591de6c6322b52";
+ carolIp4 = "192.168.0.9";
+
+ basicConfig =
+ { config, pkgs, ... }:
+ { services.cjdns.enable = true;
+
+ # Turning off DHCP isn't very realistic but makes
+ # the sequence of address assignment less stochastic.
+ networking.useDHCP = false;
+
+ networking.interfaces.eth1.prefixLength = 24;
+ # CJDNS output is incompatible with the XML log.
+ systemd.services.cjdns.serviceConfig.StandardOutput = "null";
+ #networking.firewall.enable = true;
+ networking.firewall.allowPing = true;
+ #networking.firewall.rejectPackets = true;
+ };
+
+in
+
+import ./make-test.nix {
+ name = "cjdns";
+
+ nodes = rec
+ { # Alice finds peers over over ETHInterface.
+ alice =
+ { config, ... }:
+ { imports = [ basicConfig ];
+
+ services.cjdns.ETHInterface.bind = "eth1";
+
+ services.httpd.enable = true;
+ services.httpd.adminAddr = "foo@example.org";
+ networking.firewall.allowedTCPPorts = [ 80 ];
+ };
+
+ # Bob explicitly connects to Carol over UDPInterface.
+ bob =
+ { config, lib, nodes, ... }:
+
+ let carolIp4 = lib.mkForce nodes.carol.config.networking.interfaces.eth1; in
+
+ { imports = [ basicConfig ];
+
+ networking.interfaces.eth1.ipAddress = "192.168.0.2";
+
+ services.cjdns =
+ { UDPInterface =
+ { bind = "0.0.0.0:1024";
+ connectTo."192.168.0.1:1024}" =
+ { hostname = "carol.hype";
+ password = carolPassword;
+ publicKey = carolPubKey;
+ };
+ };
+ };
+ };
+
+ # Carol listens on ETHInterface and UDPInterface,
+ # but knows neither Alice or Bob.
+ carol =
+ { config, lib, nodes, ... }:
+ let
+ carolIp4 = (lib.mkForce nodes.carol.config.networking.interfaces.eth1);
+ in
+ { imports = [ basicConfig ];
+
+ environment.etc."cjdns.keys".text = ''
+ CJDNS_PRIVATE_KEY=${carolKey}
+ CJDNS_ADMIN_PASSWORD=FOOBAR
+ '';
+
+ networking.interfaces.eth1.ipAddress = "192.168.0.1";
+
+ services.cjdns =
+ { authorizedPasswords = [ carolPassword ];
+ ETHInterface.bind = "eth1";
+ UDPInterface.bind = "192.168.0.1:1024";
+ };
+ networking.firewall.allowedUDPPorts = [ 1024 ];
+ };
+
+ };
+
+ testScript =
+ ''
+ startAll;
+
+ $alice->waitForUnit("cjdns.service");
+ $bob->waitForUnit("cjdns.service");
+ $carol->waitForUnit("cjdns.service");
+
+ sub cjdnsIp {
+ my ($machine) = @_;
+ my $ip = (split /[ \/]+/, $machine->succeed("ip -o -6 addr show dev tun0"))[3];
+ $machine->log("has ip $ip");
+ return $ip;
+ }
+
+ my $aliceIp6 = cjdnsIp $alice;
+ my $bobIp6 = cjdnsIp $bob;
+ my $carolIp6 = cjdnsIp $carol;
+
+ # ping a few times each to let the routing table establish itself
+
+ $alice->succeed("ping6 -c 4 $carolIp6");
+ $bob->succeed("ping6 -c 4 carol.hype");
+
+ $carol->succeed("ping6 -c 4 $aliceIp6");
+ $carol->succeed("ping6 -c 4 $bobIp6");
+
+ $alice->succeed("ping6 -c 4 $bobIp6");
+ $bob->succeed("ping6 -c 4 $aliceIp6");
+
+ $alice->waitForUnit("httpd.service");
+
+ $bob->succeed("curl --fail -g http://[$aliceIp6]");
+ '';
+}