[PATCH] strongswan: provide a service definition and configuration interface.

  • Done
  • quality assurance status badge
Details
2 participants
  • Domagoj Stolfa
  • Tobias Geerinckx-Rice
Owner
unassigned
Submitted by
Domagoj Stolfa
Severity
normal
D
D
Domagoj Stolfa wrote on 3 Jun 2021 00:11
(address . guix-patches@gnu.org)
YLgB91U8SgsJxdCe@pepehands
Attachment: file
-----BEGIN PGP SIGNATURE-----

iQIzBAEBCAAdFiEE7JyU1wrLyiw5G92zcc2InUujXj0FAmC4AfcACgkQcc2InUuj
Xj0pyQ//VdkTDnZf33xXTTFEiehsBHZkz/jDa/X+DHPnMwUUJEvsI4hoTU+ialNL
ytg6hwfphbcremuh2c3QiYbpxAEl0n3Uep/YTz22+CZ8X/lSnHzrsBQaS2JWMgVT
sThwWdjW47RIVYH6VC3kF8zkTPvjkGEDm5wzvEQqo/du5Dp43HClHhEZ4Gc8zTDr
gI06/JVdhttb+VNgi3GccAtADEGGOcAR9I4Wd9nNK4utZjNNonmHUWc8l5h/p3ZQ
BcD0XRRF86bycVEl1SGuQr9BgOaIepiTr6jcE57nYjZetW2XuZ8sTVxGIRHEUvCt
9cv4ON7DF9hmBGiBU2h2jodGParcTPWf6lxqevG771RjBWaYq28md6umSyKKLeeg
uAIbbgRuR0f8NCRXdx5Whjh8XtoUligkf3BzyUbH0ev60/pHaQtsY4Nm2PCPz/Mp
QJk6Y8zl0LXlLl/ogDRhMFodzFNLFVBXsV7xCtLWuIp8HqOQxrBRSi1Xa0GlbkiV
qMS3FSR3dR3Tykq8GTRMdlTFckgHPo4b8iKkigWXV9+RXf2Dbeuf48wlpV+cb/tu
qjE3Z7mO0sl3ZDrmzV5HTavx/XIeaaS/HwVAHAkfURVKX9vHYe9G6tFHnsgvdLSz
1NEQImJ7wcqlFx/9dKNbXIq6eVbDbgTaTuDBYBQiSGJB2tp57vY=
=e1Hs
-----END PGP SIGNATURE-----


T
T
Tobias Geerinckx-Rice wrote on 13 Jun 2021 14:41
(name . Domagoj Stolfa)(address . ds815@gmx.com)
87r1h6x7hf.fsf@nckx
Domagoj,

Domagoj Stolfa ???
Toggle quote (4 lines)
> This commit adds a strongswan-service-type which allows the user
> to
> start strongswan correctly on Guix.

Thank you!

Toggle quote (4 lines)
> Because ipsec.conf depends on indentation and is a deprecated
> intreface,
> we do not provide an EDSL to configure it,

OK.

Toggle quote (3 lines)
> and we do not put the config
> file in a Guile string (to avoid indentation issues).

Not using a string is fine by me, but I don't understand this
particular argument for it.

Toggle quote (6 lines)
> Similarly,
> ipsec.secrets contains the users authentication token/passwords,
> and is
> for security reasons transmitted separately from the
> configuration file.

OK, good to make it hard to inadvertently intern into the store.

Toggle quote (6 lines)
> (service strongswan-service-type
> (strongswan-configuration
> (use-ipsec? #t)
> (ipsec-conf "/config-files/ipsec.conf")
> (ipsec-secrets "/config-files/ipsec.secrets")))

(I)IRC you told me that the majority of users simply point
StrongSwan to a .conf/.secrets file they got from on high, and
this is all they'll ever need to do so. Sounds good to me.

This is a bit straightforward (no ‘local-file’, ‘plain-file’, …)
but there's precedent for that:

(service nginx-service-type
(nginx-configuration
(file "/etc/guix/nginx/nginx.conf")))

What does the daemon do now when USE-IPSEC? is #f? Anything
useful?

Could we drop USE-IPSEC? and allow IPSEC-CONF/IPSEC-SECRETS to be
#f to signal the same thing (enforcing only sane combinations)?
Or would that make things more confusing?

Is all this legacy enough to mark as such in the field name
(LEGACY-IPSEC-CONF, etc.) or is it one of those things that will
never ever go away and VPN providers will still hand out
ipsecs.conf in 2038?

Toggle quote (92 lines)
> This will start the charon daemon and allow them to connect to
> their
> VPNs configured in `/config-files/ipsec.conf`.
> ---
> gnu/services/vpn.scm | 128
> +++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 128 insertions(+)
>
> diff --git a/gnu/services/vpn.scm b/gnu/services/vpn.scm
> index 2bcbf76727..e026f2aa58 100644
> --- a/gnu/services/vpn.scm
> +++ b/gnu/services/vpn.scm
> @@ -4,6 +4,7 @@
> ;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com>
> ;;; Copyright © 2021 Guillaume Le Vaillant <glv@posteo.net>
> ;;; Copyright © 2021 Solene Rapenne <solene@perso.pw>
> +;;; Copyright © 2021 Domagoj Stolfa <ds815@gmx.com>
> ;;;
> ;;; This file is part of GNU Guix.
> ;;;
> @@ -26,6 +27,7 @@
> #:use-module (gnu services shepherd)
> #:use-module (gnu system shadow)
> #:use-module (gnu packages admin)
> + #:use-module (gnu packages networking)
> #:use-module (gnu packages vpn)
> #:use-module (guix packages)
> #:use-module (guix records)
> @@ -44,6 +46,9 @@
> generate-openvpn-client-documentation
> generate-openvpn-server-documentation
>
> + strongswan-configuration
> + strongswan-service-type
> +
> wireguard-peer
> wireguard-peer?
> wireguard-peer-name
> @@ -529,6 +534,129 @@ is truncated and rewritten every minute.")
> (openvpn-remote-configuration
> ,openvpn-remote-configuration-fields))
> 'openvpn-client-configuration))
>
> +;;;
> +;;; Strongswan.
> +;;;
> +
> +(define-record-type* <strongswan-configuration>
> + strongswan-configuration make-strongswan-configuration
> + strongswan-configuration?
> + (strongswan strongswan-configuration-strongswan
> ;<package>
> + (default strongswan))
> + (use-ipsec? strongswan-configuration-use-ipsec? ;legacy
> interface
> + (default #f))
> + (ipsec-conf strongswan-configuration-ipsec-conf)
> + (ipsec-secrets strongswan-configuration-ipsec-secrets))
> +
> +;; In the future, it might be worth implementing a record type
> to configure
> +;; all of the plugins, but for *most* basic usecases, simply
> creating the
> +;; files will be sufficient. Same is true of charon-plugins.
> +(define strongswand-config-files
> + (list "charon" "charon-logging" "pki" "pool" "scepclient"
> + "swanctl" "tnc"))
> +
> +;; Plugins to load.
> +(define charon-plugins
> + (list "aes" "aesni" "attr" "attr-sql" "chapoly" "cmac"
> "constraints"
> + "counters" "curl" "curve25519" "dhcp" "dnskey" "drbg"
> "eap-aka-3gpp"
> + "eap-aka" "eap-dynamic" "eap-identity" "eap-md5"
> "eap-mschapv2"
> + "eap-peap" "eap-radius" "eap-simaka-pseudonym"
> "eap-simaka-reauth"
> + "eap-simaka-sql" "eap-sim" "eap-sim-file" "eap-tls"
> "eap-tnc"
> + "eap-ttls" "ext-auth" "farp" "fips-prf" "gmp" "ha"
> "hmac"
> + "kernel-netlink" "led" "md4" "md5" "mgf1" "nonce"
> "openssl" "pem"
> + "pgp" "pkcs12" "pkcs1" "pkcs7" "pkcs8" "pubkey"
> "random" "rc2"
> + "resolve" "revocation" "sha1" "sha2" "socket-default"
> "soup" "sql"
> + "sqlite" "sshkey" "tnc-tnccs" "vici" "x509" "xauth-eap"
> "xauth-generic"
> + "xauth-noauth" "xauth-pam" "xcbc"))

Are these simply ‘all of the plug-ins’?

I'm fine with this ‘temporary’ solution as long as it's never
exported.

I'll trust you on all of this configuration syntax madness: :-)

Toggle quote (25 lines)
> +(define (strongswan-configuration-file config)
> + (match-record config <strongswan-configuration>
> + (strongswan use-ipsec? ipsec-conf ipsec-secrets)
> + (let* ((strongswan-dir
> + (computed-file
> + "strongswan.d"
> + #~(begin
> + (mkdir #$output)
> + ;; Create all of the configuration files in
> strongswan.d/*.conf
> + (map (lambda (conf-file)
> + (let* ((filename (string-append
> + #$output "/"
> + conf-file ".conf")))
> + (call-with-output-file filename
> + (lambda (port)
> + (display
> + "# Created by
> 'strongswan-service'\n"
> + port)))))
> + (list #$@strongswand-config-files))
> + (mkdir (string-append #$output "/charon"))
> + ;; And all of the strongswan.d/charon/*.conf
> files (plugins)

Nitpick: ;;-comments are full sentences ending in a full stop.

Toggle quote (32 lines)
> + (map (lambda (plugin)
> + (let* ((filename (string-append
> + #$output "/charon/"
> + plugin ".conf")))
> + (call-with-output-file filename
> + (lambda (port)
> + (format port "~a {
> + load = yes
> +}"
> + plugin)))))
> + (list #$@charon-plugins))))))
> + ;; Generate our strongswan.conf to reflect the user
> configuration.
> + (computed-file
> + "strongswan.conf"
> + #~(begin
> + (call-with-output-file #$output
> + (lambda (port)
> + (display "# Generated by
> 'strongswan-service'.\n" port)
> + (format port "charon {
> + load_modular = yes
> + plugins {
> + include ~a/charon/*.conf"
> + #$strongswan-dir)
> + (if #$use-ipsec?
> + (format port "
> + stroke {
> + load = yes
> + secrets_file = ~a
> + }

All this indentation is doing my head in, but it looks like here…

Toggle quote (17 lines)
> + }
> +}
> +
> +starter {
> + config_file = ~a
> +}
> +
> +include ~a/*.conf"
> + #$ipsec-secrets
> + #$ipsec-conf
> + #$strongswan-dir)
> + (format port "
> + }
> +}
> +include ~a/*.conf"
> + #$strongswan-dir)))))))))

…you had to choose between two ifs and two #$strongswan-dirs, and
chose two #$strongswan-dirs? I prefer two ifs.

Toggle quote (8 lines)
> +(define (strongswan-shepherd-service config)
> + (let* ((ipsec (file-append strongswan "/sbin/ipsec"))
> + (strongswan-conf-path (strongswan-configuration-file
> config)))
> + (list (shepherd-service
> + (requirement '(networking))
> + (provision '(strongswan))

I guess. I have no idea how ‘generic’ StrongSwan is and whether
this makes more sense than (provision '(ipsec)) or not.

Toggle quote (10 lines)
> + (start #~(make-forkexec-constructor
> + (list #$ipsec "start" "--nofork")
> + #:environment-variables
> + (list (string-append "STRONGSWAN_CONF="
> +
> #$strongswan-conf-path))))
> + (stop #~(make-kill-destructor))
> + (documentation "Start the charon daemon for IPsec
> VPN")))))

"StrongSwan's charon IKE keying daemon for IPsec VPN."

Most of ‘Run the …’/‘Start the …’ noise that has snuck into
gnu/services should probably be removed.

Toggle quote (11 lines)
> +(define strongswan-service-type
> + (service-type
> + (name 'strongswan)
> + (extensions
> + (list (service-extension shepherd-root-service-type
> + strongswan-shepherd-service)))))
> +
> ;;;
> ;;; Wireguard.
> ;;;

For this to be merged, we're still missing some documentation in
doc/guix.text. Would you be willing to write some?

Kind regards,

T G-R
-----BEGIN PGP SIGNATURE-----

iIMEARYKACsWIQT12iAyS4c9C3o4dnINsP+IT1VteQUCYMX83A0cbWVAdG9iaWFz
LmdyAAoJEA2w/4hPVW15tw0BAJxhD1hMnjz2I+UlsZJ5Lwsv0GXqbgEBHceH/yvl
2c3zAP9IhfsKMTTD5+O8hB1FLWru2BPF+suePUWUtC0LBGVcAQ==
=YLDL
-----END PGP SIGNATURE-----

T
T
Tobias Geerinckx-Rice wrote on 13 Jun 2021 14:45
(name . Domagoj Stolfa)(address . ds815@gmx.com)
87o8cax79z.fsf@nckx
Forgot to add: please include a GNU/Guix-style commit message
like:

gnu: Add strongswan service.

* gnu/services/vpn.scm (strongswan-configuration): New record
type.
(charon-plugins, strongswan-configuration-file)
(strongswan-shepherd-service, strongswan-service-type): New
variables.
* doc/guix.tex (VPN Services): Document them all!

Kind regards,

T G-R
-----BEGIN PGP SIGNATURE-----

iIMEARYKACsWIQT12iAyS4c9C3o4dnINsP+IT1VteQUCYMX96A0cbWVAdG9iaWFz
LmdyAAoJEA2w/4hPVW15P+EBAK+mofMs5eQ9pEmLC2N+w/CPsT4tOrM5Zdt2wckz
xAitAP4urTNYDuR48Ka44TojuysZoRGXAu/4dgB7LCBtw1QFAQ==
=3GM4
-----END PGP SIGNATURE-----

D
D
Domagoj Stolfa wrote on 13 Jun 2021 15:04
(name . Tobias Geerinckx-Rice)(address . me@tobias.gr)
YMYCQGd9afRr/IrD@parenthesis
Tobias,
Toggle quote (6 lines)
> > and we do not put the config
> > file in a Guile string (to avoid indentation issues).
>
> Not using a string is fine by me, but I don't understand this particular
> argument for it.

ipsec.conf is pythonistic in the sense that it's sensitive to
indentation. This is just to avoid copy-paste errors in a config file
that results in cryptic error messages because the user missed a space
while copy-pasting something. It's easier to just transmit the file as
given by the "higher-ups" out of bounds than have it as a configuration
string, as ipsec.secrets kind of has to be transmitted that way anyway.

Toggle quote (2 lines)
> What does the daemon do now when USE-IPSEC? is #f? Anything useful?

It doesn't do anything other than use the default configuration that is
provided by strongswan as it is shipped (basically, whatever is in the
build directory by default). This is what it has done up until this
point already, the user would have start strongswan by setting an
environment variable to some local `strongswan.conf`. It is also what
strongswan does on a fresh installation in any other distribution I've
tried it on.

Toggle quote (4 lines)
> Could we drop USE-IPSEC? and allow IPSEC-CONF/IPSEC-SECRETS to be #f to
> signal the same thing (enforcing only sane combinations)? Or would that make
> things more confusing?

We could, the plan I had for `strongswan` as a service is to support
both ipsec.conf/ipsec.secrets and swanctl, hence the `use-ipsec?` as a
separate thing. I can refactor it without that flag and have no real
strong opinion on it.

Toggle quote (4 lines)
> Is all this legacy enough to mark as such in the field name
> (LEGACY-IPSEC-CONF, etc.) or is it one of those things that will never ever
> go away and VPN providers will still hand out ipsecs.conf in 2038?

Unclear at this point, I don't see how strongswan could drop support for
ipsec.conf and ipsec.secrets without making a lot of users angry at this
point. The VPN that I'm using is configured and documented by people who
are quite familiar with strongswan, and even there the documentation is
referring to ipsec.conf and ipsec.secrets rather than swanctl at the
moment.

Toggle quote (2 lines)
> Nitpick: ;;-comments are full sentences ending in a full stop.

ACK. Will fix.

Toggle quote (3 lines)
> …you had to choose between two ifs and two #$strongswan-dirs, and chose two
> #$strongswan-dirs? I prefer two ifs.

I think the reasoning for this was that if we're not using
ipsec.conf/ipsec.secrets, we would be writing swanctl-specific
configuration. Right now, that is just including strongswan.d, but it
might do other things, so I've kept it in a more traditional if-else
format.

Toggle quote (3 lines)
> I guess. I have no idea how ‘generic’ StrongSwan is and whether this makes
> more sense than (provision '(ipsec)) or not.

That's a good question. I think it could probably provision ipsec, but I
haven't really verified it so I didn't want to risk doing that. I assume
that it can, though.

Toggle quote (2 lines)
> "StrongSwan's charon IKE keying daemon for IPsec VPN."

ACK.

Toggle quote (3 lines)
> For this to be merged, we're still missing some documentation in
> doc/guix.text. Would you be willing to write some?

Will include the docs with the next patch.

Thanks for the detailed feedback!

--
Domagoj
-----BEGIN PGP SIGNATURE-----

iQIzBAEBCAAdFiEE7JyU1wrLyiw5G92zcc2InUujXj0FAmDGAkAACgkQcc2InUuj
Xj05XQ//fGwngakdWwDkRacDQJWH4o084wb3aRU5QrQl2AfTol1tbokhPSkPEE47
ndkHbDJzgP4U/WQGy6l/CLu8W77IG385MvLiAv7Od99gTlYCzGrwbaAyogl3FMtq
uhmgtaGvmJaldZkZnjRhta1S5yvjxe6WrHPI9iVcuoD7BxSLgRFy+MjQP5mBTvF7
7wgPmFqBCTG+w4dSGlR665hPdVfJK9GTW5ajNaP34eFHZOCmoHahFiKdDsHhbQzU
17EU1JgVIZeMXIIPXQtwrz5knh6Uu1Ft2DIA3VNNbwsmdSdSE4Ww7cotZURNGFM7
FJn6h993KuSL3T2j3XhwnCzXBUEkQXXkmW/Qn9EAzokAzd+MaEca/9FeIUThk8ly
AJIoG8gMObCd/XTLz0Ck6NGqr8QPVs3sXl//l4nSzCgYInD6t0Jq6b48sQMwTK31
tRK/UD/O6z/CoB81g7vwN1JR3lm2WpblSNKhPZYD2FJzyKrp1v+d6ZHi05t17Vz9
hMoYZU5z32oA4zGUSpFriV9RWhu2TK6PdpOVW10eBdJd3xuSM5kwRcSNznMgflrR
kzahaTmDRcB9ycT+/IdzAyZS7TSMMx0kudxK6x1Soa7PMa+w1+QgrHKWFDdH9H1N
XCPMg6jARq9CDp5FUhVzjmiUl4MhbyNA3lz021hpNmz0QLjf8J4=
=kZ1X
-----END PGP SIGNATURE-----


D
D
Domagoj Stolfa wrote on 13 Jun 2021 17:08
[PATCH] gnu: Add strongswan service.
(address . 48803@debbugs.gnu.org)
YMYfhbU2sYobdunV@parenthesis
Attachment: file
-----BEGIN PGP SIGNATURE-----

iQIzBAEBCAAdFiEE7JyU1wrLyiw5G92zcc2InUujXj0FAmDGH4UACgkQcc2InUuj
Xj2hsg//U0lCy6zIFG+NOg1SZW9eoHKjwFfLb1Bq7xrf2VmgKNfbswboYwsN7Hgy
tdSq4UDqqYbzqwS5B4bzEaNAptM2vFqEqpJsdPG+s99D7SQdfJSkLZsO2kodwNLZ
llkcVaZPS2CRnXVd9fl5DqhJax5k9aJhfnPGitaR1Vw0aHGNQw1H8pXqM0TD+rL/
JvNpFXR8m84dc4rCxozDwsri7ciF8HszWntrFeF9ERPfRZKZt5Iwp1E2voQ+eGBV
4tT4ph9WJTo0XTeOGDJQfGaYu7wbkQItAlT1o3bEtCv2Hb/MamJlJL6x5ZmV0PCd
hXRMHG9jTnL3JsLPbCN3TJUGOYXc9OzzC60oheHCf3H4um/4b2VC1cvRaoG/+Msv
anuZS+yogbpfqU1oF1J/2IxqDTBxuNdrtFjO6/M2z09TIPVBItuUke0OhPosKWvA
2p6ZpSLqgJHdf0GDg2vTWM+FKNvjIXizhXGFAgGmGxddaqsjSi1hY62cHyuLymAu
/MnnSzg1JhuIav6YBZ21SiqOptKiD09iw4MojbQZjv8GDCiuiBNQkz4vuUdRfs0s
TbZEhPj4IZv9K63fux/W5c2XaIxyvKK6IjXhon03OQ2vyHW23PloIUZrZ5y1E9Y8
1jr2lXOUYVKtvJs9Vp3mTSoUyp05M0HxWXWVoxqusfdTDTLjers=
=hO9G
-----END PGP SIGNATURE-----


T
T
Tobias Geerinckx-Rice wrote on 25 Jun 2021 01:17
(name . Domagoj Stolfa)(address . ds815@gmx.com)
87r1gqsvhk.fsf@nckx
Domagoj!

This is finally on master with the following changes:

Domagoj Stolfa ???
Toggle quote (6 lines)
> * gnu/services/vpn.scm (strongswan-configuration): New record
> type.
> (charon-plugins, strongswan-configuration-file)
> (strongswan-shepherd-service, strongswan-service-type): New
> variables.

I don't know where this extra spacing came from but removed it.

Toggle quote (2 lines)
> +@subheading StrongSwan

I'm sure some style guides disapprove, but I changed all usage of
‘StrongSwan’ to upstream's ‘strongSwan’.

Toggle quote (4 lines)
> +Currently, the StrongSwan service only provides legacy-style
> configuration with
> +ipsec.conf and ipsec.secrets files.

We have cool @file{} mark up so I used it.

Toggle quote (3 lines)
> +@defvr {Scheme Variable} strongswan-service-type
> +A service type for StrongSwan configuration.

Added a very brief ‘IPsec VPN’ context.

Toggle quote (6 lines)
> +@lisp
> +(service strongswan-service-type
> + (strongswan-configuration
> + (ipsec-conf "/etc/ipsec.conf")
> + (ipsec-secrets "/etc/ipsec.secrets")))

Fixed the indentation.

Toggle quote (5 lines)
> +@item @code{ipsec-conf} (default: @code{#f})
> +The path to an ipsec.conf file. If set to @code{#f},
> @code{ipsec-secrets} will
> +also be ignored.

Reworded this to match the exception I added below. Added moar
@file{}.

Toggle quote (2 lines)
> @c %end of automatic openvpn-server documentation

This indicates that the author of the previous OpenVPN section
automated the docs somehow. I moved it back.

Toggle quote (11 lines)
> @subsubheading Wireguard
> diff --git a/gnu/services/vpn.scm b/gnu/services/vpn.scm
> index 2bcbf76727..691cc3c05a 100644
> --- a/gnu/services/vpn.scm
> +++ b/gnu/services/vpn.scm
> @@ -26,6 +26,7 @@
> #:use-module (gnu services shepherd)
> #:use-module (gnu system shadow)
> #:use-module (gnu packages admin)
> + #:use-module (gnu packages networking)

Oops, noticed this only now… I don't think it's needed anymore.
Can you confirm?

‘guix system’ & friends will now throw an inelegant error if
ipsec-conf & ipsec-secrets are incongruent. I couldn't get
meaningful location data out of CONFIG. This does the job:

+ (throw 'error
+ (G_ "strongSwan ipsec-conf and ipsec-secrets must
\
+both be (un)set")))))

Toggle quote (7 lines)
> +(define strongswan-service-type
> + (service-type
> + (name 'strongswan)
> + (extensions
> + (list (service-extension shepherd-root-service-type
> + strongswan-shepherd-service)))))

I added a default-value so people can simply write

(service strongswan-service-type)

and a short description.

Thank you very much!

T G-R
-----BEGIN PGP SIGNATURE-----

iIMEARYKACsWIQT12iAyS4c9C3o4dnINsP+IT1VteQUCYNUSlw0cbWVAdG9iaWFz
LmdyAAoJEA2w/4hPVW15fYsBANgZkj+O/7JhdlZQgQTOsxkiMG9PfVWWTMD0xBS2
cXAuAQDtw5b9UqPSdJjvu1+M1RDO1mEY3nzK+YGHkkjFyDcPCw==
=2rHS
-----END PGP SIGNATURE-----

?