1{ config, lib, pkgs, ... }:
2
3with lib;
4with (import ./param-lib.nix lib);
5
6let
7 cfg = config.services.strongswan-swanctl;
8 swanctlParams = import ./swanctl-params.nix lib;
9in {
10 options.services.strongswan-swanctl = {
11 enable = mkEnableOption "strongswan-swanctl service";
12
13 package = mkOption {
14 type = types.package;
15 default = pkgs.strongswan;
16 defaultText = "pkgs.strongswan";
17 description = ''
18 The strongswan derivation to use.
19 '';
20 };
21
22 strongswan.extraConfig = mkOption {
23 type = types.str;
24 default = "";
25 description = ''
26 Contents of the <literal>strongswan.conf</literal> file.
27 '';
28 };
29
30 swanctl = paramsToOptions swanctlParams;
31 };
32
33 config = mkIf cfg.enable {
34
35 assertions = [
36 { assertion = !config.services.strongswan.enable;
37 message = "cannot enable both services.strongswan and services.strongswan-swanctl. Choose either one.";
38 }
39 ];
40
41 environment.etc."swanctl/swanctl.conf".text =
42 paramsToConf cfg.swanctl swanctlParams;
43
44 # The swanctl command complains when the following directories don't exist:
45 # See: https://wiki.strongswan.org/projects/strongswan/wiki/Swanctldirectory
46 system.activationScripts.strongswan-swanctl-etc = stringAfter ["etc"] ''
47 mkdir -p '/etc/swanctl/x509' # Trusted X.509 end entity certificates
48 mkdir -p '/etc/swanctl/x509ca' # Trusted X.509 Certificate Authority certificates
49 mkdir -p '/etc/swanctl/x509ocsp'
50 mkdir -p '/etc/swanctl/x509aa' # Trusted X.509 Attribute Authority certificates
51 mkdir -p '/etc/swanctl/x509ac' # Attribute Certificates
52 mkdir -p '/etc/swanctl/x509crl' # Certificate Revocation Lists
53 mkdir -p '/etc/swanctl/pubkey' # Raw public keys
54 mkdir -p '/etc/swanctl/private' # Private keys in any format
55 mkdir -p '/etc/swanctl/rsa' # PKCS#1 encoded RSA private keys
56 mkdir -p '/etc/swanctl/ecdsa' # Plain ECDSA private keys
57 mkdir -p '/etc/swanctl/bliss'
58 mkdir -p '/etc/swanctl/pkcs8' # PKCS#8 encoded private keys of any type
59 mkdir -p '/etc/swanctl/pkcs12' # PKCS#12 containers
60 '';
61
62 systemd.services.strongswan-swanctl = {
63 description = "strongSwan IPsec IKEv1/IKEv2 daemon using swanctl";
64 wantedBy = [ "multi-user.target" ];
65 after = [ "network-online.target" "keys.target" ];
66 wants = [ "keys.target" ];
67 path = with pkgs; [ kmod iproute iptables utillinux ];
68 environment.STRONGSWAN_CONF = pkgs.writeTextFile {
69 name = "strongswan.conf";
70 text = cfg.strongswan.extraConfig;
71 };
72 restartTriggers = [ config.environment.etc."swanctl/swanctl.conf".source ];
73 serviceConfig = {
74 ExecStart = "${cfg.package}/sbin/charon-systemd";
75 Type = "notify";
76 ExecStartPost = "${cfg.package}/sbin/swanctl --load-all --noprompt";
77 ExecReload = "${cfg.package}/sbin/swanctl --reload";
78 Restart = "on-abnormal";
79 };
80 };
81 };
82}