Subject: Re: [bug#70314] [PATCH] guix: scripts: environment: add tls certs to networked containers

From: Richard Sent <[email-masked]>
Date: Wed, 04 Sep 2024 11:01:53 -0400

Hi Ludo!

Thanks for the response!

Ludovic Courtès <[email-masked]> writes:

> Instead of adding the ‘nss-certs’ package, I would rather expose
> /etc/ssl/certs (when it exists), for two reasons: (1) the system-chosen
> certificates will be used, and (2) it’s less expensive than having to
> compute the derivation of ‘nss-certs’.

There is an issue with this that's cropped up in the past. The files in
/etc/ssl/certs/* are symlinks to store items. Because containers only
see a subset of store items that are in that container's profile, it
often sees the symlinks to store items but not the target file.

For example:

--8<---------------cut here---------------start------------->8---
$ guix shell -C bash coreutils --expose=/etc/ssl/certs -- bash
[env]$ ls /etc/ssl/certs/ca*
/etc/ssl/certs/ca-certificates.crt  /etc/ssl/certs/ca6e4ad9.0
[env]$ cat /etc/ssl/certs/ca-certificates.crt
cat: /etc/ssl/certs/ca-certificates.crt: No such file or directory
[env]$ ls -l /etc/ssl/certs/ca6e4ad9.0
lrwxrwxrwx 1 65534 overflow 85 Jan  1  1970 /etc/ssl/certs/ca6e4ad9.0 -> /gnu/store/5y39gqnvlfrw9gxyxbqqkdr8cxgp1fa1-nss-certs-3.88.1/etc/ssl/certs/ca6e4ad9.0
[env]$ cat /etc/ssl/certs/ca6e4ad9.0  
cat: /etc/ssl/certs/ca6e4ad9.0: No such file or directory
--8<---------------cut here---------------end--------------->8---

We can /sort of/ solve this by adding nss-certs to the container, but
only when the nss-certs being added has the same hash as the nss-certs
package.

--8<---------------cut here---------------start------------->8---
# nss-certs w/o version adds v3.99 to the profile, which doesn't match
# the system. Ergo it's still unavailable.
~ $ guix shell -C bash coreutils --expose=/etc/ssl/certs -- bash -c 'cat /etc/ssl/certs/ca6e4ad9.0'
cat: /etc/ssl/certs/ca6e4ad9.0: No such file or directory
# 
# If we specify 3.88.1, it does work, but only for various nss-certificates,
# not the ca-certificates.crt bundle file (which isn't a package).
guix shell -C bash coreutils [email-masked] --expose=/etc/ssl/certs -- bash -c 'cat /etc/ssl/certs/ca6e4ad9.0'
# snip, contents of ca6e4ad9.0
# 
~ $ guix shell -C bash coreutils [email-masked] --expose=/etc/ssl/certs -- bash -c 'cat /etc/ssl/certs/ca-certificates.crt'
cat: /etc/ssl/certs/ca-certificates.crt: No such file or directory
--8<---------------cut here---------------end--------------->8---

This problem becomes impossible to solve in situations where the system
Guix and user Guix have different nss-certs hashes.

Be it by adding nss-certs to the container profile or by exposing
/etc/ssl/certs, we still need to calculate the nss-certs derivation.

(Perhaps a alternative solution is making sure symlink targets to store
items visible to a container are persisted. I don't know how complicated
that would be, but I imagine it's nontrivial.)

> Users who definitely want Guix’s ‘nss-certs’ can always add it to the
> shell and it will take precedence over /etc/ssl/certs, assuming
> SSL_CERT_{FILE,DIR} is defined.

True, although at present anyone who wants to use nss-certs must set
SSL_CERT_{FILE,DIR} manually (or coincidentally install a package that
registers the search path).

--8<---------------cut here---------------start------------->8---
# nss-certs alone doesn't set SSL_CERT_DIR
~ $ guix shell -C bash coreutils [email-masked] -- bash -c 'echo $SSL_CERT_DIR'
# blank
#
# curl registers $SSL_CERT_{FILE,DIR}
~ $ guix shell -C bash coreutils [email-masked] curl -- bash -c 'echo $SSL_CERT_DIR'
/gnu/store/hxylrsqs5cy87cgkxi5fmlzxvfhczlzj-profile/etc/ssl/certs
--8<---------------cut here---------------end--------------->8---

This is unintuitive. Many packages that make use of nss-certs don't
register the search path, e.g. rust-cargo [1]. I'd rather avoid a
solution that is "edit every package that may possibly use nss-certs now
and in the future to register the search path".

> WDYT?

My thoughts are if we have to decide between

1. Users who want TLS with standard public endpoints
2. Users who want TLS with custom private endpoints

it's better to prioritize a good experience for 1 and let 2 opt-out of
the "hand holding" defaults. But perhaps it's possible to make everyone
happy.

If desired this patch can be reworked as opt-in.

[1]: https://logs.guix.gnu.org/guix/2024-04-08.log

-- 
Take it easy,
Richard Sent
Making my computer weirder one commit at a time.