at 25.11-pre 5.3 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7 8let 9 10 inherit (builtins) toFile; 11 inherit (lib) 12 concatMapStrings 13 concatStringsSep 14 mapAttrsToList 15 mkIf 16 mkEnableOption 17 mkOption 18 types 19 literalExpression 20 optionalString 21 ; 22 23 cfg = config.services.strongswan; 24 25 ipsecSecrets = secrets: concatMapStrings (f: "include ${f}\n") secrets; 26 27 ipsecConf = 28 { 29 setup, 30 connections, 31 ca, 32 }: 33 let 34 # https://wiki.strongswan.org/projects/strongswan/wiki/IpsecConf 35 makeSections = 36 type: sections: 37 concatStringsSep "\n\n" ( 38 mapAttrsToList ( 39 sec: attrs: 40 "${type} ${sec}\n" + (concatStringsSep "\n" (mapAttrsToList (k: v: " ${k}=${v}") attrs)) 41 ) sections 42 ); 43 setupConf = makeSections "config" { inherit setup; }; 44 connectionsConf = makeSections "conn" connections; 45 caConf = makeSections "ca" ca; 46 47 in 48 builtins.toFile "ipsec.conf" '' 49 ${setupConf} 50 ${connectionsConf} 51 ${caConf} 52 ''; 53 54 strongswanConf = 55 { 56 setup, 57 connections, 58 ca, 59 secretsFile, 60 managePlugins, 61 enabledPlugins, 62 }: 63 toFile "strongswan.conf" '' 64 charon { 65 ${optionalString managePlugins "load_modular = no"} 66 ${optionalString managePlugins ("load = " + (concatStringsSep " " enabledPlugins))} 67 plugins { 68 stroke { 69 secrets_file = ${secretsFile} 70 } 71 } 72 } 73 74 starter { 75 config_file = ${ipsecConf { inherit setup connections ca; }} 76 } 77 ''; 78 79in 80{ 81 options.services.strongswan = { 82 enable = mkEnableOption "strongSwan"; 83 84 secrets = mkOption { 85 type = types.listOf types.str; 86 default = [ ]; 87 example = [ "/run/keys/ipsec-foo.secret" ]; 88 description = '' 89 A list of paths to IPSec secret files. These 90 files will be included into the main ipsec.secrets file with 91 the `include` directive. It is safer if these 92 paths are absolute. 93 ''; 94 }; 95 96 setup = mkOption { 97 type = types.attrsOf types.str; 98 default = { }; 99 example = { 100 cachecrls = "yes"; 101 strictcrlpolicy = "yes"; 102 }; 103 description = '' 104 A set of options for the config setup section of the 105 {file}`ipsec.conf` file. Defines general 106 configuration parameters. 107 ''; 108 }; 109 110 connections = mkOption { 111 type = types.attrsOf (types.attrsOf types.str); 112 default = { }; 113 example = literalExpression '' 114 { 115 "%default" = { 116 keyexchange = "ikev2"; 117 keyingtries = "1"; 118 }; 119 roadwarrior = { 120 auto = "add"; 121 leftcert = "/run/keys/moonCert.pem"; 122 leftid = "@moon.strongswan.org"; 123 leftsubnet = "10.1.0.0/16"; 124 right = "%any"; 125 }; 126 } 127 ''; 128 description = '' 129 A set of connections and their options for the conn xxx 130 sections of the {file}`ipsec.conf` file. 131 ''; 132 }; 133 134 ca = mkOption { 135 type = types.attrsOf (types.attrsOf types.str); 136 default = { }; 137 example = { 138 strongswan = { 139 auto = "add"; 140 cacert = "/run/keys/strongswanCert.pem"; 141 crluri = "http://crl2.strongswan.org/strongswan.crl"; 142 }; 143 }; 144 description = '' 145 A set of CAs (certification authorities) and their options for 146 the ca xxx sections of the {file}`ipsec.conf` 147 file. 148 ''; 149 }; 150 151 managePlugins = mkOption { 152 type = types.bool; 153 default = false; 154 description = '' 155 If set to true, this option will disable automatic plugin loading and 156 then tell strongSwan to enable the plugins specified in the 157 {option}`enabledPlugins` option. 158 ''; 159 }; 160 161 enabledPlugins = mkOption { 162 type = types.listOf types.str; 163 default = [ ]; 164 description = '' 165 A list of additional plugins to enable if 166 {option}`managePlugins` is true. 167 ''; 168 }; 169 }; 170 171 config = 172 with cfg; 173 mkIf enable { 174 175 # here we should use the default strongswan ipsec.secrets and 176 # append to it (default one is empty so not a pb for now) 177 environment.etc."ipsec.secrets".text = ipsecSecrets cfg.secrets; 178 179 systemd.services.strongswan = { 180 description = "strongSwan IPSec Service"; 181 wantedBy = [ "multi-user.target" ]; 182 path = with pkgs; [ 183 kmod 184 iproute2 185 iptables 186 util-linux 187 ]; # XXX Linux 188 wants = [ "network-online.target" ]; 189 after = [ "network-online.target" ]; 190 environment = { 191 STRONGSWAN_CONF = strongswanConf { 192 inherit 193 setup 194 connections 195 ca 196 managePlugins 197 enabledPlugins 198 ; 199 secretsFile = "/etc/ipsec.secrets"; 200 }; 201 }; 202 serviceConfig = { 203 ExecStart = "${pkgs.strongswan}/sbin/ipsec start --nofork"; 204 }; 205 preStart = '' 206 # with 'nopeerdns' setting, ppp writes into this folder 207 mkdir -m 700 -p /etc/ppp 208 ''; 209 }; 210 }; 211}