From 62f28d30a069135f9c48678507203958adfc334f Mon Sep 17 00:00:00 2001 From: Igor Pashev Date: Thu, 29 Sep 2016 13:51:44 +0300 Subject: Moved everything into ./modules --- modules/apps/strongswan/default.nix | 101 ++++++++++++++++++++++++++++++ modules/apps/strongswan/options/ca.nix | 20 ++++++ modules/apps/strongswan/options/conn.nix | 88 ++++++++++++++++++++++++++ modules/apps/strongswan/options/lib.nix | 26 ++++++++ modules/apps/strongswan/options/setup.nix | 24 +++++++ 5 files changed, 259 insertions(+) create mode 100644 modules/apps/strongswan/default.nix create mode 100644 modules/apps/strongswan/options/ca.nix create mode 100644 modules/apps/strongswan/options/conn.nix create mode 100644 modules/apps/strongswan/options/lib.nix create mode 100644 modules/apps/strongswan/options/setup.nix (limited to 'modules/apps/strongswan') diff --git a/modules/apps/strongswan/default.nix b/modules/apps/strongswan/default.nix new file mode 100644 index 0000000..d9a5034 --- /dev/null +++ b/modules/apps/strongswan/default.nix @@ -0,0 +1,101 @@ +{ config, pkgs, lib, ... }: + +let + + inherit (lib) mkIf mkOption types filterAttrs hasPrefix + mapAttrsToList concatStringsSep concatMapStringsSep; + inherit (types) listOf submodule path attrsOf; + inherit (builtins) filter toString toFile isList isBool; + + cfg = config.nixsap.apps.strongswan; + explicit = filterAttrs (n: v: n != "_module" && v != null); + + ipsecSecrets = toFile "ipsec.secrets" '' + ${concatMapStringsSep "\n" (f: "include ${f}") cfg.secrets} + ''; + + ipsecConf = + let + show = k: v: + if k == "charondebug" then concatStringsSep "," + (mapAttrsToList (t: l: "${t} ${toString l}") (explicit v)) + else if isList v then concatStringsSep "," v + else if isBool v then (if v then "yes" else "no") + else toString v; + makeSections = type: sections: concatStringsSep "\n\n" ( + mapAttrsToList (sec: attrs: + "${type} ${sec}\n" + + (concatStringsSep "\n" ( + mapAttrsToList (k: v: " ${k}=${show k v}") (explicit attrs) + )) + ) (explicit sections) + ); + setupSec = makeSections "config" { inherit (cfg) setup; }; + caSec = makeSections "ca" cfg.ca; + connSec = makeSections "conn" cfg.conn; + in toFile "ipsec.conf" '' + ${setupSec} + ${caSec} + ${connSec} + ''; + + strongswanConf = toFile "strongswan.conf" '' + charon { plugins { stroke { secrets_file = ${ipsecSecrets} } } } + starter { config_file = ${ipsecConf } } + ''; + +in { + options.nixsap.apps.strongswan = { + secrets = mkOption { + description = '' + A list of paths to IPSec secret files. These files will be included into + the main ipsec.secrets file by the "include" directive + ''; + type = listOf path; + default = []; + }; + setup = mkOption { + description = '' + A set of options for the ‘config setup’ section of the + ipsec.conf file. Defines general configuration parameters + ''; + type = submodule (import ./options/setup.nix); + default = {}; + }; + ca = mkOption { + description = '' + A set of CAs (certification authorities) and their options for + the ‘ca xxx’ sections of the ipsec.conf file + ''; + type = attrsOf (submodule (import ./options/ca.nix)); + default = {}; + }; + conn = mkOption { + description = '' + A set of connections and their options for the ‘conn xxx’ + sections of the ipsec.conf file + ''; + type = attrsOf (submodule (import ./options/conn.nix)); + default = {}; + }; + }; + + config = mkIf ({} != explicit cfg.conn) { + nixsap.deployment.keyrings.root = filter (hasPrefix "/run/keys/") cfg.secrets; + environment.systemPackages = [ pkgs.strongswan ]; + systemd.services.strongswan = { + description = "strongSwan IPSec Service"; + wantedBy = [ "multi-user.target" ]; + path = with pkgs; [ config.system.sbin.modprobe iproute iptables utillinux ]; + wants = [ "keys.target" ]; + after = [ "network.target" "keys.target" "local-fs.target" ]; + environment = { + STRONGSWAN_CONF = strongswanConf; + }; + serviceConfig = { + ExecStart = "${pkgs.strongswan}/sbin/ipsec start --nofork"; + Restart = "always"; + }; + }; + }; +} diff --git a/modules/apps/strongswan/options/ca.nix b/modules/apps/strongswan/options/ca.nix new file mode 100644 index 0000000..e52b088 --- /dev/null +++ b/modules/apps/strongswan/options/ca.nix @@ -0,0 +1,20 @@ +{ config, lib, ... }: + +let + + inherit (lib) foldl; + inherit (lib.types) str path enum; + inherit (import ./lib.nix lib) optional; + +in { + options = foldl (a: b: a//b) {} [ + { also = optional str; } + { auto = optional (enum [ "add" "ignore" ]); } + { cacert = optional path; } + { certuribase = optional str; } + { crluri = optional str; } + { crluri2 = optional str; } + { ocspuri = optional str; } + { ocspuri2 = optional str; } + ]; +} diff --git a/modules/apps/strongswan/options/conn.nix b/modules/apps/strongswan/options/conn.nix new file mode 100644 index 0000000..ac1d88c --- /dev/null +++ b/modules/apps/strongswan/options/conn.nix @@ -0,0 +1,88 @@ +{ config, lib, ... }: + +let + + inherit (lib) foldl attrNames head; + inherit (lib.types) int str path either listOf enum; + inherit (import ./lib.nix lib) boolean boolOr default optional; + + leftright = map + (a: let n = head (attrNames a); + in { + "left${n}" = a."${n}"; + "right${n}" = a."${n}"; + }) + [ + { allowany = optional boolean; } + { auth = optional str; } + { auth2 = optional str; } + { ca = optional str; } + { ca2 = optional str; } + { cert = optional path; } + { cert2 = optional path; } + { dns = optional (either str (listOf str)); } + { firewall = optional boolean; } + { groups = optional (either str (listOf str)); } + { hostaccess = optional boolean; } + { id = optional str; } + { id2 = optional str; } + { policy = optional (either str (listOf str)); } + { sendcert = optional (boolOr [ "never" "always" "ifasked" ]); } + { sigkey = optional (either str path); } + { sourceip = optional str; } + { subnet = optional (either str (listOf str)); } + { updown = optional path; } + ]; + + conn = leftright ++ [ + { aaa_identity = optional str; } + { aggressive = optional boolean; } + { ah = optional (either str (listOf str)); } + { also = optional str; } + { authby = optional (enum [ "pubkey" "rsasig" "ecdsasig" "psk" "secret" "xauthrsasig" "xauthpsk" "never" ]); } + { auto = optional (enum [ "ignore" "add" "route" "start" ]); } + { closeaction = optional (enum [ "none" "clear" "hold" "restart" ]); } + { compress = optional boolean; } + { dpdaction = optional (enum [ "none" "clear" "hold" "restart" ]); } + { dpddelay = optional int; } + { dpdtimeout = optional int; } + { eap_identity = optional str; } + { esp = optional (either str (listOf str)); } + { forceencaps = optional boolean; } + { fragmentation = optional (boolOr [ "force" ]); } + { ike = optional (either str (listOf str)); } + { ikedscp = optional str; } + { ikelifetime = optional int; } + { inactivity = optional int; } + { installpolicy = optional boolean; } + { keyexchange = optional (enum [ "ikev1" "ikev2" ]); } + { keyingtries = optional (either int (enum [ "%forever" ])); } + { left = optional str; } + { lifebytes = optional int; } + { lifepackets = optional int; } + { lifetime = optional int; } + { marginbytes = optional int; } + { marginpackets = optional int; } + { mark = optional str; } + { mark_in = optional str; } + { mark_out = optional str; } + { me_peerid = optional str; } + { mediated_by = optional str; } + { mediation = optional boolean; } + { mobike = optional boolean; } + { modeconfig = optional (enum [ "push" "pull" ]); } + { reauth = optional boolean; } + { rekey = optional boolean; } + { rekeyfuzz = optional int; } + { replay_window = optional int; } + { reqid = optional int; } + { right = optional str; } + { tfc = optional (either int (enum [ "%mtu" ])); } + { type = optional (enum [ "tunnel" "transport" "transport_proxy" "passthrough" "drop" ]); } + { xauth = optional (enum [ "client" "server" ]); } + { xauth_identity = optional str; } + ]; + +in { + options = foldl (a: b: a//b) {} conn; +} diff --git a/modules/apps/strongswan/options/lib.nix b/modules/apps/strongswan/options/lib.nix new file mode 100644 index 0000000..5b0808f --- /dev/null +++ b/modules/apps/strongswan/options/lib.nix @@ -0,0 +1,26 @@ +lib: + +let + inherit (lib) mkOption mkOptionType mergeOneOption elem flip concatStringsSep; + inherit (lib.types) nullOr submodule bool either; + +in rec { + default = v: type: mkOption { type = type; default = v; }; + optional = type: mkOption { type = nullOr type; default = null; }; + set = opts: mkOption { type = nullOr (submodule { options = opts; }); default = null; }; + + # XXX https://github.com/NixOS/nixpkgs/issues/9826 + enum' = values: + let show = v: let t = builtins.typeOf v; + in if t == "string" then ''"${v}"'' + else if t == "int" then builtins.toString v + else ''<${t}>''; + in mkOptionType { + name = "one of ${concatStringsSep ", " (map show values)}"; + check = flip elem values; + merge = mergeOneOption; + }; + + boolean = either bool (enum' [ "yes" "no" ]); + boolOr = l: either bool (enum' ([ "yes" "no" ] ++ l)); +} diff --git a/modules/apps/strongswan/options/setup.nix b/modules/apps/strongswan/options/setup.nix new file mode 100644 index 0000000..d60a2af --- /dev/null +++ b/modules/apps/strongswan/options/setup.nix @@ -0,0 +1,24 @@ +{ config, lib, ... }: + +let + + inherit (lib) foldl genAttrs; + inherit (import ./lib.nix lib) boolean boolOr default optional set enum'; + + charondebug = genAttrs [ + "asn" "cfg" "chd" "dmn" + "enc" "esp" "ike" "imc" + "imv" "job" "knl" "lib" + "mgr" "net" "pts" "tls" + "tnc" + ] (_: optional (enum' [ (-1) 0 1 2 3 4 ])); + +in { + options = foldl (a: b: a//b) {} [ + { cachecrls = optional boolean; } + { charondebug = set charondebug; } + { charonstart = optional boolean; } + { strictcrlpolicy = optional (boolOr [ "ifuri" ]); } + { uniqueids = optional (boolOr [ "never" "replace" "keep" ]); } + ]; +} -- cgit v1.2.3