The strongswan-swanctl systemd service starts charon-systemd. This implements a IKE daemon very similar to charon, but it's specifically designed for use with systemd. It uses the systemd libraries for a native integration. Instead of using starter and an ipsec.conf based configuration, the daemon is directly managed by systemd and configured with the swanctl configuration backend. See: https://wiki.strongswan.org/projects/strongswan/wiki/Charon-systemd Note that the strongswan.conf and swantctl.conf configuration files are automatically generated based on NixOS options under services.strongswan-swanctl.strongswan and services.strongswan-swanctl.swanctl respectively.wip/yesman
parent
04dd1987a3
commit
bd24b3addd
@ -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"; |
||||
}; |
||||
}; |
||||
}; |
||||
} |
@ -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 + '' |
||||
</para><para> |
||||
StrongSwan default: <literal><![CDATA[${builtins.toJSON strongswanDefault}]]></literal> |
||||
''; |
||||
|
||||
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); |
||||
}; |
||||
|
||||
} |
@ -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; |
||||
|
||||
} |
@ -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 |
||||
<literal>/etc/ipsec.d/crls</literal> (stroke) or |
||||
<literal>/etc/swanctl/x509crl</literal> (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). |
||||
</para><para> |
||||
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 |
||||
<option>interfaces_use</option> 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). |
||||
</para><para> |
||||
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. <literal>NixOS</literal>). |
||||
''; |
||||
|
||||
os_info.version = mkOptionalStrParam '' |
||||
Manually set the version of the client OS (e.g. <literal>17.09</literal>). |
||||
''; |
||||
|
||||
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. |
||||
''; |
||||
}; |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -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. |
||||
''; |
||||
}; |
||||
} |
@ -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."; |
||||
} |
@ -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 "<default>" '' |
||||
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. |
||||
''; |
||||
}; |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -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"); |
||||
''; |
||||
}) |
Loading…
Reference in new issue