summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
authorNikolay Amiantov <ab@fmap.me>2018-04-01 18:22:14 +0300
committerAustin Seipp <aseipp@pobox.com>2018-04-22 13:33:11 -0500
commit7c90a8677090bb144cc8db17aaf485def8d54a91 (patch)
tree15616075b5fb6346638418c40464194ecdb0f223 /nixos
parentfb7cdbc15d964f3a3b7337ed125fb2b5a20c30cc (diff)
downloadnixpkgs-7c90a8677090bb144cc8db17aaf485def8d54a91.tar
nixpkgs-7c90a8677090bb144cc8db17aaf485def8d54a91.tar.gz
nixpkgs-7c90a8677090bb144cc8db17aaf485def8d54a91.tar.bz2
nixpkgs-7c90a8677090bb144cc8db17aaf485def8d54a91.tar.lz
nixpkgs-7c90a8677090bb144cc8db17aaf485def8d54a91.tar.xz
nixpkgs-7c90a8677090bb144cc8db17aaf485def8d54a91.tar.zst
nixpkgs-7c90a8677090bb144cc8db17aaf485def8d54a91.zip
wireguard service: use scripts instead of ExecStarts/Stops
This is more in line with what other services do; also looks cleaner.
It changes configuration entries for pre-and post-hooks type to lines from
lists of strings which are more logical for them; coersion is provided for
backwards compatibility.

Finally, add several steps to improve robustness:

1. Load kernel module on start if not loaded;
2. Don't remove wireguard interface on start; it is removed on service stop. If
   it's not something is wrong.
Diffstat (limited to 'nixos')
-rw-r--r--nixos/modules/services/networking/wireguard.nix101
1 files changed, 51 insertions, 50 deletions
diff --git a/nixos/modules/services/networking/wireguard.nix b/nixos/modules/services/networking/wireguard.nix
index 24accd41511..0591917c742 100644
--- a/nixos/modules/services/networking/wireguard.nix
+++ b/nixos/modules/services/networking/wireguard.nix
@@ -53,30 +53,30 @@ let
       };
 
       preSetup = mkOption {
-        example = literalExample [''
+        example = literalExample ''
           ${pkgs.iproute}/bin/ip netns add foo
-        ''];
-        default = [];
-        type = with types; listOf str;
+        '';
+        default = "";
+        type = with types; coercedTo (listOf str) (concatStringsSep "\n") lines;
         description = ''
-          A list of commands called at the start of the interface setup.
+          Commands called at the start of the interface setup.
         '';
       };
 
       postSetup = mkOption {
-        example = literalExample [''
-          ${pkgs.bash} -c 'printf "nameserver 10.200.100.1" | ${pkgs.openresolv}/bin/resolvconf -a wg0 -m 0'
-        ''];
-        default = [];
-        type = with types; listOf str;
-        description = "A list of commands called at the end of the interface setup.";
+        example = literalExample ''
+          printf "nameserver 10.200.100.1" | ${pkgs.openresolv}/bin/resolvconf -a wg0 -m 0
+        '';
+        default = "";
+        type = with types; coercedTo (listOf str) (concatStringsSep "\n") lines;
+        description = "Commands called at the end of the interface setup.";
       };
 
       postShutdown = mkOption {
-        example = literalExample ["${pkgs.openresolv}/bin/resolvconf -d wg0"];
-        default = [];
-        type = with types; listOf str;
-        description = "A list of commands called after shutting down the interface.";
+        example = literalExample "${pkgs.openresolv}/bin/resolvconf -d wg0";
+        default = "";
+        type = with types; coercedTo (listOf str) (concatStringsSep "\n") lines;
+        description = "Commands called after shutting down the interface.";
       };
 
       table = mkOption {
@@ -182,9 +182,6 @@ let
 
   };
 
-  ipCommand = "${pkgs.iproute}/bin/ip";
-  wgCommand = "${pkgs.wireguard}/bin/wg";
-
   generateUnit = name: values:
     # exactly one way to specify the private key must be set
     assert (values.privateKey != null) != (values.privateKeyFile != null);
@@ -196,49 +193,53 @@ let
         after = [ "network.target" ];
         wantedBy = [ "multi-user.target" ];
         environment.DEVICE = name;
+        path = with pkgs; [ kmod iproute wireguard ];
 
         serviceConfig = {
           Type = "oneshot";
           RemainAfterExit = true;
-          ExecStart = flatten([
-            values.preSetup
+        };
+
+        script = ''
+          modprobe wireguard
+
+          ${values.preSetup}
 
-            "-${ipCommand} link del dev ${name}"
-            "${ipCommand} link add dev ${name} type wireguard"
+          ip link add dev ${name} type wireguard
 
-            (map (ip:
-            "${ipCommand} address add ${ip} dev ${name}"
-            ) values.ips)
+          ${concatMapStringsSep "\n" (ip:
+            "ip address add ${ip} dev ${name}"
+          ) values.ips}
 
-            ("${wgCommand} set ${name} private-key ${privKey}" +
-            optionalString (values.listenPort != null) " listen-port ${toString values.listenPort}")
+          wg set ${name} private-key ${privKey} ${
+            optionalString (values.listenPort != null) " listen-port ${toString values.listenPort}"}
 
-            (map (peer:
+          ${concatMapStringsSep "\n" (peer:
             assert (peer.presharedKeyFile == null) || (peer.presharedKey == null); # at most one of the two must be set
             let psk = if peer.presharedKey != null then pkgs.writeText "wg-psk" peer.presharedKey else peer.presharedKeyFile;
             in
-            "${wgCommand} set ${name} peer ${peer.publicKey}" +
-            optionalString (psk != null) " preshared-key ${psk}" +
-            optionalString (peer.endpoint != null) " endpoint ${peer.endpoint}" +
-            optionalString (peer.persistentKeepalive != null) " persistent-keepalive ${toString peer.persistentKeepalive}" +
-            optionalString (peer.allowedIPs != []) " allowed-ips ${concatStringsSep "," peer.allowedIPs}"
-            ) values.peers)
-
-            "${ipCommand} link set up dev ${name}"
-
-            (optionals (values.allowedIPsAsRoutes != false) (map (peer:
-            (map (allowedIP:
-            "${ipCommand} route replace ${allowedIP} dev ${name} table ${values.table}"
-            ) peer.allowedIPs)
-            ) values.peers))
-
-            values.postSetup
-          ]);
-          ExecStop = flatten([
-            "${ipCommand} link del dev ${name}"
-            values.postShutdown
-          ]);
-        };
+              "wg set ${name} peer ${peer.publicKey}" +
+              optionalString (psk != null) " preshared-key ${psk}" +
+              optionalString (peer.endpoint != null) " endpoint ${peer.endpoint}" +
+              optionalString (peer.persistentKeepalive != null) " persistent-keepalive ${toString peer.persistentKeepalive}" +
+              optionalString (peer.allowedIPs != []) " allowed-ips ${concatStringsSep "," peer.allowedIPs}"
+            ) values.peers}
+
+          ip link set up dev ${name}
+
+          ${optionalString (values.allowedIPsAsRoutes != false) (concatStringsSep "\n" (concatMap (peer:
+              (map (allowedIP:
+                "ip route replace ${allowedIP} dev ${name} table ${values.table}"
+              ) peer.allowedIPs)
+            ) values.peers))}
+
+          ${values.postSetup}
+        '';
+
+        preStop = ''
+          ip link del dev ${name}
+          ${values.postShutdown}
+        '';
       };
 
 in