diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 13a32b968dc..f9545740ade 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -560,6 +560,7 @@
./services/networking/ssh/lshd.nix
./services/networking/ssh/sshd.nix
./services/networking/strongswan.nix
+ ./services/networking/strongswan-swanctl/module.nix
./services/networking/stunnel.nix
./services/networking/supplicant.nix
./services/networking/supybot.nix
diff --git a/nixos/modules/services/networking/strongswan-swanctl/module.nix b/nixos/modules/services/networking/strongswan-swanctl/module.nix
new file mode 100644
index 00000000000..8bfb62e6b03
--- /dev/null
+++ b/nixos/modules/services/networking/strongswan-swanctl/module.nix
@@ -0,0 +1,80 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+with (import ./param-lib.nix lib);
+
+let
+ cfg = config.services.strongswan-swanctl;
+
+ # TODO: auto-generate these files using:
+ # https://github.com/strongswan/strongswan/tree/master/conf
+ # IDEA: extend the format-options.py script to output these Nix files.
+ strongswanParams = import ./strongswan-params.nix lib;
+ swanctlParams = import ./swanctl-params.nix lib;
+in {
+ options.services.strongswan-swanctl = {
+ enable = mkEnableOption "strongswan-swanctl service";
+
+ package = mkOption {
+ type = types.package;
+ default = pkgs.strongswan;
+ defaultText = "pkgs.strongswan";
+ description = ''
+ The strongswan derivation to use.
+ '';
+ };
+
+ strongswan = paramsToOptions strongswanParams;
+ swanctl = paramsToOptions swanctlParams;
+ };
+
+ config = mkIf cfg.enable {
+
+ assertions = [
+ { assertion = !config.services.strongswan.enable;
+ message = "cannot enable both services.strongswan and services.strongswan-swanctl. Choose either one.";
+ }
+ ];
+
+ environment.etc."swanctl/swanctl.conf".text =
+ paramsToConf cfg.swanctl swanctlParams;
+
+ # The swanctl command complains when the following directories don't exist:
+ # See: https://wiki.strongswan.org/projects/strongswan/wiki/Swanctldirectory
+ system.activationScripts.strongswan-swanctl-etc = stringAfter ["etc"] ''
+ mkdir -p '/etc/swanctl/x509' # Trusted X.509 end entity certificates
+ mkdir -p '/etc/swanctl/x509ca' # Trusted X.509 Certificate Authority certificates
+ mkdir -p '/etc/swanctl/x509ocsp'
+ mkdir -p '/etc/swanctl/x509aa' # Trusted X.509 Attribute Authority certificates
+ mkdir -p '/etc/swanctl/x509ac' # Attribute Certificates
+ mkdir -p '/etc/swanctl/x509crl' # Certificate Revocation Lists
+ mkdir -p '/etc/swanctl/pubkey' # Raw public keys
+ mkdir -p '/etc/swanctl/private' # Private keys in any format
+ mkdir -p '/etc/swanctl/rsa' # PKCS#1 encoded RSA private keys
+ mkdir -p '/etc/swanctl/ecdsa' # Plain ECDSA private keys
+ mkdir -p '/etc/swanctl/bliss'
+ mkdir -p '/etc/swanctl/pkcs8' # PKCS#8 encoded private keys of any type
+ mkdir -p '/etc/swanctl/pkcs12' # PKCS#12 containers
+ '';
+
+ systemd.services.strongswan-swanctl = {
+ description = "strongSwan IPsec IKEv1/IKEv2 daemon using swanctl";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "network-online.target" "keys.target" ];
+ wants = [ "keys.target" ];
+ path = with pkgs; [ kmod iproute iptables utillinux ];
+ environment.STRONGSWAN_CONF = pkgs.writeTextFile {
+ name = "strongswan.conf";
+ text = paramsToConf cfg.strongswan strongswanParams;
+ };
+ restartTriggers = [ config.environment.etc."swanctl/swanctl.conf".source ];
+ serviceConfig = {
+ ExecStart = "${cfg.package}/sbin/charon-systemd";
+ Type = "notify";
+ ExecStartPost = "${cfg.package}/sbin/swanctl --load-all --noprompt";
+ ExecReload = "${cfg.package}/sbin/swanctl --reload";
+ Restart = "on-abnormal";
+ };
+ };
+ };
+}
diff --git a/nixos/modules/services/networking/strongswan-swanctl/param-constructors.nix b/nixos/modules/services/networking/strongswan-swanctl/param-constructors.nix
new file mode 100644
index 00000000000..5e74a96664f
--- /dev/null
+++ b/nixos/modules/services/networking/strongswan-swanctl/param-constructors.nix
@@ -0,0 +1,162 @@
+# In the following context a parameter is an attribute set that
+# contains a NixOS option and a render function. It also contains the
+# attribute: '_type = "param"' so we can distinguish it from other
+# sets.
+#
+# The render function is used to convert the value of the option to a
+# snippet of strongswan.conf. Most parameters simply render their
+# value to a string. For example, take the following parameter:
+#
+# threads = mkIntParam 10 "Threads to use for request handling.";
+#
+# When a users defines the corresponding option as for example:
+#
+# services.strongswan-swanctl.strongswan.threads = 32;
+#
+# It will get rendered to the following snippet in strongswan.conf:
+#
+# threads = 32
+#
+# Some parameters however need to be able to change the attribute
+# name. For example, take the following parameter:
+#
+# id = mkPrefixedAttrsOfParam (mkOptionalStrParam "") "...";
+#
+# A user can define the corresponding option as for example:
+#
+# id = {
+# "foo" = "bar";
+# "baz" = "qux";
+# };
+#
+# This will get rendered to the following snippet:
+#
+# foo-id = bar
+# baz-id = qux
+#
+# For this reason the render function is not simply a function from
+# value -> string but a function from a value to an attribute set:
+# { "${name}" = string }. This allows parameters to change the attribute
+# name like in the previous example.
+
+lib :
+
+with lib;
+with (import ./param-lib.nix lib);
+
+rec {
+ mkParamOfType = type : strongswanDefault : description : {
+ _type = "param";
+ option = mkOption {
+ type = types.nullOr type;
+ default = null;
+ description = documentDefault description strongswanDefault;
+ };
+ render = single toString;
+ };
+
+ documentDefault = description : strongswanDefault :
+ if isNull strongswanDefault
+ then description
+ else description + ''
+
+ StrongSwan default:
+ '';
+
+ single = f: name: value: { "${name}" = f value; };
+
+ mkStrParam = mkParamOfType types.str;
+ mkOptionalStrParam = mkStrParam null;
+
+ mkEnumParam = values : mkParamOfType (types.enum values);
+
+ mkIntParam = mkParamOfType types.int;
+ mkOptionalIntParam = mkIntParam null;
+
+ # We should have floats in Nix...
+ mkFloatParam = mkStrParam;
+
+ # TODO: Check for hex format:
+ mkHexParam = mkStrParam;
+ mkOptionalHexParam = mkOptionalStrParam;
+
+ # TODO: Check for duration format:
+ mkDurationParam = mkStrParam;
+ mkOptionalDurationParam = mkOptionalStrParam;
+
+ mkYesNoParam = strongswanDefault : description : {
+ _type = "param";
+ option = mkOption {
+ type = types.nullOr types.bool;
+ default = null;
+ description = documentDefault description strongswanDefault;
+ };
+ render = single (b: if b then "yes" else "no");
+ };
+ yes = true;
+ no = false;
+
+ mkSpaceSepListParam = mkSepListParam " ";
+ mkCommaSepListParam = mkSepListParam ",";
+
+ mkSepListParam = sep : strongswanDefault : description : {
+ _type = "param";
+ option = mkOption {
+ type = types.nullOr (types.listOf types.str);
+ default = null;
+ description = documentDefault description strongswanDefault;
+ };
+ render = single (value: concatStringsSep sep value);
+ };
+
+ mkAttrsOfParams = params :
+ mkAttrsOf params (types.submodule {options = paramsToOptions params;});
+
+ mkAttrsOfParam = param :
+ mkAttrsOf param param.option.type;
+
+ mkAttrsOf = param : option : description : {
+ _type = "param";
+ option = mkOption {
+ type = types.attrsOf option;
+ default = {};
+ inherit description;
+ };
+ render = single (attrs:
+ (paramsToRenderedStrings attrs
+ (mapAttrs (_n: _v: param) attrs)));
+ };
+
+ mkPrefixedAttrsOfParams = params :
+ mkPrefixedAttrsOf params (types.submodule {options = paramsToOptions params;});
+
+ mkPrefixedAttrsOfParam = param :
+ mkPrefixedAttrsOf param param.option.type;
+
+ mkPrefixedAttrsOf = p : option : description : {
+ _type = "param";
+ option = mkOption {
+ type = types.attrsOf option;
+ default = {};
+ inherit description;
+ };
+ render = prefix: attrs:
+ let prefixedAttrs = mapAttrs' (name: nameValuePair "${prefix}-${name}") attrs;
+ in paramsToRenderedStrings prefixedAttrs
+ (mapAttrs (_n: _v: p) prefixedAttrs);
+ };
+
+ mkPostfixedAttrsOfParams = params : description : {
+ _type = "param";
+ option = mkOption {
+ type = types.attrsOf (types.submodule {options = paramsToOptions params;});
+ default = {};
+ inherit description;
+ };
+ render = postfix: attrs:
+ let postfixedAttrs = mapAttrs' (name: nameValuePair "${name}-${postfix}") attrs;
+ in paramsToRenderedStrings postfixedAttrs
+ (mapAttrs (_n: _v: params) postfixedAttrs);
+ };
+
+}
diff --git a/nixos/modules/services/networking/strongswan-swanctl/param-lib.nix b/nixos/modules/services/networking/strongswan-swanctl/param-lib.nix
new file mode 100644
index 00000000000..fb87e81f321
--- /dev/null
+++ b/nixos/modules/services/networking/strongswan-swanctl/param-lib.nix
@@ -0,0 +1,82 @@
+lib :
+
+with lib;
+
+rec {
+ paramsToConf = cfg : ps : mkConf 0 (paramsToRenderedStrings cfg ps);
+
+ # mkConf takes an indentation level (which usually starts at 0) and a nested
+ # attribute set of strings and will render that set to a strongswan.conf style
+ # configuration format. For example:
+ #
+ # mkConf 0 {a = "1"; b = { c = { "foo" = "2"; "bar" = "3"; }; d = "4";};} => ''
+ # a = 1
+ # b {
+ # c {
+ # foo = 2
+ # bar = 3
+ # }
+ # d = 4
+ # }''
+ mkConf = indent : ps :
+ concatMapStringsSep "\n"
+ (name:
+ let value = ps."${name}";
+ indentation = replicate indent " ";
+ in
+ indentation + (
+ if isAttrs value
+ then "${name} {\n" +
+ mkConf (indent + 2) value + "\n" +
+ indentation + "}"
+ else "${name} = ${value}"
+ )
+ )
+ (attrNames ps);
+
+ replicate = n : c : concatStrings (builtins.genList (_x : c) n);
+
+ # `paramsToRenderedStrings cfg ps` converts the NixOS configuration `cfg`
+ # (typically the "config" argument of a NixOS module) and the set of
+ # parameters `ps` (an attribute set where the values are constructed using the
+ # parameter constructors in ./param-constructors.nix) to a nested attribute
+ # set of strings (rendered parameters).
+ paramsToRenderedStrings = cfg : ps :
+ filterEmptySets (
+ (mapParamsRecursive (path: name: param:
+ let value = attrByPath path null cfg;
+ in optionalAttrs (!isNull value) (param.render name value)
+ ) ps));
+
+ filterEmptySets = set : filterAttrs (n: v: !(isNull v)) (mapAttrs (name: value:
+ if isAttrs value
+ then let value' = filterEmptySets value;
+ in if value' == {}
+ then null
+ else value'
+ else value
+ ) set);
+
+ # Recursively map over every parameter in the given attribute set.
+ mapParamsRecursive = mapAttrsRecursiveCond' (as: (!(as ? "_type" && as._type == "param")));
+
+ mapAttrsRecursiveCond' = cond: f: set:
+ let
+ recurse = path: set:
+ let
+ g =
+ name: value:
+ if isAttrs value && cond value
+ then { "${name}" = recurse (path ++ [name]) value; }
+ else f (path ++ [name]) name value;
+ in mapAttrs'' g set;
+ in recurse [] set;
+
+ mapAttrs'' = f: set:
+ foldl' (a: b: a // b) {} (map (attr: f attr set.${attr}) (attrNames set));
+
+ # Extract the options from the given set of parameters.
+ paramsToOptions = ps :
+ mapParamsRecursive (_path: name: param: { "${name}" = param.option; }) ps;
+
+}
diff --git a/nixos/modules/services/networking/strongswan-swanctl/strongswan-charon-params.nix b/nixos/modules/services/networking/strongswan-swanctl/strongswan-charon-params.nix
new file mode 100644
index 00000000000..3eec9886811
--- /dev/null
+++ b/nixos/modules/services/networking/strongswan-swanctl/strongswan-charon-params.nix
@@ -0,0 +1,568 @@
+lib: with (import ./param-constructors.nix lib);
+
+let loglevelParams = import ./strongswan-loglevel-params.nix lib;
+in {
+ accept_unencrypted_mainmode_messages = mkYesNoParam no ''
+ Accept unencrypted ID and HASH payloads in IKEv1 Main Mode. Some
+ implementations send the third Main Mode message unencrypted, probably
+ to find the PSKs for the specified ID for authentication. This is very
+ similar to Aggressive Mode, and has the same security implications: A
+ passive attacker can sniff the negotiated Identity, and start brute
+ forcing the PSK using the HASH payload. It is recommended to keep this
+ option to no, unless you know exactly what the implications are and
+ require compatibility to such devices (for example, some SonicWall
+ boxes).
+ '';
+
+ block_threshold = mkIntParam 5 ''
+ Maximum number of half-open IKE_SAs for a single peer IP.
+ '';
+
+ cache_crls = mkYesNoParam no ''
+ Whether Certicate Revocation Lists (CRLs) fetched via HTTP or LDAP
+ should be saved under a unique file name derived from the public
+ key of the Certification Authority (CA) to
+ /etc/ipsec.d/crls (stroke) or
+ /etc/swanctl/x509crl (vici), respectively.
+ '';
+
+ cert_cache = mkYesNoParam yes ''
+ Whether relations in validated certificate chains should be cached in memory.
+ '';
+
+ cisco_unity = mkYesNoParam no ''
+ Send Cisco Unity vendor ID payload (IKEv1 only), see unity plugin.
+ '';
+
+ close_ike_on_child_failure = mkYesNoParam no ''
+ Close the IKE_SA if setup of the CHILD_SA along with IKE_AUTH failed.
+ '';
+
+ cookie_threshold = mkIntParam 10 ''
+ Number of half-open IKE_SAs that activate the cookie mechanism.
+ '';
+
+ crypto_test.bench = mkYesNoParam no ''
+ Benchmark crypto algorithms and order them by efficiency.
+ '';
+
+ crypto_test.bench_size = mkIntParam 1024 ''
+ Buffer size used for crypto benchmark.
+ '';
+
+ crypto_test.bench_time = mkIntParam 50 ''
+ Number of iterations to test each algorithm.
+ '';
+
+ crypto_test.on_add = mkYesNoParam no ''
+ Test crypto algorithms during registration
+ (requires test vectors provided by the test-vectors plugin).
+ '';
+
+ crypto_test.on_create = mkYesNoParam no ''
+ Test crypto algorithms on each crypto primitive instantiation.
+ '';
+
+ crypto_test.required = mkYesNoParam no ''
+ Strictly require at least one test vector to enable an algorithm.
+ '';
+
+ crypto_test.rng_true = mkYesNoParam no ''
+ Whether to test RNG with TRUE quality; requires a lot of entropy.
+ '';
+
+ delete_rekeyed = mkYesNoParam no ''
+ Delete CHILD_SAs right after they got successfully rekeyed (IKEv1 only).
+ Reduces the number of stale CHILD_SAs in scenarios with a lot of rekeyings.
+ However, this might cause problems with implementations that continue
+ to use rekeyed SAs until they expire.
+ '';
+
+ delete_rekeyed_delay = mkIntParam 5 ''
+ Delay in seconds until inbound IPsec SAs are deleted after rekeyings
+ (IKEv2 only).
+
+ To process delayed packets the inbound part of a CHILD_SA is kept
+ installed up to the configured number of seconds after it got replaced
+ during a rekeying. If set to 0 the CHILD_SA will be kept installed until
+ it expires (if no lifetime is set it will be destroyed immediately).
+ '';
+
+ dh_exponent_ansi_x9_42 = mkYesNoParam yes ''
+ Use ANSI X9.42 DH exponent size or optimum size matched to
+ cryptographical strength.
+ '';
+
+ dlopen_use_rtld_now = mkYesNoParam no ''
+ Use RTLD_NOW with dlopen() when loading plugins and IMV/IMCs to reveal
+ missing symbols immediately. Useful during development of custom plugins.
+ '';
+
+ dns1 = mkOptionalStrParam ''
+ DNS server assigned to peer via configuration payload (CP), see attr plugin.
+ '';
+
+ dns2 = mkOptionalStrParam ''
+ DNS server assigned to peer via configuration payload (CP).
+ '';
+
+ dos_protection = mkYesNoParam yes ''
+ Enable Denial of Service protection using cookies and aggressiveness checks.
+ '';
+
+ ecp_x_coordinate_only = mkYesNoParam yes ''
+ Compliance with the errata for RFC 4753.
+ '';
+
+ filelog = mkAttrsOfParams ({
+ append = mkYesNoParam yes ''
+ If this option is enabled log entries are appended to the existing file.
+ '';
+
+ flush_line = mkYesNoParam no ''
+ Enabling this option disables block buffering and enables line
+ buffering. That is, a flush to disk is enforced for each logged line.
+ '';
+
+ ike_name = mkYesNoParam no ''
+ Prefix each log entry with the connection name and a unique numerical
+ identifier for each IKE_SA.
+ '';
+
+ time_format = mkOptionalStrParam ''
+ Prefix each log entry with a timestamp. The option accepts a format string
+ as passed to strftime(3).
+ '';
+
+ time_add_ms = mkYesNoParam no ''
+ Adds the milliseconds within the current second after the timestamp
+ (separated by a dot, so time_format should end with %S or %T)
+ '';
+ } // loglevelParams) ''Section to define file loggers, see LoggerConfiguration.'';
+
+ flush_auth_cfg = mkYesNoParam no ''
+ If enabled objects used during authentication (certificates, identities
+ etc.) are released to free memory once an IKE_SA is
+ established. Enabling this might conflict with plugins that later need
+ access to e.g. the used certificates.
+ '';
+
+ follow_redirects = mkYesNoParam yes ''
+ Whether to follow IKEv2 redirects (RFC 5685).
+ '';
+
+ fragment_size = mkIntParam 1280 ''
+ Maximum size (complete IP datagram size in bytes) of a sent IKE fragment
+ when using proprietary IKEv1 or standardized IKEv2 fragmentation,
+ defaults to 1280 (use 0 for address family specific default values,
+ which uses a lower value for IPv4). If specified this limit is used for
+ both IPv4 and IPv6.
+ '';
+
+ group = mkOptionalStrParam ''
+ Name of the group the daemon changes to after startup.
+ '';
+
+ half_open_timeout = mkIntParam 30 ''
+ Timeout in seconds for connecting IKE_SAs, also see IKE_SA_INIT dropping.
+ '';
+
+ hash_and_url = mkYesNoParam no ''
+ Enable hash and URL support.
+ '';
+
+ host_resolver.max_threads = mkIntParam 3 ''
+ Maximum number of concurrent resolver threads (they are terminated if unused).
+ '';
+
+ host_resolver.min_threads = mkIntParam 0 ''
+ Minimum number of resolver threads to keep around.
+ '';
+
+ i_dont_care_about_security_and_use_aggressive_mode_psk = mkYesNoParam no ''
+ If enabled responders are allowed to use IKEv1 Aggressive Mode with
+ pre-shared keys, which is discouraged due to security concerns (offline
+ attacks on the openly transmitted hash of the PSK).
+ '';
+
+ ignore_acquire_ts = mkYesNoParam no ''
+ If this is disabled the traffic selectors from the kernel's acquire
+ events, which are derived from the triggering packet, are prepended to
+ the traffic selectors from the configuration for IKEv2 connection. By
+ enabling this, such specific traffic selectors will be ignored and only
+ the ones in the config will be sent. This always happens for IKEv1
+ connections as the protocol only supports one set of traffic selectors
+ per CHILD_SA.
+ '';
+
+ ignore_routing_tables = mkSpaceSepListParam [] ''
+ A space-separated list of routing tables to be excluded from route lookup.
+ '';
+
+ ikesa_limit = mkIntParam 0 ''
+ Maximum number of IKE_SAs that can be established at the same time
+ before new connection attempts are blocked.
+ '';
+
+ ikesa_table_segments = mkIntParam 1 ''
+ Number of exclusively locked segments in the hash table, see IKE_SA
+ lookup tuning.
+ '';
+
+ ikesa_table_size = mkIntParam 1 ''
+ Size of the IKE_SA hash table, see IKE_SA lookup tuning.
+ '';
+
+ inactivity_close_ike = mkYesNoParam no ''
+ Whether to close IKE_SA if the only CHILD_SA closed due to inactivity.
+ '';
+
+ init_limit_half_open = mkIntParam 0 ''
+ Limit new connections based on the current number of half open IKE_SAs,
+ see IKE_SA_INIT dropping.
+ '';
+
+ init_limit_job_load = mkIntParam 0 ''
+ Limit new connections based on the number of jobs currently queued for
+ processing, see IKE_SA_INIT dropping.
+ '';
+
+ initiator_only = mkYesNoParam no ''
+ Causes charon daemon to ignore IKE initiation requests.
+ '';
+
+ install_routes = mkYesNoParam yes ''
+ Install routes into a separate routing table for established IPsec
+ tunnels. If disabled a more efficient lookup for source and next-hop
+ addresses is used since 5.5.2.
+ '';
+
+ install_virtual_ip = mkYesNoParam yes ''
+ Install virtual IP addresses.
+ '';
+
+ install_virtual_ip_on = mkOptionalStrParam ''
+ The name of the interface on which virtual IP addresses should be
+ installed. If not specified the addresses will be installed on the
+ outbound interface.
+ '';
+
+ integrity_test = mkYesNoParam no ''
+ Check daemon, libstrongswan and plugin integrity at startup.
+ '';
+
+ interfaces_ignore = mkCommaSepListParam [] ''
+ List of network interfaces that should be ignored, if
+ is specified this option has no effect.
+ '';
+
+ interfaces_use = mkCommaSepListParam [] ''
+ List of network interfaces that should be used by
+ charon. All other interfaces are ignored.
+ '';
+
+ keep_alive = mkIntParam 20 ''
+ NAT keep alive interval in seconds.
+ '';
+
+ leak_detective.detailed = mkYesNoParam yes ''
+ Includes source file names and line numbers in leak detective output.
+ '';
+
+ leak_detective.usage_threshold = mkIntParam 10240 ''
+ Threshold in bytes for leaks to be reported (0 to report all).
+ '';
+
+ leak_detective.usage_threshold_count = mkIntParam 0 ''
+ Threshold in number of allocations for leaks to be reported (0 to report
+ all).
+ '';
+
+ load = mkSpaceSepListParam [] ''
+ Plugins to load in IKEv2 charon daemon, see PluginLoad.
+ '';
+
+ load_modular = mkYesNoParam no ''
+ If enabled the list of plugins to load is determined by individual load
+ settings for each plugin, see PluginLoad.
+ '';
+
+ make_before_break = mkYesNoParam no ''
+ Initiate IKEv2 reauthentication with a make-before-break instead of a
+ break-before-make scheme. Make-before-break uses overlapping IKE and
+ CHILD_SA during reauthentication by first recreating all new SAs before
+ deleting the old ones. This behavior can be beneficial to avoid
+ connectivity gaps during reauthentication, but requires support for
+ overlapping SAs by the peer. strongSwan can handle such overlapping SAs
+ since 5.3.0.
+ '';
+
+ max_ikev1_exchanges = mkIntParam 3 ''
+ Maximum number of IKEv1 phase 2 exchanges per IKE_SA to keep state about
+ and track concurrently.
+ '';
+
+ max_packet = mkIntParam 10000 ''
+ Maximum packet size accepted by charon.
+ '';
+
+ multiple_authentication = mkYesNoParam yes ''
+ Enable multiple authentication exchanges (RFC 4739).
+ '';
+
+ nbns1 = mkOptionalStrParam ''
+ WINS server assigned to peer via configuration payload (CP), see attr
+ plugin.
+ '';
+
+ nbns2 = mkOptionalStrParam ''
+ WINS server assigned to peer via configuration payload (CP).
+ '';
+
+ port = mkIntParam 500 ''
+ UDP port used locally. If set to 0 a random port will be allocated.
+ '';
+
+ port_nat_t = mkIntParam 4500 ''
+ UDP port used locally in case of NAT-T. If set to 0 a random port will
+ be allocated. Has to be different from charon.port, otherwise a random
+ port will be allocated.
+ '';
+
+ prefer_best_path = mkYesNoParam no ''
+ By default, charon keeps SAs on the routing path with addresses it
+ previously used if that path is still usable. By enabling this option,
+ it tries more aggressively to update SAs with MOBIKE on routing priority
+ changes using the cheapest path. This adds more noise, but allows to
+ dynamically adapt SAs to routing priority changes. This option has no
+ effect if MOBIKE is not supported or disabled.
+ '';
+
+ prefer_configured_proposals = mkYesNoParam yes ''
+ Prefer locally configured proposals for IKE/IPsec over supplied ones as
+ responder (disabling this can avoid keying retries due to
+ INVALID_KE_PAYLOAD notifies).
+ '';
+
+ prefer_temporary_addrs = mkYesNoParam no ''
+ By default public IPv6 addresses are preferred over temporary ones
+ (according to RFC 4941), to make connections more stable. Enable this
+ option to reverse this.
+ '';
+
+ process_route = mkYesNoParam yes ''
+ Process RTM_NEWROUTE and RTM_DELROUTE events.
+ '';
+
+ processor.priority_threads = {
+ critical = mkIntParam 0 ''
+ Threads reserved for CRITICAL priority class jobs.
+ '';
+
+ high = mkIntParam 0 ''
+ Threads reserved for HIGH priority class jobs.
+ '';
+
+ medium = mkIntParam 0 ''
+ Threads reserved for MEDIUM priority class jobs.
+ '';
+
+ low = mkIntParam 0 ''
+ Threads reserved for LOW priority class jobs.
+ '';
+ };
+
+ receive_delay = mkIntParam 0 ''
+ Delay in ms for receiving packets, to simulate larger RTT.
+ '';
+
+ receive_delay_response = mkYesNoParam yes ''
+ Delay response messages.
+ '';
+
+ receive_delay_request = mkYesNoParam yes ''
+ Delay request messages.
+ '';
+
+ receive_delay_type = mkIntParam 0 ''
+ Specific IKEv2 message type to delay, 0 for any.
+ '';
+
+ replay_window = mkIntParam 32 ''
+ Size of the AH/ESP replay window, in packets.
+ '';
+
+ retransmit_base = mkFloatParam "1.8" ''
+ Base to use for calculating exponential back off, see Retransmission.
+ '';
+
+ retransmit_jitter = mkIntParam 0 ''
+ Maximum jitter in percent to apply randomly to calculated retransmission
+ timeout (0 to disable).
+ '';
+
+ retransmit_limit = mkIntParam 0 ''
+ Upper limit in seconds for calculated retransmission timeout (0 to
+ disable).
+ '';
+
+ retransmit_timeout = mkFloatParam "4.0" ''
+ Timeout in seconds before sending first retransmit.
+ '';
+
+ retransmit_tries = mkIntParam 5 ''
+ Number of times to retransmit a packet before giving up.
+ '';
+
+ retry_initiate_interval = mkIntParam 0 ''
+ Interval in seconds to use when retrying to initiate an IKE_SA (e.g. if
+ DNS resolution failed), 0 to disable retries.
+ '';
+
+ reuse_ikesa = mkYesNoParam yes ''
+ Initiate CHILD_SA within existing IKE_SAs (always enabled for IKEv1).
+ '';
+
+ routing_table = mkIntParam 220 ''
+ Numerical routing table to install routes to.
+ '';
+
+ routing_table_prio = mkIntParam 220 ''
+ Priority of the routing table.
+ '';
+
+ send_delay = mkIntParam 0 ''
+ Delay in ms for sending packets, to simulate larger RTT.
+ '';
+
+ send_delay_request = mkYesNoParam yes ''
+ Delay request messages.
+ '';
+
+ send_delay_response = mkYesNoParam yes ''
+ Delay response messages.
+ '';
+
+ send_delay_type = mkIntParam 0 ''
+ Specific IKEv2 message type to delay, 0 for any.
+ '';
+
+ send_vendor_id = mkYesNoParam no ''
+ Send strongSwan vendor ID payload.
+ '';
+
+ signature_authentication = mkYesNoParam yes ''
+ Whether to enable Signature Authentication as per RFC 7427.
+ '';
+
+ signature_authentication_constraints = mkYesNoParam yes ''
+ If enabled, signature schemes configured in rightauth, in addition to
+ getting used as constraints against signature schemes employed in the
+ certificate chain, are also used as constraints against the signature
+ scheme used by peers during IKEv2.
+ '';
+
+ spi_min = mkHexParam "0xc0000000" ''
+ The lower limit for SPIs requested from the kernel for IPsec SAs. Should
+ not be set lower than 0x00000100 (256), as SPIs between 1 and 255 are
+ reserved by IANA.
+ '';
+
+ spi_max = mkHexParam "0xcfffffff" ''
+ The upper limit for SPIs requested from the kernel for IPsec SAs.
+ '';
+
+ start-scripts = mkAttrsOfParam (mkStrParam "" "") ''
+ Section containing a list of scripts (name = path) that are executed
+ when the daemon is started.
+ '';
+
+ stop-scripts = mkAttrsOfParam (mkStrParam "" "") ''
+ Section containing a list of scripts (name = path) that are executed
+ when the daemon is terminated.
+ '';
+
+ syslog = loglevelParams // {
+ identifier = mkOptionalStrParam ''
+ Identifier for use with openlog(3).
+
+ Global identifier used for an openlog(3) call, prepended to each log
+ message by syslog. If not configured, openlog(3) is not called, so
+ the value will depend on system defaults (often the program name).
+ '';
+
+ ike_name = mkYesNoParam no ''
+ Prefix each log entry with the connection name and a unique numerical
+ identifier for each IKE_SA.
+ '';
+ };
+
+ threads = mkIntParam 16 ''
+ Number of worker threads in charon. Several of these are reserved for
+ long running tasks in internal modules and plugins. Therefore, make sure
+ you don't set this value too low. The number of idle worker threads
+ listed in ipsec statusall might be used as indicator on the number of
+ reserved threads (JobPriority has more on this).
+ '';
+
+ user = mkOptionalStrParam ''
+ Name of the user the daemon changes to after startup.
+ '';
+
+ x509.enforce_critical = mkYesNoParam yes ''
+ Discard certificates with unsupported or unknown critical extensions.
+ '';
+
+ plugins = import ./strongswan-charon-plugins-params.nix lib;
+
+ imcv = {
+ assessment_result = mkYesNoParam yes ''
+ Whether IMVs send a standard IETF Assessment Result attribute.
+ '';
+
+ database = mkOptionalStrParam ''
+ Global IMV policy database URI. If it contains a password, make sure to
+ adjust the permissions of the config file accordingly.
+ '';
+
+ os_info.default_password_enabled = mkYesNoParam no ''
+ Manually set whether a default password is enabled.
+ '';
+
+ os_info.name = mkOptionalStrParam ''
+ Manually set the name of the client OS (e.g. NixOS).
+ '';
+
+ os_info.version = mkOptionalStrParam ''
+ Manually set the version of the client OS (e.g. 17.09).
+ '';
+
+ policy_script = mkStrParam "ipsec _imv_policy" ''
+ Script called for each TNC connection to generate IMV policies.
+ '';
+ };
+
+ tls = {
+ cipher = mkSpaceSepListParam [] ''
+ List of TLS encryption ciphers.
+ '';
+
+ key_exchange = mkSpaceSepListParam [] ''
+ List of TLS key exchange methods.
+ '';
+
+ mac = mkSpaceSepListParam [] ''
+ List of TLS MAC algorithms.
+ '';
+
+ suites = mkSpaceSepListParam [] ''
+ List of TLS cipher suites.
+ '';
+ };
+
+ tnc = {
+ libtnccs.tnc_config = mkStrParam "/etc/tnc_config" ''
+ TNC IMC/IMV configuration file.
+ '';
+ };
+}
diff --git a/nixos/modules/services/networking/strongswan-swanctl/strongswan-charon-plugins-params.nix b/nixos/modules/services/networking/strongswan-swanctl/strongswan-charon-plugins-params.nix
new file mode 100644
index 00000000000..56a253d85d3
--- /dev/null
+++ b/nixos/modules/services/networking/strongswan-swanctl/strongswan-charon-plugins-params.nix
@@ -0,0 +1,1070 @@
+lib : with (import ./param-constructors.nix lib); {
+ addrblock.strict = mkYesNoParam yes ''
+ If enabled, a subject certificate without an RFC 3779 address block
+ extension is rejected if the issuer certificate has such an addrblock
+ extension. If disabled, subject certificates issued without addrblock
+ extension are accepted without any traffic selector checks and no policy
+ is enforced by the plugin.
+ '';
+
+ android_log.loglevel = mkIntParam 1 ''
+ Loglevel for logging to Android specific logger.
+ '';
+
+ attr = mkAttrsOfParam (mkCommaSepListParam [] "") ''
+ Section to specify arbitrary attributes that are assigned to a peer
+ via configuration payload, see attr plugin.
+
+ The attribute can be either
+ address,
+ netmask,
+ dns,
+ nbns,
+ dhcp,
+ subnet,
+ split-include,
+ split-exclude
+ or the numeric identifier of the attribute type. The assigned value can be
+ an IPv4/IPv6 address, a subnet in CIDR notation or an arbitrary value
+ depending on the attribute type. Since some attribute types accept multiple
+ values all values must be specified as a list.
+ '';
+
+ attr-sql.crash_recovery = mkYesNoParam yes ''
+ Release all online leases during startup. Disable this to share the DB
+ between multiple VPN gateways.
+ '';
+
+ attr-sql.database = mkOptionalStrParam ''
+ Database URI for attr-sql plugin used by charon. If it contains a
+ password, make sure to adjust the permissions of the config file
+ accordingly.
+ '';
+
+ attr-sql.lease_history = mkYesNoParam yes ''
+ Enable logging of SQL IP pool leases.
+ '';
+
+ bliss.use_bliss_b = mkYesNoParam yes ''
+ Use the enhanced BLISS-B key generation and signature algorithm.
+ '';
+
+ bypass-lan.interfaces_ignore = mkCommaSepListParam [] ''
+ List of network interfaces for which connected subnets
+ should be ignored, if interfaces_use is specified this option has no
+ effect.
+ '';
+
+ bypass-lan.interfaces_use = mkCommaSepListParam [] ''
+ List of network interfaces for which connected subnets
+ should be considered. All other interfaces are ignored.
+ '';
+
+ certexpire.csv.cron = mkOptionalStrParam ''
+ Cron style string specifying CSV export times, see certexpire for
+ details.
+ '';
+
+ certexpire.csv.empty_string = mkOptionalStrParam ''
+ String to use in empty intermediate CA fields.
+ '';
+
+ certexpire.csv.fixed_fields = mkYesNoParam yes ''
+ Use a fixed intermediate CA field count.
+ '';
+
+ certexpire.csv.force = mkYesNoParam yes ''
+ Force export of all trustchains we have a private key for.
+ '';
+
+ certexpire.csv.format = mkStrParam "%d:%m:%Y" ''
+ strftime(3) format string to export expiration dates as.
+ '';
+
+ certexpire.csv.local = mkOptionalStrParam ''
+ strftime(3) format string for the CSV file name to export local
+ certificates to.
+ '';
+
+ certexpire.csv.remote = mkOptionalStrParam ''
+ strftime(3) format string for the CSV file name to export remote
+ certificates to.
+ '';
+
+ certexpire.csv.separator = mkStrParam "," ''
+ CSV field separator.
+ '';
+
+ coupling.file = mkOptionalStrParam ''
+ File to store coupling list to, see certcoupling plugin for details.
+ '';
+
+ coupling.hash = mkStrParam "sha1" ''
+ Hashing algorithm to fingerprint coupled certificates.
+ '';
+
+ coupling.max = mkIntParam 1 ''
+ Maximum number of coupling entries to create.
+ '';
+
+ curl.redir = mkIntParam (-1) ''
+ Maximum number of redirects followed by the plugin, set to 0 to disable
+ following redirects, set to -1 for no limit.
+ '';
+
+ dhcp.force_server_address = mkYesNoParam no ''
+ Always use the configured server address, see DHCP plugin for details.
+ '';
+
+ dhcp.identity_lease = mkYesNoParam no ''
+ Derive user-defined MAC address from hash of IKEv2 identity.
+ '';
+
+ dhcp.interface = mkOptionalStrParam ''
+ Interface name the plugin uses for address allocation. The default is to
+ bind to any and let the system decide which way to route the packets to
+ the DHCP server.
+ '';
+
+ dhcp.server = mkStrParam "255.255.255.255" ''
+ DHCP server unicast or broadcast IP address.
+ '';
+
+ dnscert.enable = mkYesNoParam no ''
+ Enable fetching of CERT RRs via DNS.
+ '';
+
+ duplicheck.enable = mkYesNoParam yes ''
+ Enable duplicheck plugin (if loaded).
+ '';
+
+ duplicheck.socket = mkStrParam "unix://\${piddir}/charon.dck" ''
+ Socket provided by the duplicheck plugin.
+ '';
+
+ eap-aka.request_identity = mkYesNoParam yes "";
+
+ eap-aka-3ggp2.seq_check = mkOptionalStrParam ''
+ Enable to activate sequence check of the AKA SQN values in order to trigger
+ resync cycles.
+ '';
+
+ eap-dynamic.prefer_user = mkYesNoParam no ''
+ If enabled, the eap-dynamic plugin will prefer the order of the EAP
+ methods in an EAP-Nak message sent by a client over the one configured
+ locally.
+ '';
+
+ eap-dynamic.preferred = mkCommaSepListParam [] ''
+ The preferred EAP method(s) to be used by the eap-dynamic plugin. If it is
+ not set, the first registered method will be used initially. The methods
+ are tried in the given order before trying the rest of the registered
+ methods.
+ '';
+
+ eap-gtc.backend = mkStrParam "pam" ''
+ XAuth backend to be used for credential verification, see EAP-GTC.
+ '';
+
+ eap-peap.fragment_size = mkIntParam 1024 ''
+ Maximum size of an EAP-PEAP packet.
+ '';
+
+ eap-peap.max_message_count = mkIntParam 32 ''
+ Maximum number of processed EAP-PEAP packets.
+ '';
+
+ eap-peap.include_length = mkYesNoParam no ''
+ Include length in non-fragmented EAP-PEAP packets.
+ '';
+
+ eap-peap.phase2_method = mkStrParam "mschapv2" ''
+ Phase2 EAP client authentication method.
+ '';
+
+ eap-peap.phase2_piggyback = mkYesNoParam no ''
+ Phase2 EAP Identity request piggybacked by server onto TLS Finished
+ message.
+ '';
+
+ eap-peap.phase2_tnc = mkYesNoParam no ''
+ Start phase2 EAP-TNC protocol after successful client authentication.
+ '';
+
+ eap-peap.request_peer_auth = mkYesNoParam no ''
+ Request peer authentication based on a client certificate.
+ '';
+
+ eap-radius.accounting = mkYesNoParam no ''
+ Enable EAP-RADIUS accounting.
+ '';
+
+ eap-radius.accounting_close_on_timeout = mkYesNoParam yes ''
+ Close the IKE_SA if there is a timeout during interim RADIUS accounting
+ updates.
+ '';
+
+ eap-radius.accounting_interval = mkIntParam 0 ''
+ Interval in seconds for interim RADIUS accounting updates, if not
+ specified by the RADIUS server in the Access-Accept message.
+ '';
+
+ eap-radius.accounting_requires_vip = mkYesNoParam no ''
+ If enabled, accounting is disabled unless an IKE_SA has at least one
+ virtual IP.
+ '';
+
+ eap-radius.class_group = mkYesNoParam no ''
+ Use the class attribute sent in the Access-Accept message as group
+ membership information, see EapRadius.
+ '';
+
+ eap-radius.close_all_on_timeout = mkYesNoParam no ''
+ Closes all IKE_SAs if communication with the RADIUS server times out. If
+ it is not set only the current IKE_SA is closed.
+ '';
+
+ eap-radius.dae.enable = mkYesNoParam no ''
+ Enables support for the Dynamic Authorization Extension (RFC 5176).
+ '';
+
+ eap-radius.dae.listen = mkStrParam "0.0.0.0" ''
+ Address to listen for DAE messages from the RADIUS server.
+ '';
+
+ eap-radius.dae.port = mkIntParam 3799 ''
+ Port to listen for DAE requests.
+ '';
+
+ eap-radius.dae.secret = mkOptionalStrParam ''
+ Shared secret used to verify/sign DAE messages.If set, make sure to
+ adjust the permissions of the config file accordingly.
+ '';
+
+ eap-radius.eap_start = mkYesNoParam no ''
+ Send EAP-Start instead of EAP-Identity to start RADIUS conversation.
+ '';
+
+ eap-radius.filter_id = mkYesNoParam no ''
+ Use the filter_id attribute sent in the RADIUS-Accept message as group
+ membership if the RADIUS tunnel_type attribute is set to ESP.
+ '';
+
+ eap-radius.forward.ike_to_radius = mkOptionalStrParam ''
+ RADIUS attributes to be forwarded from IKEv2 to RADIUS (can be defined
+ by name or attribute number, a colon can be used to specify
+ vendor-specific attributes, e.g. Reply-Message, or 11, or 36906:12).
+ '';
+
+ eap-radius.forward.radius_to_ike = mkOptionalStrParam ''
+ Same as above but from RADIUS to IKEv2, a strongSwan specific private
+ notify (40969) is used to transmit the attributes.
+ '';
+
+ eap-radius.id_prefix = mkOptionalStrParam ''
+ Prefix to EAP-Identity, some AAA servers use a IMSI prefix to select the
+ EAP method.
+ '';
+
+ eap-radius.nas_identifier = mkStrParam "strongSwan" ''
+ NAS-Identifier to include in RADIUS messages.
+ '';
+
+ eap-radius.port = mkIntParam 1812 ''
+ Port of RADIUS server (authentication).
+ '';
+
+ eap-radius.retransmit_base = mkFloatParam "1.4" ''
+ Base to use for calculating exponential back off.
+ '';
+
+ eap-radius.retransmit_timeout = mkFloatParam "2.0" ''
+ Timeout in seconds before sending first retransmit.
+ '';
+
+ eap-radius.retransmit_tries = mkIntParam 4 ''
+ Number of times to retransmit a packet before giving up.
+ '';
+
+ eap-radius.secret = mkOptionalStrParam ''
+ Shared secret between RADIUS and NAS. If set, make sure to adjust the
+ permissions of the config file accordingly.
+ '';
+
+ eap-radius.server = mkOptionalStrParam ''
+ IP/Hostname of RADIUS server.
+ '';
+
+ eap-radius.servers = mkAttrsOfParams {
+ nas_identifier = mkStrParam "strongSwan" ''
+ The nas_identifer (default: strongSwan) identifies the gateway against the
+ RADIUS server and allows it to enforce a policy, for example.
+ '';
+
+ secret = mkOptionalStrParam "";
+
+ sockets = mkIntParam 1 ''
+ The number of pre-allocated sockets to use. A value of 5 allows the
+ gateway to authentication 5 clients simultaneously over RADIUS.
+ '';
+
+ auth_port = mkIntParam 1812 ''
+ RADIUS UDP port
+ '';
+
+ address = mkOptionalStrParam ''
+ The server's IP/Hostname.
+ '';
+
+ acct_port = mkIntParam 1813 ''
+ Accounting port.
+ '';
+
+ preference = mkIntParam 0 ''
+ With the preference paramter of a server, priorities for specific servers
+ can be defined. This allows to use a secondary RADIUS server only if the
+ first gets unresponsive, or if it is overloaded.
+ '';
+ } ''Section to specify multiple RADIUS servers, see EapRadius.'';
+
+ eap-radius.sockets = mkIntParam 1 ''
+ Number of sockets (ports) to use, increase for high load.
+ '';
+
+ eap-radius.xauth = mkAttrsOfParams {
+ nextpin = mkOptionalStrParam "";
+ password = mkOptionalStrParam "";
+ passcode = mkOptionalStrParam "";
+ answer = mkOptionalStrParam "";
+ } ''
+ Section to configure multiple XAuth authentication rounds via RADIUS.
+ '';
+
+ eap-sim.request_identity = mkYesNoParam yes "";
+
+ eap-simaka-sql.database = mkOptionalStrParam "";
+
+ eap-simaka-sql.remove_used = mkOptionalStrParam "";
+
+ eap-tls.fragment_size = mkIntParam 1024 ''
+ Maximum size of an EAP-TLS packet.
+ '';
+
+ eap-tls.include_length = mkYesNoParam yes ''
+ Include length in non-fragmented EAP-TLS packets.
+ '';
+
+ eap-tls.max_message_count = mkIntParam 32 ''
+ Maximum number of processed EAP-TLS packets (0 = no limit).
+ '';
+
+ eap-tnc.max_message_count = mkIntParam 10 ''
+ Maximum number of processed EAP-TNC packets (0 = no limit).
+ '';
+
+ eap-tnc.protocol = mkStrParam "tnccs-2.0" ''
+ IF-TNCCS protocol version to be used (tnccs-1.1, tnccs-2.0,
+ tnccs-dynamic).
+ '';
+
+ eap-ttls.fragment_size = mkIntParam 1024 ''
+ Maximum size of an EAP-TTLS packet.
+ '';
+
+ eap-ttls.include_length = mkYesNoParam yes ''
+ Include length in non-fragmented EAP-TTLS packets.
+ '';
+
+ eap-ttls.max_message_count = mkIntParam 32 ''
+ Maximum number of processed EAP-TTLS packets (0 = no limit).
+ '';
+
+ eap-ttls.phase2_method = mkStrParam "md5" ''
+ Phase2 EAP client authentication method.
+ '';
+
+ eap-ttls.phase2_piggyback = mkYesNoParam no ''
+ Phase2 EAP Identity request piggybacked by server onto TLS Finished
+ message.
+ '';
+
+ eap-ttls.phase2_tnc = mkYesNoParam no ''
+ Start phase2 EAP TNC protocol after successful client authentication.
+ '';
+
+ eap-ttls-phase2_tnc_method = mkEnumParam ["pt" "legacy"] "pt" ''
+ Phase2 EAP TNC transport protocol (pt as IETF standard or legacy tnc)
+ '';
+
+ eap-ttls.request_peer_auth = mkYesNoParam no ''
+ Request peer authentication based on a client certificate.
+ '';
+
+ error-notify.socket = mkStrParam "unix://\${piddir}/charon.enfy" ''
+ Socket provided by the error-notify plugin.
+ '';
+
+ ext-auth.script = mkOptionalStrParam ''
+ Shell script to invoke for peer authorization (see ext-auth).
+ '';
+
+ gcrypt.quick_random = mkYesNoParam no ''
+ Use faster random numbers in gcrypt. For testing only, produces weak
+ keys!
+ '';
+
+ ha.autobalance = mkIntParam 0 ''
+ Interval in seconds to automatically balance handled segments between
+ nodes. Set to 0 to disable.
+ '';
+
+ ha.fifo_interface = mkYesNoParam yes "";
+
+ ha.heartbeat_delay = mkIntParam 1000 "";
+
+ ha.heartbeat_timeout = mkIntParam 2100 "";
+
+ ha.local = mkOptionalIntParam "";
+
+ ha.monitor = mkYesNoParam yes "";
+
+ ha.pools = mkOptionalStrParam "";
+
+ ha.remote = mkOptionalStrParam "";
+
+ ha.resync = mkYesNoParam yes "";
+
+ ha.secret = mkOptionalStrParam "";
+
+ ha.segment_count = mkIntParam 1 "";
+
+ ipseckey.enable = mkYesNoParam no ''
+ Enable fetching of IPSECKEY RRs via DNS.
+ '';
+
+ kernel-libipsec.allow_peer_ts = mkYesNoParam no ''
+ Allow that the remote traffic selector equals the IKE peer (see
+ kernel-libipsec for details).
+ '';
+
+ kernel-netlink.buflen = mkOptionalIntParam ''
+ Buffer size for received Netlink messages. Defaults to
+ min(PAGE_SIZE, 8192).
+ '';
+
+ kernel-netlink.force_receive_buffer_size = mkYesNoParam no ''
+ If the maximum Netlink socket receive buffer in bytes set by
+ receive_buffer_size exceeds the system-wide maximum from
+ /proc/sys/net/core/rmem_max, this option can be used to
+ override the limit. Enabling this option requires special priviliges
+ (CAP_NET_ADMIN).
+ '';
+
+ kernel-netlink.fwmark = mkOptionalStrParam ''
+ Firewall mark to set on the routing rule that directs traffic to our own
+ routing table. The format is [!]mark[/mask], where the
+ optional exclamation mark inverts the meaning (i.e. the rule only applies to
+ packets that don't match the mark). A possible use case are host-to-host
+ tunnels with kernel-libipsec. When set to !<mark> a more efficient
+ lookup for source and next-hop addresses may also be used since 5.3.3.
+ '';
+
+ kernel-netlink.mss = mkIntParam 0 ''
+ MSS to set on installed routes, 0 to disable.
+ '';
+
+ kernel-netlink.mtu = mkIntParam 0 ''
+ MTU to set on installed routes, 0 to disable.
+ '';
+
+ kernel-netlink.receive_buffer_size = mkIntParam 0 ''
+ Maximum Netlink socket receive buffer in bytes. This value controls how many
+ bytes of Netlink messages can be received on a Netlink socket. The default
+ value is set by /proc/sys/net/core/rmem_default. The
+ specified value cannot exceed the system-wide maximum from
+ /proc/sys/net/core/rmem_max, unless
+ is enabled.
+ '';
+
+ kernel-netlink.roam_events = mkYesNoParam yes ''
+ Whether to trigger roam events when interfaces, addresses or routes
+ change.
+ '';
+
+ kernel-netlink.set_proto_port_transport_sa = mkYesNoParam no ''
+ Whether to set protocol and ports in the selector installed on transport
+ mode IPsec SAs in the kernel. While doing so enforces policies for
+ inbound traffic, it also prevents the use of a single IPsec SA by more
+ than one traffic selector.
+ '';
+
+ kernel-netlink.spdh_thresh.ipv4.lbits = mkIntParam 32 ''
+ Local subnet XFRM policy hashing threshold for IPv4.
+ '';
+
+ kernel-netlink.spdh_thresh.ipv4.rbits = mkIntParam 32 ''
+ Remote subnet XFRM policy hashing threshold for IPv4.
+ '';
+
+ kernel-netlink.spdh_thresh.ipv6.lbits = mkIntParam 128 ''
+ Local subnet XFRM policy hashing threshold for IPv6.
+ '';
+
+ kernel-netlink.spdh_thresh.ipv6.rbits = mkIntParam 128 ''
+ Remote subnet XFRM policy hashing threshold for IPv6.
+ '';
+
+ kernel-netlink.xfrm_acq_expires = mkIntParam 165 ''
+ Lifetime of XFRM acquire state created by the kernel when traffic matches a
+ trap policy. The value gets written to
+ /proc/sys/net/core/xfrm_acq_expires. Indirectly controls
+ the delay between XFRM acquire messages triggered by the kernel for a trap
+ policy. The same value is used as timeout for SPIs allocated by the
+ kernel. The default value equals the default total retransmission timeout
+ for IKE messages (since 5.5.3 this value is determined dynamically based on
+ the configuration).
+ '';
+
+ kernel-pfkey.events_buffer_size = mkIntParam 0 ''
+ Size of the receive buffer for the event socket (0 for default
+ size). Because events are received asynchronously installing e.g. lots
+ of policies may require a larger buffer than the default on certain
+ platforms in order to receive all messages.
+ '';
+
+ kernel-pfroute.vip_wait = mkIntParam 1000 ''
+ Time in ms to wait until virtual IP addresses appear/disappear before
+ failing.
+ '';
+
+ led.activity_led = mkOptionalStrParam "";
+
+ led.blink_time = mkIntParam 50 "";
+
+ load-tester = {
+ addrs = mkAttrsOfParam (mkOptionalStrParam "") ''
+ Section that contains key/value pairs with address pools (in CIDR
+ notation) to use for a specific network interface e.g.
+ eth0 = 10.10.0.0/16.
+ '';
+
+ addrs_keep = mkYesNoParam no ''
+ Whether to keep dynamic addresses even after the associated SA got
+ terminated.
+ '';
+
+ addrs_prefix = mkIntParam 16 ''
+ Network prefix length to use when installing dynamic addresses.
+ If set to -1 the full address is used (i.e. 32 or 128).
+ '';
+
+ ca_dir = mkOptionalStrParam ''
+ Directory to load (intermediate) CA certificates from.
+ '';
+
+ child_rekey = mkIntParam 600 ''
+ Seconds to start CHILD_SA rekeying after setup.
+ '';
+
+ crl = mkOptionalStrParam ''
+ URI to a CRL to include as certificate distribution point in generated
+ certificates.
+ '';
+
+ delay = mkIntParam 0 ''
+ Delay between initiatons for each thread.
+ '';
+
+ delete_after_established = mkYesNoParam no ''
+ Delete an IKE_SA as soon as it has been established.
+ '';
+
+ digest = mkStrParam "sha1" ''
+ Digest algorithm used when issuing certificates.
+ '';
+
+ dpd_delay = mkIntParam 0 ''
+ DPD delay to use in load test.
+ '';
+
+ dynamic_port = mkIntParam 0 ''
+ Base port to be used for requests (each client uses a different port).
+ '';
+
+ eap_password = mkStrParam "default-pwd" ''
+ EAP secret to use in load test.
+ '';
+
+ enable = mkYesNoParam no ''
+ Enable the load testing plugin. **WARNING**: Never enable this plugin on
+ productive systems. It provides preconfigured credentials and allows an
+ attacker to authenticate as any user.
+ '';
+
+ esp = mkStrParam "aes128-sha1" ''
+ CHILD_SA proposal to use for load tests.
+ '';
+
+ fake_kernel = mkYesNoParam no ''
+ Fake the kernel interface to allow load-testing against self.
+ '';
+
+ ike_rekey = mkIntParam 0 ''
+ Seconds to start IKE_SA rekeying after setup.
+ '';
+
+ init_limit = mkIntParam 0 ''
+ Global limit of concurrently established SAs during load test.
+ '';
+
+ initiator = mkStrParam "0.0.0.0" ''
+ Address to initiate from.
+ '';
+
+ initiators = mkIntParam 0 ''
+ Number of concurrent initiator threads to use in load test.
+ '';
+
+ initiator_auth = mkStrParam "pubkey" ''
+ Authentication method(s) the intiator uses.
+ '';
+
+ initiator_id = mkOptionalStrParam ''
+ Initiator ID used in load test.
+ '';
+
+ initiator_match = mkOptionalStrParam ''
+ Initiator ID to match against as responder.
+ '';
+
+ initiator_tsi = mkOptionalStrParam ''
+ Traffic selector on initiator side, as proposed by initiator.
+ '';
+
+ initiator_tsr = mkOptionalStrParam ''
+ Traffic selector on responder side, as proposed by initiator.
+ '';
+
+ iterations = mkIntParam 1 ''
+ Number of IKE_SAs to initiate by each initiator in load test.
+ '';
+
+ issuer_cert = mkOptionalStrParam ''
+ Path to the issuer certificate (if not configured a hard-coded default
+ value is used).
+ '';
+
+ issuer_key = mkOptionalStrParam ''
+ Path to private key that is used to issue certificates (if not configured
+ a hard-coded default value is used).
+ '';
+
+ mode = mkEnumParam ["tunnel" "transport" "beet"] "tunnel" ''
+ IPsec mode to use.
+ '';
+
+ pool = mkOptionalStrParam ''
+ Provide INTERNAL_IPV4_ADDRs from a named pool.
+ '';
+
+ preshared_key = mkStrParam "" ''
+ Preshared key to use in load test.
+ '';
+
+ proposal = mkStrParam "aes128-sha1-modp768" ''
+ IKE proposal to use in load test.
+ '';
+
+ responder = mkStrParam "127.0.0.1" ''
+ Address to initiation connections to.
+ '';
+
+ responder_auth = mkStrParam "pubkey" ''
+ Authentication method(s) the responder uses.
+ '';
+
+ responder_id = mkOptionalStrParam ''
+ Responder ID used in load test.
+ '';
+
+ responder_tsi = mkStrParam "initiator_tsi" ''
+ Traffic selector on initiator side, as narrowed by responder.
+ '';
+
+ responder_tsr = mkStrParam "initiator_tsr" ''
+ Traffic selector on responder side, as narrowed by responder.
+ '';
+
+ request_virtual_ip = mkYesNoParam no ''
+ Request an INTERNAL_IPV4_ADDR from the server.
+ '';
+
+ shutdown_when_complete = mkYesNoParam no ''
+ Shutdown the daemon after all IKE_SAs have been established.
+ '';
+
+ socket = mkStrParam "unix://\\\${piddir}/charon.ldt" ''
+ Socket provided by the load-tester plugin.
+ '';
+
+ version = mkIntParam 0 ''
+ IKE version to use (0 means use IKEv2 as initiator and accept any version
+ as responder).
+ '';
+ };
+
+ lookip.socket = mkStrParam "unix://\\\${piddir}/charon.lkp" ''
+ Socket provided by the lookip plugin.
+ '';
+
+ ntru.max_drbg_requests = mkIntParam 4294967294 ''
+ Number of pseudo-random bit requests from the DRBG before an automatic
+ reseeding occurs.
+ '';
+
+ ntru.parameter_set =
+ mkEnumParam ["x9_98_speed" "x9_98_bandwidth" "x9_98_balance" "optimum"] "optimum" ''
+ The following parameter sets are available:
+ x9_98_speed, x9_98_bandwidth,
+ x9_98_balance and optimum, the last
+ set not being part of the X9.98 standard but having the best performance.
+ '';
+
+ openssl.engine_id = mkStrParam "pkcs11" ''
+ ENGINE ID to use in the OpenSSL plugin.
+ '';
+
+ openssl.fips_mode = mkIntParam 0 ''
+ Set OpenSSL FIPS mode:
+
+ disabled (0),
+ enabled (1),
+ Suite B enabled (2).
+
+ Defaults to the value configured with the
+ --with-fips-mode option.
+
+ '';
+
+ osx-attr.append = mkYesNoParam yes ''
+ Whether DNS servers are appended to existing entries, instead of
+ replacing them.
+ '';
+
+ pkcs11.load_certs = mkYesNoParam yes ''
+ Whether to load certificates from tokens.
+ '';
+
+ pkcs11.modules = mkAttrsOfParams {
+ path = mkOptionalStrParam ''
+ Full path to the shared object file of this PKCS#11 module
+ '';
+
+ os_locking = mkYesNoParam no ''
+ Whether OS locking should be enabled for this module
+ '';
+
+ load_certs = mkYesNoParam no ''
+ Whether the PKCS#11 modules should load certificates from tokens (since 5.0.2)
+ '';
+ } ''
+ List of available PKCS#11 modules, see SmartCardsIKEv2.
+ '';
+
+ pkcs11.reload_certs = mkYesNoParam no ''
+ Reload certificates from all tokens if charon receives a SIGHUP.
+ '';
+
+ pkcs11.use_dh = mkYesNoParam no ''
+ Whether the PKCS#11 modules should be used for DH and ECDH.
+ '';
+
+ pkcs11.use_ecc = mkYesNoParam no ''
+ Whether the PKCS#11 modules should be used for ECDH and ECDSA public key
+ operations. ECDSA private keys are used regardless of this option.
+ '';
+
+ pkcs11.use_hasher = mkYesNoParam no ''
+ Whether the PKCS#11 modules should be used to hash data.
+ '';
+
+ pkcs11.use_pubkey = mkYesNoParam no ''
+ Whether the PKCS#11 modules should be used for public key operations,
+ even for keys not stored on tokens.
+ '';
+
+ pkcs11.use_rng = mkYesNoParam no ''
+ Whether the PKCS#11 modules should be used as RNG.
+ '';
+
+ radattr.dir = mkOptionalStrParam ''
+ Directory where RADIUS attributes are stored in client-ID specific
+ files, see radattr.
+ '';
+
+ radattr.message_id = mkIntParam (-1) ''
+ RADIUS attributes are added to all IKE_AUTH messages by default (-1), or
+ only to the IKE_AUTH message with the given IKEv2 message ID.
+ '';
+
+ random.random = mkStrParam "/dev/random" ''
+ File to read random bytes from.
+ '';
+
+ random.urandom = mkStrParam "/dev/urandom" ''
+ File to read pseudo random bytes from.
+ '';
+
+ random.strong_equals_true = mkYesNoParam no ''
+ If enabled the RNG_STRONG class reads random bytes from the same source
+ as the RNG_TRUE class.
+ '';
+
+ resolve.file = mkStrParam "/etc/resolv.conf" ''
+ File used by the resolve plugin to write DNS server entries to.
+ '';
+
+ resolve.resolvconf.iface_prefix = mkStrParam "lo.inet.ipsec." ''
+ Prefix used by the resolve plugin for interface names sent to
+ resolvconf(8). The name server address is appended to this prefix to
+ make it unique. The result has to be a valid interface name according to
+ the rules defined by resolvconf. Also, it should have a high priority
+ according to the order defined in interface-order(5).
+ '';
+
+ revocation.enable_crl = mkYesNoParam yes ''
+ Whether CRL validation should be enabled.
+ '';
+
+ revocation.enable_ocsp = mkYesNoParam yes ''
+ Whether OCSP validation should be enabled.
+ '';
+
+ socket-default.fwmark = mkOptionalStrParam ''
+ Firewall mark to set on outbound packets (a possible use case are
+ host-to-host tunnels with kernel-libipsec).
+ '';
+
+ socket-default.set_source = mkYesNoParam yes ''
+ Set source address on outbound packets, if possible.
+ '';
+
+ socket-default.set_sourceif = mkYesNoParam no ''
+ Force sending interface on outbound packets, if possible. This allows
+ using IPv6 link-local addresses as tunnel endpoints.
+ '';
+
+ socket-default.use_ipv4 = mkYesNoParam yes ''
+ Listen on IPv4, if possible.
+ '';
+
+ socket-default.use_ipv6 = mkYesNoParam yes ''
+ Listen on IPv6, if possible.
+ '';
+
+ sql.database = mkOptionalStrParam ''
+ Database URI for charon's SQL plugin. If it contains a password, make
+ sure to adjust the permissions of the config file accordingly.
+ '';
+
+ sql.loglevel = mkIntParam (-1) ''
+ Loglevel for logging to SQL database.
+ '';
+
+ stroke.allow_swap = mkYesNoParam yes ''
+ Analyze addresses/hostnames in left/right to detect which side is local
+ and swap configuration options if necessary. If disabled left is always
+ local.
+ '';
+
+ stroke.ignore_missing_ca_basic_constraint = mkYesNoParam no ''
+ Treat certificates in ipsec.d/cacerts and ipsec.conf ca sections as CA
+ certificates even if they don't contain a CA basic constraint.
+ '';
+
+ stroke.max_concurrent = mkIntParam 4 ''
+ Maximum number of stroke messages handled concurrently.
+ '';
+
+ stroke.secrets_file = mkStrParam "\${sysconfdir}/ipsec.secrets" ''
+ Location of the ipsec.secrets file.
+ '';
+
+ stroke.socket = mkStrParam "unix://\${piddir}/charon.ctl" ''
+ Socket provided by the stroke plugin.
+ '';
+
+ stroke.timeout = mkIntParam 0 ''
+ Timeout in ms for any stroke command. Use 0 to disable the timeout.
+ '';
+
+ systime-fix.interval = mkIntParam 0 ''
+ Interval in seconds to check system time for validity. 0 disables the
+ check. See systime-fix plugin.
+ '';
+
+ systime-fix.reauth = mkYesNoParam no ''
+ Whether to use reauth or delete if an invalid cert lifetime is detected.
+ '';
+
+ systime-fix.threshold = mkOptionalStrParam ''
+ Threshold date where system time is considered valid. Disabled if not
+ specified.
+ '';
+
+ systime-fix.threshold_format = mkStrParam "%Y" ''
+ strptime(3) format used to parse threshold option.
+ '';
+
+ tnc-ifmap.client_cert = mkOptionalStrParam ''
+ Path to X.509 certificate file of IF-MAP client.
+ '';
+
+ tnc-ifmap.client_key = mkOptionalStrParam ''
+ Path to private key file of IF-MAP client.
+ '';
+
+ tnc-ifmap.device_name = mkOptionalStrParam ''
+ Unique name of strongSwan server as a PEP and/or PDP device.
+ '';
+
+ tnc-ifmap.renew_session_interval = mkIntParam 150 ''
+ Interval in seconds between periodic IF-MAP RenewSession requests.
+ '';
+
+ tnc-ifmap.server_cert = mkOptionalStrParam ''
+ Path to X.509 certificate file of IF-MAP server.
+ '';
+
+ tnc-ifmap.server_uri = mkStrParam "https://localhost:8444/imap" ''
+ URI of the form [https://]servername[:port][/path].
+ '';
+
+ tnc-ifmap.username_password = mkOptionalStrParam ''
+ Credentials of IF-MAP client of the form
+ username:password. If set, make sure to adjust the
+ permissions of the config file accordingly.
+ '';
+
+ tnc-imc.dlcose = mkYesNoParam yes ''
+ Unload IMC after use.
+ '';
+
+ tnc-imc.preferred_language = mkStrParam "en" ''
+ Preferred language for TNC recommendations.
+ '';
+
+ tnc-imv.dlcose = mkYesNoParam yes ''
+ Unload IMV after use.
+ '';
+
+ tnc-imv.recommendation_policy = mkEnumParam ["default" "any" "all"] "default" ''
+ default TNC recommendation policy.
+ '';
+
+ tnc-pdp.pt_tls.enable = mkYesNoParam yes ''
+ Enable PT-TLS protocol on the strongSwan PDP.
+ '';
+
+ tnc-pdp.pt_tls.port = mkIntParam 271 ''
+ PT-TLS server port the strongSwan PDP is listening on.
+ '';
+
+ tnc-pdp.radius.enable = mkYesNoParam yes ''
+ Enable RADIUS protocol on the strongSwan PDP.
+ '';
+
+ tnc-pdp.radius.method = mkStrParam "ttls" ''
+ EAP tunnel method to be used.
+ '';
+
+ tnc-pdp.radius.port = mkIntParam 1812 ''
+ RADIUS server port the strongSwan PDP is listening on.
+ '';
+
+ tnc-pdp.radius.secret = mkOptionalStrParam ''
+ Shared RADIUS secret between strongSwan PDP and NAS. If set, make sure
+ to adjust the permissions of the config file accordingly.
+ '';
+
+ tnc-pdp.server = mkOptionalStrParam ''
+ Name of the strongSwan PDP as contained in the AAA certificate.
+ '';
+
+ tnc-pdp.timeout = mkOptionalIntParam ''
+ Timeout in seconds before closing incomplete connections.
+ '';
+
+ tnccs-11.max_message_size = mkIntParam 45000 ''
+ Maximum size of a PA-TNC message (XML & Base64 encoding).
+ '';
+
+ tnccs-20.max_batch_size = mkIntParam 65522 ''
+ Maximum size of a PB-TNC batch (upper limit via PT-EAP = 65529).
+ '';
+
+ tnccs-20.max_message_size = mkIntParam 65490 ''
+ Maximum size of a PA-TNC message (upper limit via PT-EAP = 65497).
+ '';
+
+ tnccs-20.mutual = mkYesNoParam no ''
+ Enable PB-TNC mutual protocol.
+ '';
+
+ tpm.use_rng = mkYesNoParam no ''
+ Whether the TPM should be used as RNG.
+ '';
+
+ unbound.dlv_anchors = mkOptionalStrParam ''
+ File to read trusted keys for DLV from. It uses the same format as
+ . Only one DLV can be configured, which is
+ then used as a root trusted DLV, this means that it is a lookaside for the
+ root.
+ '';
+
+ unbound.resolv_conf = mkStrParam "/etc/resolv.conf" ''
+ File to read DNS resolver configuration from.
+ '';
+
+ unbound.trust_anchors = mkStrParam "/etc/ipsec.d/dnssec.keys" ''
+ File to read DNSSEC trust anchors from (usually root zone KSK). The
+ format of the file is the standard DNS Zone file format, anchors can be
+ stored as DS or DNSKEY entries in the file.
+ '';
+
+ updown.dns_handler = mkYesNoParam no ''
+ Whether the updown script should handle DNS servers assigned via IKEv1
+ Mode Config or IKEv2 Config Payloads (if enabled they can't be handled
+ by other plugins, like resolve).
+ '';
+
+ vici.socket = mkStrParam "unix://\${piddir}/charon.vici" ''
+ Socket the vici plugin serves clients.
+ '';
+
+ whitelist.enable = mkYesNoParam yes ''
+ Enable loaded whitelist plugin.
+ '';
+
+ whitelist.socket = mkStrParam "unix://\${piddir}/charon.wlst" ''
+ Socket provided by the whitelist plugin.
+ '';
+
+ xauth-eap.backend = mkStrParam "radius" ''
+ EAP plugin to be used as backend for XAuth credential verification, see
+ XAuthEAP.
+ '';
+
+ xauth-pam.pam_service = mkStrParam "login" ''
+ PAM service to be used for authentication, see XAuthPAM.
+ '';
+
+ xauth-pam.session = mkYesNoParam no ''
+ Open/close a PAM session for each active IKE_SA.
+ '';
+
+ xauth-pam.trim_email = mkYesNoParam yes ''
+ If an email address is given as an XAuth username, trim it to just the
+ username part.
+ '';
+}
diff --git a/nixos/modules/services/networking/strongswan-swanctl/strongswan-libimcv-params.nix b/nixos/modules/services/networking/strongswan-swanctl/strongswan-libimcv-params.nix
new file mode 100644
index 00000000000..2ca2c9c396e
--- /dev/null
+++ b/nixos/modules/services/networking/strongswan-swanctl/strongswan-libimcv-params.nix
@@ -0,0 +1,291 @@
+lib : with (import ./param-constructors.nix lib); {
+ debug_level = mkIntParam 1 ''
+ Debug level for a stand-alone libimcv library.
+ '';
+
+ load = mkSpaceSepListParam ["random" "nonce" "gmp" "pubkey" "x509"] ''
+ Plugins to load in IMC/IMVs with stand-alone libimcv library.
+ '';
+
+ stderr_quiet = mkYesNoParam no ''
+ Disable the output to stderr with a stand-alone libimcv library.
+ '';
+
+ swid_gen = {
+ command = mkStrParam "/usr/local/bin/swid_generator" ''
+ SWID generator command to be executed.
+ '';
+
+ tag_creator = {
+ name = mkStrParam "strongSwan Project" ''
+ Name of the tagCreator entity.
+ '';
+
+ regid = mkStrParam "strongswan.org" ''
+ regid of the tagCreator entity.
+ '';
+ };
+ };
+
+ plugins = {
+
+ imc-attestation = {
+ aik_blob = mkOptionalStrParam ''
+ AIK encrypted private key blob file.
+ '';
+
+ aik_cert = mkOptionalStrParam ''
+ AIK certificate file.
+ '';
+
+ aik_handle = mkOptionalStrParam ''
+ AIK object handle, e.g. 0x81010003.
+ '';
+
+ aik_pubkey = mkOptionalStrParam ''
+ AIK public key file.
+ '';
+
+ mandatory_dh_groups = mkYesNoParam yes ''
+ Enforce mandatory Diffie-Hellman groups
+ '';
+
+ nonce_len = mkIntParam 20 ''
+ DH nonce length.
+ '';
+
+ pcr_info = mkYesNoParam no ''
+ Whether to send pcr_before and pcr_after info.
+ '';
+
+ use_quote2 = mkYesNoParam yes ''
+ Use Quote2 AIK signature instead of Quote signature.
+ '';
+
+ use_version_info = mkYesNoParam no ''
+ Version Info is included in Quote2 signature.
+ '';
+ };
+
+ imc-hcd.push_info = mkYesNoParam yes ''
+ Send quadruple info without being prompted.
+ '';
+
+ imc-hcd.subtypes = let
+ imcHcdSubtypeParams = let
+ softwareParams = mkAttrsOfParams {
+ name = mkOptionalStrParam ''
+ Name of the software installed on the hardcopy device.
+ '';
+
+ patches = mkOptionalStrParam ''
+ String describing all patches applied to the given software on this
+ hardcopy device. The individual patches are separated by a newline
+ character '\\n'.
+ '';
+
+ string_version = mkOptionalStrParam ''
+ String describing the version of the given software on this hardcopy device.
+ '';
+
+ version = mkOptionalStrParam ''
+ Hex-encoded version string with a length of 16 octets consisting of
+ the fields major version number (4 octets), minor version number (4
+ octets), build number (4 octets), service pack major number (2
+ octets) and service pack minor number (2 octets).
+ '';
+ } ''
+ Defines a software section having an arbitrary name.
+ '';
+ in {
+ firmware = softwareParams;
+ resident_application = softwareParams;
+ user_application = softwareParams;
+ attributes_natural_language = mkStrParam "en" ''
+ Variable length natural language tag conforming to RFC 5646 specifies
+ the language to be used in the health assessment message of a given
+ subtype.
+ '';
+ };
+ in {
+ system = imcHcdSubtypeParams // {
+ certification_state = mkOptionalStrParam ''
+ Hex-encoded certification state.
+ '';
+
+ configuration_state = mkOptionalStrParam ''
+ Hex-encoded configuration state.
+ '';
+
+ machine_type_model = mkOptionalStrParam ''
+ String specifying the machine type and model of the hardcopy device.
+ '';
+
+ pstn_fax_enabled = mkYesNoParam no ''
+ Specifies if a PSTN facsimile interface is installed and enabled on the
+ hardcopy device.
+ '';
+
+ time_source = mkOptionalStrParam ''
+ String specifying the hostname of the network time server used by the
+ hardcopy device.
+ '';
+
+ user_application_enabled = mkYesNoParam no ''
+ Specifies if users can dynamically download and execute applications on
+ the hardcopy device.
+ '';
+
+ user_application_persistence_enabled = mkYesNoParam no ''
+ Specifies if user dynamically downloaded applications can persist outside
+ the boundaries of a single job on the hardcopy device.
+ '';
+
+ vendor_name = mkOptionalStrParam ''
+ String specifying the manufacturer of the hardcopy device.
+ '';
+
+ vendor_smi_code = mkOptionalIntParam ''
+ Integer specifying the globally unique 24-bit SMI code assigned to the
+ manufacturer of the hardcopy device.
+ '';
+ };
+ control = imcHcdSubtypeParams;
+ marker = imcHcdSubtypeParams;
+ finisher = imcHcdSubtypeParams;
+ interface = imcHcdSubtypeParams;
+ scanner = imcHcdSubtypeParams;
+ };
+
+ imc-os = {
+ device_cert = mkOptionalStrParam ''
+ Manually set the path to the client device certificate
+ (e.g. /etc/pts/aikCert.der)
+ '';
+
+ device_id = mkOptionalStrParam ''
+ Manually set the client device ID in hexadecimal format
+ (e.g. 1083f03988c9762703b1c1080c2e46f72b99cc31)
+ '';
+
+ device_pubkey = mkOptionalStrParam ''
+ Manually set the path to the client device public key
+ (e.g. /etc/pts/aikPub.der)
+ '';
+
+ push_info = mkYesNoParam yes ''
+ Send operating system info without being prompted.
+ '';
+ };
+
+ imc-scanner.push_info = mkYesNoParam yes ''
+ Send open listening ports without being prompted.
+ '';
+
+ imc-swid = {
+ swid_full = mkYesNoParam no ''
+ Include file information in the XML-encoded SWID tags.
+ '';
+
+ swid_pretty = mkYesNoParam no ''
+ Generate XML-encoded SWID tags with pretty indentation.
+ '';
+
+ swid_directory = mkStrParam "\${prefix}/share" ''
+ Directory where SWID tags are located.
+ '';
+ };
+
+ imc-swima = {
+ eid_epoch = mkHexParam "0x11223344" ''
+ Set 32 bit epoch value for event IDs manually if software collector
+ database is not available.
+ '';
+
+ swid_database = mkOptionalStrParam ''
+ URI to software collector database containing event timestamps, software
+ creation and deletion events and collected software identifiers. If it
+ contains a password, make sure to adjust the permissions of the config
+ file accordingly.
+ '';
+
+ swid_directory = mkStrParam "\${prefix}/share" ''
+ Directory where SWID tags are located.
+ '';
+
+ swid_pretty = mkYesNoParam no ''
+ Generate XML-encoded SWID tags with pretty indentation.
+ '';
+
+ swid_full = mkYesNoParam no ''
+ Include file information in the XML-encoded SWID tags.
+ '';
+ };
+
+ imc-test = {
+ additional_ids = mkIntParam 0 ''
+ Number of additional IMC IDs.
+ '';
+
+ command = mkStrParam "none" ''
+ Command to be sent to the Test IMV.
+ '';
+
+ dummy_size = mkIntParam 0 ''
+ Size of dummy attribute to be sent to the Test IMV (0 = disabled).
+ '';
+
+ retry = mkYesNoParam no ''
+ Do a handshake retry.
+ '';
+
+ retry_command = mkOptionalStrParam ''
+ Command to be sent to the IMV Test in the handshake retry.
+ '';
+ };
+
+ imv-attestation = {
+ cadir = mkOptionalStrParam ''
+ Path to directory with AIK cacerts.
+ '';
+
+ dh_group = mkStrParam "ecp256" ''
+ Preferred Diffie-Hellman group.
+ '';
+
+ hash_algorithm = mkStrParam "sha256" ''
+ Preferred measurement hash algorithm.
+ '';
+
+ min_nonce_len = mkIntParam 0 ''
+ DH minimum nonce length.
+ '';
+
+ remediation_uri = mkOptionalStrParam ''
+ URI pointing to attestation remediation instructions.
+ '';
+ };
+
+ imv-os.remediation_uri = mkOptionalStrParam ''
+ URI pointing to operating system remediation instructions.
+ '';
+
+ imv-scanner.remediation_uri = mkOptionalStrParam ''
+ URI pointing to scanner remediation instructions.
+ '';
+
+ imv-swima.rest_api = {
+ uri = mkOptionalStrParam ''
+ HTTP URI of the SWID REST API.
+ '';
+
+ timeout = mkIntParam 120 ''
+ Timeout of SWID REST API HTTP POST transaction.
+ '';
+ };
+
+ imv-test.rounds = mkIntParam 0 ''
+ Number of IMC-IMV retry rounds.
+ '';
+ };
+}
diff --git a/nixos/modules/services/networking/strongswan-swanctl/strongswan-loglevel-params.nix b/nixos/modules/services/networking/strongswan-swanctl/strongswan-loglevel-params.nix
new file mode 100644
index 00000000000..0f517d8ead4
--- /dev/null
+++ b/nixos/modules/services/networking/strongswan-swanctl/strongswan-loglevel-params.nix
@@ -0,0 +1,29 @@
+lib : with (import ./param-constructors.nix lib);
+
+let mkJournalParam = description :
+ mkEnumParam [(-1) 0 1 2 3 4] 0 "Logging level for ${description}";
+in {
+ default = mkIntParam 1 ''
+ Specifies the default loglevel to be used for subsystems for which no
+ specific loglevel is defined.
+ '';
+
+ app = mkJournalParam "applications other than daemons.";
+ asn = mkJournalParam "low-level encoding/decoding (ASN.1, X.509 etc.)";
+ cfg = mkJournalParam "configuration management and plugins.";
+ chd = mkJournalParam "CHILD_SA/IPsec SA.";
+ dmn = mkJournalParam "main daemon setup/cleanup/signal handling.";
+ enc = mkJournalParam "packet encoding/decoding encryption/decryption operations.";
+ esp = mkJournalParam "libipsec library messages.";
+ ike = mkJournalParam "IKE_SA/ISAKMP SA.";
+ imc = mkJournalParam "integrity Measurement Collector.";
+ imv = mkJournalParam "integrity Measurement Verifier.";
+ job = mkJournalParam "jobs queuing/processing and thread pool management.";
+ knl = mkJournalParam "IPsec/Networking kernel interface.";
+ lib = mkJournalParam "libstrongwan library messages.";
+ mgr = mkJournalParam "IKE_SA manager, handling synchronization for IKE_SA access.";
+ net = mkJournalParam "IKE network communication.";
+ pts = mkJournalParam "platform Trust Service.";
+ tls = mkJournalParam "libtls library messages.";
+ tnc = mkJournalParam "trusted Network Connect.";
+}
diff --git a/nixos/modules/services/networking/strongswan-swanctl/strongswan-params.nix b/nixos/modules/services/networking/strongswan-swanctl/strongswan-params.nix
new file mode 100644
index 00000000000..ad805305370
--- /dev/null
+++ b/nixos/modules/services/networking/strongswan-swanctl/strongswan-params.nix
@@ -0,0 +1,228 @@
+# See: https://wiki.strongswan.org/projects/strongswan/wiki/StrongswanConf
+#
+# When strongSwan is upgraded please update the parameters in this file. You can
+# see which parameters should be deleted, changed or added by diffing
+# the strongswan conf directory:
+#
+# git clone https://github.com/strongswan/strongswan.git
+# cd strongswan
+# git diff 5.5.3..5.6.0 conf/
+
+lib: with (import ./param-constructors.nix lib);
+
+let charonParams = import ./strongswan-charon-params.nix lib;
+in {
+ aikgen = {
+ load = mkSpaceSepListParam [] ''
+ Plugins to load in ipsec aikgen tool.
+ '';
+ };
+ attest = {
+ database = mkOptionalStrParam ''
+ File measurement information database URI. If it contains a password,
+ make sure to adjust the permissions of the config file accordingly.
+ '';
+
+ load = mkSpaceSepListParam [] ''
+ Plugins to load in ipsec attest tool.
+ '';
+ };
+
+ charon = charonParams;
+
+ charon-nm = {
+ ca_dir = mkStrParam "" ''
+ Directory from which to load CA certificates if no certificate is
+ configured.
+ '';
+ };
+
+ charon-systemd = charonParams // {
+ journal = import ./strongswan-loglevel-params.nix lib;
+ };
+
+ imv_policy_manager = {
+ command_allow = mkOptionalStrParam ''
+ Shell command to be executed with recommendation allow.
+ '';
+
+ command_block = mkOptionalStrParam ''
+ Shell command to be executed with all other recommendations.
+ '';
+
+ database = mkOptionalStrParam ''
+ Database URI for the database that stores the package information. If it
+ contains a password, make sure to adjust permissions of the config file
+ accordingly.
+ '';
+
+ load = mkSpaceSepListParam ["sqlite"] ''
+ Plugins to load in IMV policy manager.
+ '';
+ };
+
+ libimcv = import ./strongswan-libimcv-params.nix lib;
+
+ manager = {
+ database = mkOptionalStrParam ''
+ Credential database URI for manager. If it contains a password, make
+ sure to adjust the permissions of the config file accordingly.
+ '';
+
+ debug = mkYesNoParam no ''
+ Enable debugging in manager.
+ '';
+
+ load = mkSpaceSepListParam [] ''
+ Plugins to load in manager.
+ '';
+
+ socket = mkOptionalStrParam ''
+ FastCGI socket of manager, to run it statically.
+ '';
+
+ threads = mkIntParam 10 ''
+ Threads to use for request handling.
+ '';
+
+ timeout = mkDurationParam "15m" ''
+ Session timeout for manager.
+ '';
+ };
+
+ medcli = {
+ database = mkOptionalStrParam ''
+ Mediation client database URI. If it contains a password, make sure to
+ adjust the permissions of the config file accordingly.
+ '';
+
+ dpd = mkDurationParam "5m" ''
+ DPD timeout to use in mediation client plugin.
+ '';
+
+ rekey = mkDurationParam "20m" ''
+ Rekeying time on mediation connections in mediation client plugin.
+ '';
+ };
+
+ medsrv = {
+ database = mkOptionalStrParam ''
+ Mediation server database URI. If it contains a password, make sure to
+ adjust the permissions of the config file accordingly.
+ '';
+
+ debug = mkYesNoParam no ''
+ Debugging in mediation server web application.
+ '';
+
+ dpd = mkDurationParam "5m" ''
+ DPD timeout to use in mediation server plugin.
+ '';
+
+ load = mkSpaceSepListParam [] ''
+ Plugins to load in mediation server plugin.
+ '';
+
+ password_length = mkIntParam 6 ''
+ Minimum password length required for mediation server user accounts.
+ '';
+
+ rekey = mkDurationParam "20m" ''
+ Rekeying time on mediation connections in mediation server plugin.
+ '';
+
+ socket = mkOptionalStrParam ''
+ Run Mediation server web application statically on socket.
+ '';
+
+ threads = mkIntParam 5 ''
+ Number of thread for mediation service web application.
+ '';
+
+ timeout = mkDurationParam "15m" ''
+ Session timeout for mediation service.
+ '';
+ };
+
+ pacman.database = mkOptionalStrParam ''
+ Database URI for the database that stores the package information. If it
+ contains a password, make sure to adjust the permissions of the config
+ file accordingly.
+ '';
+
+ pki.load = mkSpaceSepListParam [] ''
+ Plugins to load in ipsec pki tool.
+ '';
+
+ pool = {
+ database = mkOptionalStrParam ''
+ Database URI for the database that stores IP pools and configuration
+ attributes. If it contains a password, make sure to adjust the
+ permissions of the config file accordingly.
+ '';
+
+ load = mkSpaceSepListParam [] ''
+ Plugins to load in ipsec pool tool.
+ '';
+ };
+
+ pt-tls-client.load = mkSpaceSepListParam [] ''
+ Plugins to load in ipsec pt-tls-client tool.
+ '';
+
+ scepclient.load = mkSpaceSepListParam [] ''
+ Plugins to load in ipsec scepclient tool.
+ '';
+
+ starter = {
+ config_file = mkStrParam "\${sysconfdir}/ipsec.conf" ''
+ Location of the ipsec.conf file.
+ '';
+
+ load_warning = mkYesNoParam yes ''
+ Show charon.load setting warning, see
+ https://wiki.strongswan.org/projects/strongswan/wiki/PluginLoad
+ '';
+ };
+
+ sw-collector = {
+ database = mkOptionalStrParam ''
+ URI to software collector database containing event timestamps,
+ software creation and deletion events and collected software
+ identifiers. If it contains a password, make sure to adjust the
+ permissions of the config file accordingly.
+ '';
+
+ first_file = mkStrParam "/var/log/bootstrap.log" ''
+ Path pointing to file created when the Linux OS was installed.
+ '';
+
+ first_time = mkStrParam "0000-00-00T00:00:00Z" ''
+ Time in UTC when the Linux OS was installed.
+ '';
+
+ history = mkOptionalStrParam ''
+ Path pointing to apt history.log file.
+ '';
+
+ rest_api = {
+ uri = mkOptionalStrParam ''
+ HTTP URI of the central collector's REST API.
+ '';
+
+ timeout = mkIntParam 120 ''
+ Timeout of REST API HTTP POST transaction.
+ '';
+ };
+
+ load = mkSpaceSepListParam [] "Plugins to load in sw-collector tool.";
+ };
+
+ swanctl = {
+ load = mkSpaceSepListParam [] "Plugins to load in swanctl.";
+
+ socket = mkStrParam "unix://\${piddir}/charon.vici" ''
+ VICI socket to connect to by default.
+ '';
+ };
+}
diff --git a/nixos/modules/services/networking/strongswan-swanctl/swanctl-params.nix b/nixos/modules/services/networking/strongswan-swanctl/swanctl-params.nix
new file mode 100644
index 00000000000..095ae549730
--- /dev/null
+++ b/nixos/modules/services/networking/strongswan-swanctl/swanctl-params.nix
@@ -0,0 +1,1145 @@
+# See: https://wiki.strongswan.org/projects/strongswan/wiki/Swanctlconf
+#
+# When strongSwan is upgraded please update the parameters in this file. You can
+# see which parameters should be deleted, changed or added by diffing
+# swanctl.opt:
+#
+# git clone https://github.com/strongswan/strongswan.git
+# cd strongswan
+# git diff 5.5.3..5.6.0 src/swanctl/swanctl.opt
+
+lib: with (import ./param-constructors.nix lib);
+
+let
+ certParams = {
+ file = mkOptionalStrParam ''
+ Absolute path to the certificate to load. Passed as-is to the daemon, so
+ it must be readable by it.
+
+ Configure either this or , but not both, in one section.
+ '';
+
+ handle = mkOptionalHexParam ''
+ Hex-encoded CKA_ID or handle of the certificate on a token or TPM,
+ respectively.
+
+ Configure either this or , but not both, in one section.
+ '';
+
+ slot = mkOptionalIntParam ''
+ Optional slot number of the token that stores the certificate.
+ '';
+
+ module = mkOptionalStrParam ''
+ Optional PKCS#11 module name.
+ '';
+ };
+in {
+ authorities = mkAttrsOfParams ({
+
+ cacert = mkOptionalStrParam ''
+ The certificates may use a relative path from the swanctl
+ x509ca directory or an absolute path.
+
+ Configure one of ,
+ , or
+ per section.
+ '';
+
+ cert_uri_base = mkOptionalStrParam ''
+ Defines the base URI for the Hash and URL feature supported by
+ IKEv2. Instead of exchanging complete certificates, IKEv2 allows one to
+ send an URI that resolves to the DER encoded certificate. The certificate
+ URIs are built by appending the SHA1 hash of the DER encoded certificates
+ to this base URI.
+ '';
+
+ crl_uris = mkCommaSepListParam [] ''
+ List of CRL distribution points (ldap, http, or file URI).
+ '';
+
+ ocsp_uris = mkCommaSepListParam [] ''
+ List of OCSP URIs.
+ '';
+
+ } // certParams) ''
+ Section defining complementary attributes of certification authorities, each
+ in its own subsection with an arbitrary yet unique name
+ '';
+
+ connections = mkAttrsOfParams {
+
+ version = mkIntParam 0 ''
+ IKE major version to use for connection.
+
+ 1 uses IKEv1 aka ISAKMP,
+ 2 uses IKEv2.
+ A connection using the default of 0 accepts both IKEv1 and IKEv2 as
+ responder, and initiates the connection actively with IKEv2.
+
+ '';
+
+ local_addrs = mkCommaSepListParam [] ''
+ Local address(es) to use for IKE communication. Takes
+ single IPv4/IPv6 addresses, DNS names, CIDR subnets or IP address ranges.
+
+ As initiator, the first non-range/non-subnet is used to initiate the
+ connection from. As responder, the local destination address must match at
+ least to one of the specified addresses, subnets or ranges.
+
+ If FQDNs are assigned they are resolved every time a configuration lookup
+ is done. If DNS resolution times out, the lookup is delayed for that time.
+ '';
+
+ remote_addrs = mkCommaSepListParam [] ''
+ Remote address(es) to use for IKE communication. Takes
+ single IPv4/IPv6 addresses, DNS names, CIDR subnets or IP address ranges.
+
+ As initiator, the first non-range/non-subnet is used to initiate the
+ connection to. As responder, the initiator source address must match at
+ least to one of the specified addresses, subnets or ranges.
+
+ If FQDNs are assigned they are resolved every time a configuration lookup
+ is done. If DNS resolution times out, the lookup is delayed for that time.
+ To initiate a connection, at least one specific address or DNS name must
+ be specified.
+ '';
+
+ local_port = mkIntParam 500 ''
+ Local UDP port for IKE communication. By default the port of the socket
+ backend is used, which is usually 500. If port
+ 500 is used, automatic IKE port floating to port
+ 4500 is used to work around NAT issues.
+
+ Using a non-default local IKE port requires support from the socket
+ backend in use (socket-dynamic).
+ '';
+
+ remote_port = mkIntParam 500 ''
+ Remote UDP port for IKE communication. If the default of port
+ 500 is used, automatic IKE port floating to port
+ 4500 is used to work around NAT issues.
+ '';
+
+ proposals = mkCommaSepListParam ["default"] ''
+ A proposal is a set of algorithms. For non-AEAD algorithms, this includes
+ for IKE an encryption algorithm, an integrity algorithm, a pseudo random
+ function and a Diffie-Hellman group. For AEAD algorithms, instead of
+ encryption and integrity algorithms, a combined algorithm is used.
+
+ In IKEv2, multiple algorithms of the same kind can be specified in a
+ single proposal, from which one gets selected. In IKEv1, only one
+ algorithm per kind is allowed per proposal, more algorithms get implicitly
+ stripped. Use multiple proposals to offer different algorithms
+ combinations in IKEv1.
+
+ Algorithm keywords get separated using dashes. Multiple proposals may be
+ specified in a list. The special value default forms a
+ default proposal of supported algorithms considered safe, and is usually a
+ good choice for interoperability.
+ '';
+
+ vips = mkCommaSepListParam [] ''
+ List of virtual IPs to request in IKEv2 configuration payloads or IKEv1
+ Mode Config. The wildcard addresses 0.0.0.0 and
+ :: request an arbitrary address, specific addresses may
+ be defined. The responder may return a different address, though, or none
+ at all.
+ '';
+
+ aggressive = mkYesNoParam no ''
+ Enables Aggressive Mode instead of Main Mode with Identity
+ Protection. Aggressive Mode is considered less secure, because the ID and
+ HASH payloads are exchanged unprotected. This allows a passive attacker to
+ snoop peer identities, and even worse, start dictionary attacks on the
+ Preshared Key.
+ '';
+
+ pull = mkYesNoParam yes ''
+ If the default of yes is used, Mode Config works in pull mode, where the
+ initiator actively requests a virtual IP. With no, push mode is used,
+ where the responder pushes down a virtual IP to the initiating peer.
+
+ Push mode is currently supported for IKEv1, but not in IKEv2. It is used
+ by a few implementations only, pull mode is recommended.
+ '';
+
+ dscp = mkStrParam "000000" ''
+ Differentiated Services Field Codepoint to set on outgoing IKE packets for
+ this connection. The value is a six digit binary encoded string specifying
+ the Codepoint to set, as defined in RFC 2474.
+ '';
+
+ encap = mkYesNoParam no ''
+ To enforce UDP encapsulation of ESP packets, the IKE daemon can fake the
+ NAT detection payloads. This makes the peer believe that NAT takes place
+ on the path, forcing it to encapsulate ESP packets in UDP.
+
+ Usually this is not required, but it can help to work around connectivity
+ issues with too restrictive intermediary firewalls.
+ '';
+
+ mobike = mkYesNoParam yes ''
+ Enables MOBIKE on IKEv2 connections. MOBIKE is enabled by default on IKEv2
+ connections, and allows mobility of clients and multi-homing on servers by
+ migrating active IPsec tunnels.
+
+ Usually keeping MOBIKE enabled is unproblematic, as it is not used if the
+ peer does not indicate support for it. However, due to the design of
+ MOBIKE, IKEv2 always floats to port 4500 starting from the second
+ exchange. Some implementations don't like this behavior, hence it can be
+ disabled.
+ '';
+
+ dpd_delay = mkDurationParam "0s" ''
+ Interval to check the liveness of a peer actively using IKEv2
+ INFORMATIONAL exchanges or IKEv1 R_U_THERE messages. Active DPD checking
+ is only enforced if no IKE or ESP/AH packet has been received for the
+ configured DPD delay.
+ '';
+
+ dpd_timeout = mkDurationParam "0s" ''
+ Charon by default uses the normal retransmission mechanism and timeouts to
+ check the liveness of a peer, as all messages are used for liveness
+ checking. For compatibility reasons, with IKEv1 a custom interval may be
+ specified; this option has no effect on connections using IKEv2.
+ '';
+
+ fragmentation = mkEnumParam ["yes" "accept" "force" "no"] "yes" ''
+ Use IKE fragmentation (proprietary IKEv1 extension or RFC 7383 IKEv2
+ fragmentation). Acceptable values are yes (the default
+ since 5.5.1), accept (since versions:5.5.3),
+ force and no.
+
+ If set to yes, and the peer
+ supports it, oversized IKE messages will be sent in fragments.
+ If set to
+ accept, support for fragmentation is announced to the peer but the daemon
+ does not send its own messages in fragments.
+ If set to force (only
+ supported for IKEv1) the initial IKE message will already be fragmented if
+ required.
+ Finally, setting the option to no will disable announcing
+ support for this feature.
+
+
+ Note that fragmented IKE messages sent by a peer are always processed
+ irrespective of the value of this option (even when set to no).
+ '';
+
+ send_certreq = mkYesNoParam yes ''
+ Send certificate request payloads to offer trusted root CA certificates to
+ the peer. Certificate requests help the peer to choose an appropriate
+ certificate/private key for authentication and are enabled by default.
+ Disabling certificate requests can be useful if too many trusted root CA
+ certificates are installed, as each certificate request increases the size
+ of the initial IKE packets.
+ '';
+
+ send_cert = mkEnumParam ["always" "never" "ifasked" ] "ifasked" ''
+ Send certificate payloads when using certificate authentication.
+
+ With the default of ifasked the daemon sends
+ certificate payloads only if certificate requests have been received.
+ never disables sending of certificate payloads
+ altogether,
+ always causes certificate payloads to be sent
+ unconditionally whenever certificate authentication is used.
+
+ '';
+
+ keyingtries = mkIntParam 1 ''
+ Number of retransmission sequences to perform during initial
+ connect. Instead of giving up initiation after the first retransmission
+ sequence with the default value of 1, additional
+ sequences may be started according to the configured value. A value of
+ 0 initiates a new sequence until the connection
+ establishes or fails with a permanent error.
+ '';
+
+ unique = mkEnumParam ["no" "never" "keep" "replace"] "no" ''
+ Connection uniqueness policy to enforce. To avoid multiple connections
+ from the same user, a uniqueness policy can be enforced.
+
+
+
+ The value never does never enforce such a policy, even
+ if a peer included INITIAL_CONTACT notification messages,
+
+
+ whereas no replaces existing connections for the same
+ identity if a new one has the INITIAL_CONTACT notify.
+
+
+ keep rejects new connection attempts if the same user
+ already has an active connection,
+
+
+ replace deletes any existing connection if a new one
+ for the same user gets established.
+
+
+ To compare connections for uniqueness, the remote IKE identity is used. If
+ EAP or XAuth authentication is involved, the EAP-Identity or XAuth
+ username is used to enforce the uniqueness policy instead.
+
+ On initiators this setting specifies whether an INITIAL_CONTACT notify is
+ sent during IKE_AUTH if no existing connection is found with the remote
+ peer (determined by the identities of the first authentication
+ round). Only if set to keep or replace will the client send a notify.
+ '';
+
+ reauth_time = mkDurationParam "0s" ''
+ Time to schedule IKE reauthentication. IKE reauthentication recreates the
+ IKE/ISAKMP SA from scratch and re-evaluates the credentials. In asymmetric
+ configurations (with EAP or configuration payloads) it might not be
+ possible to actively reauthenticate as responder. The IKEv2
+ reauthentication lifetime negotiation can instruct the client to perform
+ reauthentication.
+
+ Reauthentication is disabled by default. Enabling it usually may lead to
+ small connection interruptions, as strongSwan uses a break-before-make
+ policy with IKEv2 to avoid any conflicts with associated tunnel resources.
+ '';
+
+ rekey_time = mkDurationParam "4h" ''
+ IKE rekeying refreshes key material using a Diffie-Hellman exchange, but
+ does not re-check associated credentials. It is supported in IKEv2 only,
+ IKEv1 performs a reauthentication procedure instead.
+
+ With the default value IKE rekeying is scheduled every 4 hours, minus the
+ configured rand_time. If a reauth_time is configured, rekey_time defaults
+ to zero, disabling rekeying; explicitly set both to enforce rekeying and
+ reauthentication.
+ '';
+
+ over_time = mkOptionalDurationParam ''
+ Hard IKE_SA lifetime if rekey/reauth does not complete, as time. To avoid
+ having an IKE/ISAKMP kept alive if IKE reauthentication or rekeying fails
+ perpetually, a maximum hard lifetime may be specified. If the IKE_SA fails
+ to rekey or reauthenticate within the specified time, the IKE_SA gets
+ closed.
+
+ In contrast to CHILD_SA rekeying, over_time is relative in time to the
+ rekey_time and reauth_time values, as it applies to both.
+
+ The default is 10% of the longer of and
+ .
+ '';
+
+ rand_time = mkOptionalDurationParam ''
+ Time range from which to choose a random value to subtract from
+ rekey/reauth times. To avoid having both peers initiating the rekey/reauth
+ procedure simultaneously, a random time gets subtracted from the
+ rekey/reauth times.
+
+ The default is equal to the configured .
+ '';
+
+ pools = mkCommaSepListParam [] ''
+ List of named IP pools to allocate virtual IP addresses
+ and other configuration attributes from. Each name references a pool by
+ name from either the pools section or an external pool.
+ '';
+
+ mediation = mkYesNoParam no ''
+ Whether this connection is a mediation connection, that is, whether this
+ connection is used to mediate other connections using the IKEv2 Mediation
+ Extension. Mediation connections create no CHILD_SA.
+ '';
+
+ mediated_by = mkOptionalStrParam ''
+ The name of the connection to mediate this connection through. If given,
+ the connection will be mediated through the named mediation
+ connection. The mediation connection must have mediation enabled.
+ '';
+
+ mediation_peer = mkOptionalStrParam ''
+ Identity under which the peer is registered at the mediation server, that
+ is, the IKE identity the other end of this connection uses as its local
+ identity on its connection to the mediation server. This is the identity
+ we request the mediation server to mediate us with. Only relevant on
+ connections that set mediated_by. If it is not given, the remote IKE
+ identity of the first authentication round of this connection will be
+ used.
+ '';
+
+ local = mkPrefixedAttrsOfParams {
+
+ round = mkIntParam 0 ''
+ Optional numeric identifier by which authentication rounds are
+ sorted. If not specified rounds are ordered by their position in the
+ config file/vici message.
+ '';
+
+ certs = mkCommaSepListParam [] ''
+ List of certificate candidates to use for
+ authentication. The certificates may use a relative path from the
+ swanctl x509 directory or an absolute path.
+
+ The certificate used for authentication is selected based on the
+ received certificate request payloads. If no appropriate CA can be
+ located, the first certificate is used.
+ '';
+
+ cert = mkPostfixedAttrsOfParams certParams ''
+ Section for a certificate candidate to use for
+ authentication. Certificates in certs are transmitted as binary blobs,
+ these sections offer more flexibility.
+ '';
+
+ pubkeys = mkCommaSepListParam [] ''
+ List of raw public key candidates to use for
+ authentication. The public keys may use a relative path from the swanctl
+ pubkey directory or an absolute path.
+
+ Even though multiple local public keys could be defined in principle,
+ only the first public key in the list is used for authentication.
+ '';
+
+ auth = mkStrParam "pubkey" ''
+ Authentication to perform locally.
+
+
+ The default pubkey uses public key authentication
+ using a private key associated to a usable certificate.
+
+
+ psk uses pre-shared key authentication.
+
+
+ The IKEv1 specific xauth is used for XAuth or Hybrid
+ authentication,
+
+
+ while the IKEv2 specific eap keyword defines EAP
+ authentication.
+
+
+ For xauth, a specific backend name may be appended,
+ separated by a dash. The appropriate xauth backend is
+ selected to perform the XAuth exchange. For traditional XAuth, the
+ xauth method is usually defined in the second
+ authentication round following an initial pubkey (or
+ psk) round. Using xauth in the
+ first round performs Hybrid Mode client authentication.
+
+
+ For eap, a specific EAP method name may be appended, separated by a
+ dash. An EAP module implementing the appropriate method is selected to
+ perform the EAP conversation.
+
+
+ Since 5.4.0, if both peers support RFC 7427 ("Signature Authentication
+ in IKEv2") specific hash algorithms to be used during IKEv2
+ authentication may be configured. To do so use ike:
+ followed by a trust chain signature scheme constraint (see description
+ of the section's
+ keyword). For example, with ike:pubkey-sha384-sha256
+ a public key signature scheme with either SHA-384 or SHA-256 would get
+ used for authentication, in that order and depending on the hash
+ algorithms supported by the peer. If no specific hash algorithms are
+ configured, the default is to prefer an algorithm that matches or
+ exceeds the strength of the signature key. If no constraints with
+ ike: prefix are configured any signature scheme
+ constraint (without ike: prefix) will also apply to
+ IKEv2 authentication, unless this is disabled in
+ strongswan.conf.
+
+
+ '';
+
+ id = mkOptionalStrParam ''
+ IKE identity to use for authentication round. When using certificate
+ authentication, the IKE identity must be contained in the certificate,
+ either as subject or as subjectAltName.
+ '';
+
+ eap_id = mkOptionalStrParam ''
+ Client EAP-Identity to use in EAP-Identity exchange and the EAP method.
+ '';
+
+ aaa_id = mkOptionalStrParam ''
+ Server side EAP-Identity to expect in the EAP method. Some EAP methods,
+ such as EAP-TLS, use an identity for the server to perform mutual
+ authentication. This identity may differ from the IKE identity,
+ especially when EAP authentication is delegated from the IKE responder
+ to an AAA backend.
+
+ For EAP-(T)TLS, this defines the identity for which the server must
+ provide a certificate in the TLS exchange.
+ '';
+
+ xauth_id = mkOptionalStrParam ''
+ Client XAuth username used in the XAuth exchange.
+ '';
+
+ } ''
+ Section for a local authentication round. A local authentication round
+ defines the rules how authentication is performed for the local
+ peer. Multiple rounds may be defined to use IKEv2 RFC 4739 Multiple
+ Authentication or IKEv1 XAuth.
+
+ Each round is defined in a section having local as
+ prefix, and an optional unique suffix. To define a single authentication
+ round, the suffix may be omitted.
+ '';
+
+ remote = mkPrefixedAttrsOfParams {
+
+ round = mkIntParam 0 ''
+ Optional numeric identifier by which authentication rounds are
+ sorted. If not specified rounds are ordered by their position in the
+ config file/vici message.
+ '';
+
+ id = mkStrParam "%any" ''
+ IKE identity to expect for authentication round. When using certificate
+ authentication, the IKE identity must be contained in the certificate,
+ either as subject or as subjectAltName.
+ '';
+
+ eap_id = mkOptionalStrParam ''
+ Identity to use as peer identity during EAP authentication. If set to
+ %any the EAP-Identity method will be used to ask the
+ client for an EAP identity.
+ '';
+
+ groups = mkCommaSepListParam [] ''
+ Authorization group memberships to require. The peer
+ must prove membership to at least one of the specified groups. Group
+ membership can be certified by different means, for example by
+ appropriate Attribute Certificates or by an AAA backend involved in the
+ authentication.
+ '';
+
+ cert_policy = mkCommaSepListParam [] ''
+ List of certificate policy OIDs the peer's certificate
+ must have. OIDs are specified using the numerical dotted representation.
+ '';
+
+ certs = mkCommaSepListParam [] ''
+ List of certificates to accept for authentication. The certificates may
+ use a relative path from the swanctl x509 directory
+ or an absolute path.
+ '';
+
+ cert = mkPostfixedAttrsOfParams certParams ''
+ Section for a certificate candidate to use for
+ authentication. Certificates in certs are transmitted as binary blobs,
+ these sections offer more flexibility.
+ '';
+
+ cacerts = mkCommaSepListParam [] ''
+ List of CA certificates to accept for
+ authentication. The certificates may use a relative path from the
+ swanctl x509ca directory or an absolute path.
+ '';
+
+ cacert = mkPostfixedAttrsOfParams certParams ''
+ Section for a CA certificate to accept for authentication. Certificates
+ in cacerts are transmitted as binary blobs, these sections offer more
+ flexibility.
+ '';
+
+ pubkeys = mkCommaSepListParam [] ''
+ List of raw public keys to accept for
+ authentication. The public keys may use a relative path from the swanctl
+ pubkey directory or an absolute path.
+ '';
+
+ revocation = mkEnumParam ["strict" "ifuri" "relaxed"] "relaxed" ''
+ Certificate revocation policy for CRL or OCSP revocation.
+
+
+ A strict revocation policy fails if no revocation information is
+ available, i.e. the certificate is not known to be unrevoked.
+
+
+ ifuri fails only if a CRL/OCSP URI is available, but certificate
+ revocation checking fails, i.e. there should be revocation information
+ available, but it could not be obtained.
+
+
+ The default revocation policy relaxed fails only if a certificate is
+ revoked, i.e. it is explicitly known that it is bad.
+
+
+ '';
+
+ auth = mkStrParam "pubkey" ''
+ Authentication to expect from remote. See the
+ section's keyword description about the details of
+ supported mechanisms.
+
+ Since 5.4.0, to require a trustchain public key strength for the remote
+ side, specify the key type followed by the minimum strength in bits (for
+ example ecdsa-384 or
+ rsa-2048-ecdsa-256). To limit the acceptable set of
+ hashing algorithms for trustchain validation, append hash algorithms to
+ pubkey or a key strength definition (for example
+ pubkey-sha1-sha256 or
+ rsa-2048-ecdsa-256-sha256-sha384-sha512). Unless
+ disabled in strongswan.conf, or explicit IKEv2
+ signature constraints are configured (refer to the description of the
+ section's keyword for
+ details), such key types and hash algorithms are also applied as
+ constraints against IKEv2 signature authentication schemes used by the
+ remote side.
+
+ To specify trust chain constraints for EAP-(T)TLS, append a colon to the
+ EAP method, followed by the key type/size and hash algorithm as
+ discussed above (e.g. eap-tls:ecdsa-384-sha384).
+ '';
+
+ } ''
+ Section for a remote authentication round. A remote authentication round
+ defines the constraints how the peers must authenticate to use this
+ connection. Multiple rounds may be defined to use IKEv2 RFC 4739 Multiple
+ Authentication or IKEv1 XAuth.
+
+ Each round is defined in a section having remote as
+ prefix, and an optional unique suffix. To define a single authentication
+ round, the suffix may be omitted.
+ '';
+
+ children = mkAttrsOfParams {
+ ah_proposals = mkCommaSepListParam [] ''
+ AH proposals to offer for the CHILD_SA. A proposal is a set of
+ algorithms. For AH, this includes an integrity algorithm and an optional
+ Diffie-Hellman group. If a DH group is specified, CHILD_SA/Quick Mode
+ rekeying and initial negotiation uses a separate Diffie-Hellman exchange
+ using the specified group (refer to esp_proposals for details).
+
+ In IKEv2, multiple algorithms of the same kind can be specified in a
+ single proposal, from which one gets selected. In IKEv1, only one
+ algorithm per kind is allowed per proposal, more algorithms get
+ implicitly stripped. Use multiple proposals to offer different algorithms
+ combinations in IKEv1.
+
+ Algorithm keywords get separated using dashes. Multiple proposals may be
+ specified in a list. The special value default forms
+ a default proposal of supported algorithms considered safe, and is
+ usually a good choice for interoperability. By default no AH proposals
+ are included, instead ESP is proposed.
+ '';
+
+ esp_proposals = mkCommaSepListParam ["default"] ''
+ ESP proposals to offer for the CHILD_SA. A proposal is a set of
+ algorithms. For ESP non-AEAD proposals, this includes an integrity
+ algorithm, an encryption algorithm, an optional Diffie-Hellman group and
+ an optional Extended Sequence Number Mode indicator. For AEAD proposals,
+ a combined mode algorithm is used instead of the separate
+ encryption/integrity algorithms.
+
+ If a DH group is specified, CHILD_SA/Quick Mode rekeying and initial
+ negotiation use a separate Diffie-Hellman exchange using the specified
+ group. However, for IKEv2, the keys of the CHILD_SA created implicitly
+ with the IKE_SA will always be derived from the IKE_SA's key material. So
+ any DH group specified here will only apply when the CHILD_SA is later
+ rekeyed or is created with a separate CREATE_CHILD_SA exchange. A
+ proposal mismatch might, therefore, not immediately be noticed when the
+ SA is established, but may later cause rekeying to fail.
+
+ Extended Sequence Number support may be indicated with the
+ esn and noesn values, both may be
+ included to indicate support for both modes. If omitted,
+ noesn is assumed.
+
+ In IKEv2, multiple algorithms of the same kind can be specified in a
+ single proposal, from which one gets selected. In IKEv1, only one
+ algorithm per kind is allowed per proposal, more algorithms get
+ implicitly stripped. Use multiple proposals to offer different algorithms
+ combinations in IKEv1.
+
+ Algorithm keywords get separated using dashes. Multiple proposals may be
+ specified as a list. The special value default forms
+ a default proposal of supported algorithms considered safe, and is
+ usually a good choice for interoperability. If no algorithms are
+ specified for AH nor ESP, the default set of algorithms for ESP is
+ included.
+ '';
+
+ sha256_96 = mkYesNoParam no ''
+ HMAC-SHA-256 is used with 128-bit truncation with IPsec. For
+ compatibility with implementations that incorrectly use 96-bit truncation
+ this option may be enabled to configure the shorter truncation length in
+ the kernel. This is not negotiated, so this only works with peers that
+ use the incorrect truncation length (or have this option enabled).
+ '';
+
+ local_ts = mkCommaSepListParam ["dynamic"] ''
+ List of local traffic selectors to include in CHILD_SA. Each selector is
+ a CIDR subnet definition, followed by an optional proto/port
+ selector. The special value dynamic may be used
+ instead of a subnet definition, which gets replaced by the tunnel outer
+ address or the virtual IP, if negotiated. This is the default.
+
+ A protocol/port selector is surrounded by opening and closing square
+ brackets. Between these brackets, a numeric or getservent(3) protocol
+ name may be specified. After the optional protocol restriction, an
+ optional port restriction may be specified, separated by a slash. The
+ port restriction may be numeric, a getservent(3) service name, or the
+ special value opaque for RFC 4301 OPAQUE
+ selectors. Port ranges may be specified as well, none of the kernel
+ backends currently support port ranges, though.
+
+ When IKEv1 is used only the first selector is interpreted, except if the
+ Cisco Unity extension plugin is used. This is due to a limitation of the
+ IKEv1 protocol, which only allows a single pair of selectors per
+ CHILD_SA. So to tunnel traffic matched by several pairs of selectors when
+ using IKEv1 several children (CHILD_SAs) have to be defined that cover
+ the selectors. The IKE daemon uses traffic selector narrowing for IKEv1,
+ the same way it is standardized and implemented for IKEv2. However, this
+ may lead to problems with other implementations. To avoid that, configure
+ identical selectors in such scenarios.
+ '';
+
+ remote_ts = mkCommaSepListParam ["dynamic"] ''
+ List of remote selectors to include in CHILD_SA. See
+ for a description of the selector syntax.
+ '';
+
+ rekey_time = mkDurationParam "1h" ''
+ Time to schedule CHILD_SA rekeying. CHILD_SA rekeying refreshes key
+ material, optionally using a Diffie-Hellman exchange if a group is
+ specified in the proposal. To avoid rekey collisions initiated by both
+ ends simultaneously, a value in the range of
+ gets subtracted to form the effective soft lifetime.
+
+ By default CHILD_SA rekeying is scheduled every hour, minus
+ .
+ '';
+
+ life_time = mkOptionalDurationParam ''
+ Maximum lifetime before CHILD_SA gets closed. Usually this hard lifetime
+ is never reached, because the CHILD_SA gets rekeyed before. If that fails
+ for whatever reason, this limit closes the CHILD_SA. The default is 10%
+ more than the .
+ '';
+
+ rand_time = mkOptionalDurationParam ''
+ Time range from which to choose a random value to subtract from
+ . The default is the difference between
+ and .
+ '';
+
+ rekey_bytes = mkIntParam 0 ''
+ Number of bytes processed before initiating CHILD_SA rekeying. CHILD_SA
+ rekeying refreshes key material, optionally using a Diffie-Hellman
+ exchange if a group is specified in the proposal.
+
+ To avoid rekey collisions initiated by both ends simultaneously, a value
+ in the range of gets subtracted to form the
+ effective soft volume limit.
+
+ Volume based CHILD_SA rekeying is disabled by default.
+ '';
+
+ life_bytes = mkOptionalIntParam ''
+ Maximum bytes processed before CHILD_SA gets closed. Usually this hard
+ volume limit is never reached, because the CHILD_SA gets rekeyed
+ before. If that fails for whatever reason, this limit closes the
+ CHILD_SA. The default is 10% more than .
+ '';
+
+ rand_bytes = mkOptionalIntParam ''
+ Byte range from which to choose a random value to subtract from
+ . The default is the difference between
+ and .
+ '';
+
+ rekey_packets = mkIntParam 0 ''
+ Number of packets processed before initiating CHILD_SA rekeying. CHILD_SA
+ rekeying refreshes key material, optionally using a Diffie-Hellman
+ exchange if a group is specified in the proposal.
+
+ To avoid rekey collisions initiated by both ends simultaneously, a value
+ in the range of gets subtracted to form
+ the effective soft packet count limit.
+
+ Packet count based CHILD_SA rekeying is disabled by default.
+ '';
+
+ life_packets = mkOptionalIntParam ''
+ Maximum number of packets processed before CHILD_SA gets closed. Usually
+ this hard packets limit is never reached, because the CHILD_SA gets
+ rekeyed before. If that fails for whatever reason, this limit closes the
+ CHILD_SA.
+
+ The default is 10% more than .
+ '';
+
+ rand_packets = mkOptionalIntParam ''
+ Packet range from which to choose a random value to subtract from
+ . The default is the difference between
+ and .
+ '';
+
+ updown = mkOptionalStrParam ''
+ Updown script to invoke on CHILD_SA up and down events.
+ '';
+
+ hostaccess = mkYesNoParam yes ''
+ Hostaccess variable to pass to updown script.
+ '';
+
+ mode = mkEnumParam [ "tunnel"
+ "transport"
+ "transport_proxy"
+ "beet"
+ "pass"
+ "drop"
+ ] "tunnel" ''
+ IPsec Mode to establish CHILD_SA with.
+
+
+ tunnel negotiates the CHILD_SA in IPsec Tunnel Mode,
+
+
+ whereas transport uses IPsec Transport Mode.
+
+
+ transport_proxy signifying the special Mobile IPv6
+ Transport Proxy Mode.
+
+
+ beet is the Bound End to End Tunnel mixture mode,
+ working with fixed inner addresses without the need to include them in
+ each packet.
+
+
+ Both transport and beet modes are
+ subject to mode negotiation; tunnel mode is
+ negotiated if the preferred mode is not available.
+
+
+ pass and drop are used to install
+ shunt policies which explicitly bypass the defined traffic from IPsec
+ processing or drop it, respectively.
+
+
+ '';
+
+ policies = mkYesNoParam yes ''
+ Whether to install IPsec policies or not. Disabling this can be useful in
+ some scenarios e.g. MIPv6, where policies are not managed by the IKE
+ daemon. Since 5.3.3.
+ '';
+
+ policies_fwd_out = mkYesNoParam no ''
+ Whether to install outbound FWD IPsec policies or not. Enabling this is
+ required in case there is a drop policy that would match and block
+ forwarded traffic for this CHILD_SA. Since 5.5.1.
+ '';
+
+ dpd_action = mkEnumParam ["clear" "trap" "restart"] "clear" ''
+ Action to perform for this CHILD_SA on DPD timeout. The default clear
+ closes the CHILD_SA and does not take further action. trap installs a
+ trap policy, which will catch matching traffic and tries to re-negotiate
+ the tunnel on-demand. restart immediately tries to re-negotiate the
+ CHILD_SA under a fresh IKE_SA.
+ '';
+
+ ipcomp = mkYesNoParam no ''
+ Enable IPComp compression before encryption. If enabled, IKE tries to
+ negotiate IPComp compression to compress ESP payload data prior to
+ encryption.
+ '';
+
+ inactivity = mkDurationParam "0s" ''
+ Timeout before closing CHILD_SA after inactivity. If no traffic has been
+ processed in either direction for the configured timeout, the CHILD_SA
+ gets closed due to inactivity. The default value of 0 disables inactivity
+ checks.
+ '';
+
+ reqid = mkIntParam 0 ''
+ Fixed reqid to use for this CHILD_SA. This might be helpful in some
+ scenarios, but works only if each CHILD_SA configuration is instantiated
+ not more than once. The default of 0 uses dynamic reqids, allocated
+ incrementally.
+ '';
+
+ priority = mkIntParam 0 ''
+ Optional fixed priority for IPsec policies. This could be useful to
+ install high-priority drop policies. The default of 0 uses dynamically
+ calculated priorities based on the size of the traffic selectors.
+ '';
+
+ interface = mkOptionalStrParam ''
+ Optional interface name to restrict outbound IPsec policies.
+ '';
+
+ mark_in = mkStrParam "0/0x00000000" ''
+ Netfilter mark and mask for input traffic. On Linux Netfilter may
+ require marks on each packet to match an SA having that option set. This
+ allows Netfilter rules to select specific tunnels for incoming
+ traffic. The special value %unique sets a unique mark
+ on each CHILD_SA instance, beyond that the value
+ %unique-dir assigns a different unique mark for each
+ CHILD_SA direction (in/out).
+
+ An additional mask may be appended to the mark, separated by
+ /. The default mask if omitted is
+ 0xffffffff.
+ '';
+
+ mark_out = mkStrParam "0/0x00000000" ''
+ Netfilter mark and mask for output traffic. On Linux Netfilter may
+ require marks on each packet to match a policy having that option
+ set. This allows Netfilter rules to select specific tunnels for outgoing
+ traffic. The special value %unique sets a unique mark
+ on each CHILD_SA instance, beyond that the value
+ %unique-dir assigns a different unique mark for each
+ CHILD_SA direction (in/out).
+
+ An additional mask may be appended to the mark, separated by
+ /. The default mask if omitted is
+ 0xffffffff.
+ '';
+
+ tfc_padding = mkParamOfType (with lib.types; either int (enum ["mtu"])) 0 ''
+ Pads ESP packets with additional data to have a consistent ESP packet
+ size for improved Traffic Flow Confidentiality. The padding defines the
+ minimum size of all ESP packets sent. The default value of
+ 0 disables TFC padding, the special value
+ mtu adds TFC padding to create a packet size equal to
+ the Path Maximum Transfer Unit.
+ '';
+
+ replay_window = mkIntParam 32 ''
+ IPsec replay window to configure for this CHILD_SA. Larger values than
+ the default of 32 are supported using the Netlink
+ backend only, a value of 0 disables IPsec replay
+ protection.
+ '';
+
+ hw_offload = mkYesNoParam no ''
+ Enable hardware offload for this CHILD_SA, if supported by the IPsec
+ implementation.
+ '';
+
+ start_action = mkEnumParam ["none" "trap" "start"] "none" ''
+ Action to perform after loading the configuration.
+
+
+ The default of none loads the connection only, which
+ then can be manually initiated or used as a responder configuration.
+
+
+ The value trap installs a trap policy, which triggers
+ the tunnel as soon as matching traffic has been detected.
+
+
+ The value start initiates the connection actively.
+
+
+ When unloading or replacing a CHILD_SA configuration having a
+ different from none,
+ the inverse action is performed. Configurations with
+ start get closed, while such with
+ trap get uninstalled.
+ '';
+
+ close_action = mkEnumParam ["none" "trap" "start"] "none" ''
+ Action to perform after a CHILD_SA gets closed by the peer.
+
+
+ The default of none does not take any action,
+
+
+ trap installs a trap policy for the CHILD_SA.
+
+
+ start tries to re-create the CHILD_SA.
+
+
+
+ does not provide any guarantee that the
+ CHILD_SA is kept alive. It acts on explicit close messages only, but not
+ on negotiation failures. Use trap policies to reliably re-create failed
+ CHILD_SAs.
+ '';
+
+ } ''
+ CHILD_SA configuration sub-section. Each connection definition may have
+ one or more sections in its subsection. The
+ section name defines the name of the CHILD_SA configuration, which must be
+ unique within the connection (denoted <child> below).
+ '';
+ } ''
+ Section defining IKE connection configurations, each in its own subsection
+ with an arbitrary yet unique name
+ '';
+
+ secrets = let
+ mkEapXauthParams = mkPrefixedAttrsOfParams {
+ secret = mkOptionalStrParam ''
+ Value of the EAP/XAuth secret. It may either be an ASCII string, a hex
+ encoded string if it has a 0x prefix or a Base64 encoded string if it
+ has a 0s prefix in its value.
+ '';
+
+ id = mkPrefixedAttrsOfParam (mkOptionalStrParam "") ''
+ Identity the EAP/XAuth secret belongs to. Multiple unique identities may
+ be specified, each having an id prefix, if a secret
+ is shared between multiple users.
+ '';
+
+ } ''
+ EAP secret section for a specific secret. Each EAP secret is defined in a
+ unique section having the eap prefix. EAP secrets are
+ used for XAuth authentication as well.
+ '';
+
+ in {
+
+ eap = mkEapXauthParams;
+ xauth = mkEapXauthParams;
+
+ ntlm = mkPrefixedAttrsOfParams {
+ secret = mkOptionalStrParam ''
+ Value of the NTLM secret, which is the NT Hash of the actual secret,
+ that is, MD4(UTF-16LE(secret)). The resulting 16-byte value may either
+ be given as a hex encoded string with a 0x prefix or as a Base64 encoded
+ string with a 0s prefix.
+ '';
+
+ id = mkPrefixedAttrsOfParam (mkOptionalStrParam "") ''
+ Identity the NTLM secret belongs to. Multiple unique identities may be
+ specified, each having an id prefix, if a secret is shared between
+ multiple users.
+ '';
+ } ''
+ NTLM secret section for a specific secret. Each NTLM secret is defined in
+ a unique section having the ntlm prefix. NTLM secrets
+ may only be used for EAP-MSCHAPv2 authentication.
+ '';
+
+ ike = mkPrefixedAttrsOfParams {
+ secret = mkOptionalStrParam ''
+ Value of the IKE preshared secret. It may either be an ASCII string, a
+ hex encoded string if it has a 0x prefix or a Base64 encoded string if
+ it has a 0s prefix in its value.
+ '';
+
+ id = mkPrefixedAttrsOfParam (mkOptionalStrParam "") ''
+ IKE identity the IKE preshared secret belongs to. Multiple unique
+ identities may be specified, each having an id
+ prefix, if a secret is shared between multiple peers.
+ '';
+ } ''
+ IKE preshared secret section for a specific secret. Each IKE PSK is
+ defined in a unique section having the ike prefix.
+ '';
+
+ private = mkPrefixedAttrsOfParams {
+ file = mkPrefixedAttrsOfParam (mkOptionalStrParam "") ''
+ File name in the private folder for which this passphrase should be used.
+ '';
+
+ secret = mkOptionalStrParam ''
+ Value of decryption passphrase for private key.
+ '';
+ } ''
+ Private key decryption passphrase for a key in the
+ private folder.
+ '';
+
+ rsa = mkPrefixedAttrsOfParams {
+ file = mkPrefixedAttrsOfParam (mkOptionalStrParam "") ''
+ File name in the rsa folder for which this passphrase
+ should be used.
+ '';
+ secret = mkOptionalStrParam ''
+ Value of decryption passphrase for RSA key.
+ '';
+ } ''
+ Private key decryption passphrase for a key in the rsa
+ folder.
+ '';
+
+ ecdsa = mkPrefixedAttrsOfParams {
+ file = mkPrefixedAttrsOfParam (mkOptionalStrParam "") ''
+ File name in the ecdsa folder for which this
+ passphrase should be used.
+ '';
+ secret = mkOptionalStrParam ''
+ Value of decryption passphrase for ECDSA key.
+ '';
+ } ''
+ Private key decryption passphrase for a key in the
+ ecdsa folder.
+ '';
+
+ pkcs8 = mkPrefixedAttrsOfParams {
+ file = mkPrefixedAttrsOfParam (mkOptionalStrParam "") ''
+ File name in the pkcs8 folder for which this
+ passphrase should be used.
+ '';
+ secret = mkOptionalStrParam ''
+ Value of decryption passphrase for PKCS#8 key.
+ '';
+ } ''
+ Private key decryption passphrase for a key in the
+ pkcs8 folder.
+ '';
+
+ pkcs12 = mkPrefixedAttrsOfParams {
+ file = mkPrefixedAttrsOfParam (mkOptionalStrParam "") ''
+ File name in the pkcs12 folder for which this
+ passphrase should be used.
+ '';
+ secret = mkOptionalStrParam ''
+ Value of decryption passphrase for PKCS#12 container.
+ '';
+ } ''
+ PKCS#12 decryption passphrase for a container in the
+ pkcs12 folder.
+ '';
+
+ token = mkPrefixedAttrsOfParams {
+ handle = mkOptionalHexParam ''
+ Hex-encoded CKA_ID or handle of the private key on the token or TPM,
+ respectively.
+ '';
+
+ slot = mkOptionalIntParam ''
+ Optional slot number to access the token.
+ '';
+
+ module = mkOptionalStrParam ''
+ Optional PKCS#11 module name to access the token.
+ '';
+
+ pin = mkOptionalStrParam ''
+ Optional PIN required to access the key on the token. If none is
+ provided the user is prompted during an interactive
+ --load-creds call.
+ '';
+ } ''Definition for a private key that's stored on a token/smartcard/TPM.'';
+
+ };
+
+ pools = mkAttrsOfParams {
+ addrs = mkOptionalStrParam ''
+ Subnet or range defining addresses allocated in pool. Accepts a single
+ CIDR subnet defining the pool to allocate addresses from or an address
+ range (<from>-<to>). Pools must be unique and non-overlapping.
+ '';
+
+ dns = mkCommaSepListParam [] "Address or CIDR subnets";
+ nbns = mkCommaSepListParam [] "Address or CIDR subnets";
+ dhcp = mkCommaSepListParam [] "Address or CIDR subnets";
+ netmask = mkCommaSepListParam [] "Address or CIDR subnets";
+ server = mkCommaSepListParam [] "Address or CIDR subnets";
+ subnet = mkCommaSepListParam [] "Address or CIDR subnets";
+ split_include = mkCommaSepListParam [] "Address or CIDR subnets";
+ split_exclude = mkCommaSepListParam [] "Address or CIDR subnets";
+ } ''
+ Section defining named pools. Named pools may be referenced by connections
+ with the pools option to assign virtual IPs and other configuration
+ attributes. Each pool must have a unique name (denoted <name> below).
+ '';
+}
diff --git a/nixos/release.nix b/nixos/release.nix
index 23f050367d6..c3a3fa34338 100644
--- a/nixos/release.nix
+++ b/nixos/release.nix
@@ -352,6 +352,7 @@ in rec {
tests.smokeping = callTest tests/smokeping.nix {};
tests.snapper = callTest tests/snapper.nix {};
tests.statsd = callTest tests/statsd.nix {};
+ tests.strongswan-swanctl = callTest tests/strongswan-swanctl.nix {};
tests.sudo = callTest tests/sudo.nix {};
tests.switchTest = callTest tests/switch-test.nix {};
tests.taskserver = callTest tests/taskserver.nix {};
diff --git a/nixos/tests/strongswan-swanctl.nix b/nixos/tests/strongswan-swanctl.nix
new file mode 100644
index 00000000000..14be2b9f220
--- /dev/null
+++ b/nixos/tests/strongswan-swanctl.nix
@@ -0,0 +1,154 @@
+# This strongswan-swanctl test is based on:
+# https://www.strongswan.org/testing/testresults/swanctl/rw-psk-ipv4/index.html
+# https://github.com/strongswan/strongswan/tree/master/testing/tests/swanctl/rw-psk-ipv4
+#
+# The roadwarrior carol sets up a connection to gateway moon. The authentication
+# is based on pre-shared keys and IPv4 addresses. Upon the successful
+# establishment of the IPsec tunnels, the specified updown script automatically
+# inserts iptables-based firewall rules that let pass the tunneled traffic. In
+# order to test both tunnel and firewall, carol pings the client alice behind
+# the gateway moon.
+#
+# alice moon carol
+# eth1------vlan_0------eth1 eth2------vlan_1------eth1
+# 192.168.0.1 192.168.0.3 192.168.1.3 192.168.1.2
+#
+# See the NixOS manual for how to run this test:
+# https://nixos.org/nixos/manual/index.html#sec-running-nixos-tests-interactively
+
+import ./make-test.nix ({ pkgs, ...} :
+
+let
+ ifAddr = node: iface: (pkgs.lib.head node.config.networking.interfaces.${iface}.ip4).address;
+
+ allowESP = "iptables --insert INPUT --protocol ESP --jump ACCEPT";
+
+ # Shared VPN settings:
+ vlan0 = "192.168.0.0/24";
+ version = 2;
+ secret = "0sFpZAZqEN6Ti9sqt4ZP5EWcqx";
+ esp_proposals = [ "aes128gcm128-x25519" ];
+ proposals = [ "aes128-sha256-x25519" ];
+in {
+ name = "strongswan-swanctl";
+ meta.maintainers = with pkgs.stdenv.lib.maintainers; [ basvandijk ];
+ nodes = {
+
+ alice = { nodes, ... } : {
+ virtualisation.vlans = [ 0 ];
+ networking = {
+ dhcpcd.enable = false;
+ defaultGateway = ifAddr nodes.moon "eth1";
+ };
+ };
+
+ moon = {pkgs, config, nodes, ...} :
+ let
+ carolIp = ifAddr nodes.carol "eth1";
+ moonIp = ifAddr nodes.moon "eth2";
+ strongswan = config.services.strongswan-swanctl.package;
+ in {
+ virtualisation.vlans = [ 0 1 ];
+ networking = {
+ dhcpcd.enable = false;
+ firewall = {
+ allowedUDPPorts = [ 4500 500 ];
+ extraCommands = allowESP;
+ };
+ nat = {
+ enable = true;
+ internalIPs = [ vlan0 ];
+ internalInterfaces = [ "eth1" ];
+ externalIP = moonIp;
+ externalInterface = "eth2";
+ };
+ };
+ environment.systemPackages = [ strongswan ];
+ services.strongswan-swanctl = {
+ enable = true;
+ swanctl = {
+ connections = {
+ "rw" = {
+ local_addrs = [ moonIp ];
+ local."main" = {
+ auth = "psk";
+ };
+ remote."main" = {
+ auth = "psk";
+ };
+ children = {
+ "net" = {
+ local_ts = [ vlan0 ];
+ updown = "${strongswan}/libexec/ipsec/_updown iptables";
+ inherit esp_proposals;
+ };
+ };
+ inherit version;
+ inherit proposals;
+ };
+ };
+ secrets = {
+ ike."carol" = {
+ id."main" = carolIp;
+ inherit secret;
+ };
+ };
+ };
+ };
+ };
+
+ carol = {pkgs, config, nodes, ...} :
+ let
+ carolIp = ifAddr nodes.carol "eth1";
+ moonIp = ifAddr nodes.moon "eth2";
+ strongswan = config.services.strongswan-swanctl.package;
+ in {
+ virtualisation.vlans = [ 1 ];
+ networking = {
+ dhcpcd.enable = false;
+ firewall.extraCommands = allowESP;
+ };
+ environment.systemPackages = [ strongswan ];
+ services.strongswan-swanctl = {
+ enable = true;
+ swanctl = {
+ connections = {
+ "home" = {
+ local_addrs = [ carolIp ];
+ remote_addrs = [ moonIp ];
+ local."main" = {
+ auth = "psk";
+ id = carolIp;
+ };
+ remote."main" = {
+ auth = "psk";
+ id = moonIp;
+ };
+ children = {
+ "home" = {
+ remote_ts = [ vlan0 ];
+ start_action = "trap";
+ updown = "${strongswan}/libexec/ipsec/_updown iptables";
+ inherit esp_proposals;
+ };
+ };
+ inherit version;
+ inherit proposals;
+ };
+ };
+ secrets = {
+ ike."moon" = {
+ id."main" = moonIp;
+ inherit secret;
+ };
+ };
+ };
+ };
+ };
+
+ };
+ testScript = ''
+ startAll();
+ $carol->waitUntilSucceeds("ping -c 1 alice");
+ '';
+})