Some checks failed
Periodic Merges (6h) / master → staging-nixos (push) Failing after 12m50s
Periodic Merges (6h) / master → staging-next (push) Failing after 12m54s
Periodic Merges (24h) / merge-base(master,staging) → haskell-updates (push) Failing after 11m54s
Periodic Merges (6h) / staging-next → staging (push) Failing after 12m13s
Periodic Merges (24h) / staging-next-25.05 → staging-25.05 (push) Failing after 13m24s
Periodic Merges (24h) / release-25.05 → staging-next-25.05 (push) Failing after 14m28s
212 lines
5.1 KiB
Nix
212 lines
5.1 KiB
Nix
{
|
||
config,
|
||
lib,
|
||
pkgs,
|
||
...
|
||
}:
|
||
|
||
let
|
||
|
||
inherit (builtins) toFile;
|
||
inherit (lib)
|
||
concatMapStrings
|
||
concatStringsSep
|
||
mapAttrsToList
|
||
mkIf
|
||
mkEnableOption
|
||
mkOption
|
||
types
|
||
literalExpression
|
||
optionalString
|
||
;
|
||
|
||
cfg = config.services.strongswan;
|
||
|
||
ipsecSecrets = secrets: concatMapStrings (f: "include ${f}\n") secrets;
|
||
|
||
ipsecConf =
|
||
{
|
||
setup,
|
||
connections,
|
||
ca,
|
||
}:
|
||
let
|
||
# https://wiki.strongswan.org/projects/strongswan/wiki/IpsecConf
|
||
makeSections =
|
||
type: sections:
|
||
concatStringsSep "\n\n" (
|
||
mapAttrsToList (
|
||
sec: attrs:
|
||
"${type} ${sec}\n" + (concatStringsSep "\n" (mapAttrsToList (k: v: " ${k}=${v}") attrs))
|
||
) sections
|
||
);
|
||
setupConf = makeSections "config" { inherit setup; };
|
||
connectionsConf = makeSections "conn" connections;
|
||
caConf = makeSections "ca" ca;
|
||
|
||
in
|
||
builtins.toFile "ipsec.conf" ''
|
||
${setupConf}
|
||
${connectionsConf}
|
||
${caConf}
|
||
'';
|
||
|
||
strongswanConf =
|
||
{
|
||
setup,
|
||
connections,
|
||
ca,
|
||
secretsFile,
|
||
managePlugins,
|
||
enabledPlugins,
|
||
}:
|
||
toFile "strongswan.conf" ''
|
||
charon {
|
||
${optionalString managePlugins "load_modular = no"}
|
||
${optionalString managePlugins ("load = " + (concatStringsSep " " enabledPlugins))}
|
||
plugins {
|
||
stroke {
|
||
secrets_file = ${secretsFile}
|
||
}
|
||
}
|
||
}
|
||
|
||
starter {
|
||
config_file = ${ipsecConf { inherit setup connections ca; }}
|
||
}
|
||
'';
|
||
|
||
in
|
||
{
|
||
options.services.strongswan = {
|
||
enable = mkEnableOption "strongSwan";
|
||
|
||
secrets = mkOption {
|
||
type = types.listOf types.str;
|
||
default = [ ];
|
||
example = [ "/run/keys/ipsec-foo.secret" ];
|
||
description = ''
|
||
A list of paths to IPSec secret files. These
|
||
files will be included into the main ipsec.secrets file with
|
||
the `include` directive. It is safer if these
|
||
paths are absolute.
|
||
'';
|
||
};
|
||
|
||
setup = mkOption {
|
||
type = types.attrsOf types.str;
|
||
default = { };
|
||
example = {
|
||
cachecrls = "yes";
|
||
strictcrlpolicy = "yes";
|
||
};
|
||
description = ''
|
||
A set of options for the ‘config setup’ section of the
|
||
{file}`ipsec.conf` file. Defines general
|
||
configuration parameters.
|
||
'';
|
||
};
|
||
|
||
connections = mkOption {
|
||
type = types.attrsOf (types.attrsOf types.str);
|
||
default = { };
|
||
example = literalExpression ''
|
||
{
|
||
"%default" = {
|
||
keyexchange = "ikev2";
|
||
keyingtries = "1";
|
||
};
|
||
roadwarrior = {
|
||
auto = "add";
|
||
leftcert = "/run/keys/moonCert.pem";
|
||
leftid = "@moon.strongswan.org";
|
||
leftsubnet = "10.1.0.0/16";
|
||
right = "%any";
|
||
};
|
||
}
|
||
'';
|
||
description = ''
|
||
A set of connections and their options for the ‘conn xxx’
|
||
sections of the {file}`ipsec.conf` file.
|
||
'';
|
||
};
|
||
|
||
ca = mkOption {
|
||
type = types.attrsOf (types.attrsOf types.str);
|
||
default = { };
|
||
example = {
|
||
strongswan = {
|
||
auto = "add";
|
||
cacert = "/run/keys/strongswanCert.pem";
|
||
crluri = "http://crl2.strongswan.org/strongswan.crl";
|
||
};
|
||
};
|
||
description = ''
|
||
A set of CAs (certification authorities) and their options for
|
||
the ‘ca xxx’ sections of the {file}`ipsec.conf`
|
||
file.
|
||
'';
|
||
};
|
||
|
||
managePlugins = mkOption {
|
||
type = types.bool;
|
||
default = false;
|
||
description = ''
|
||
If set to true, this option will disable automatic plugin loading and
|
||
then tell strongSwan to enable the plugins specified in the
|
||
{option}`enabledPlugins` option.
|
||
'';
|
||
};
|
||
|
||
enabledPlugins = mkOption {
|
||
type = types.listOf types.str;
|
||
default = [ ];
|
||
description = ''
|
||
A list of additional plugins to enable if
|
||
{option}`managePlugins` is true.
|
||
'';
|
||
};
|
||
};
|
||
|
||
config =
|
||
with cfg;
|
||
mkIf enable {
|
||
|
||
# here we should use the default strongswan ipsec.secrets and
|
||
# append to it (default one is empty so not a pb for now)
|
||
environment.etc."ipsec.secrets".text = ipsecSecrets cfg.secrets;
|
||
|
||
systemd.services.strongswan = {
|
||
description = "strongSwan IPSec Service";
|
||
wantedBy = [ "multi-user.target" ];
|
||
path = with pkgs; [
|
||
kmod
|
||
iproute2
|
||
iptables
|
||
util-linux
|
||
]; # XXX Linux
|
||
wants = [ "network-online.target" ];
|
||
after = [ "network-online.target" ];
|
||
environment = {
|
||
STRONGSWAN_CONF = strongswanConf {
|
||
inherit
|
||
setup
|
||
connections
|
||
ca
|
||
managePlugins
|
||
enabledPlugins
|
||
;
|
||
secretsFile = "/etc/ipsec.secrets";
|
||
};
|
||
};
|
||
serviceConfig = {
|
||
ExecStart = "${pkgs.strongswan}/sbin/ipsec start --nofork";
|
||
};
|
||
preStart = ''
|
||
# with 'nopeerdns' setting, ppp writes into this folder
|
||
mkdir -m 700 -p /etc/ppp
|
||
'';
|
||
};
|
||
};
|
||
}
|