Nix SSL path set incorrectly in the daemon on macOS #226

Open
opened 2024-04-06 00:52:37 +00:00 by lunaphied · 1 comment
Owner

There's a bug in scripts/nix-profile-daemon.sh.in (and debatably all the other activation scripts) where on macOS, if you don't for some reason have system certificates in a path matching a Linux distribution (not a default configuration), it will try to find one in the default or user profile, which if you've accidentally misconfigured them without certificates, will then break, as there's no fallback for macOS.

It will then set the environment variable to a "random" broken path within the last profile

specifically, there's a state where it runs the /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh without having set NIX_SSL_CONF_FILE first, and that's not darwin'ized, so if your profiles get fucked, the fallback in here fails:

# Set $NIX_SSL_CERT_FILE so that Nixpkgs applications like curl work.
if [ -n "${NIX_SSL_CERT_FILE:-}" ]; then
    : # Allow users to override the NIX_SSL_CERT_FILE
elif [ -e /etc/ssl/certs/ca-certificates.crt ]; then # NixOS, Ubuntu, Debian, Gentoo, Arch
    export NIX_SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
elif [ -e /etc/ssl/ca-bundle.pem ]; then # openSUSE Tumbleweed
    export NIX_SSL_CERT_FILE=/etc/ssl/ca-bundle.pem
elif [ -e /etc/ssl/certs/ca-bundle.crt ]; then # Old NixOS
    export NIX_SSL_CERT_FILE=/etc/ssl/certs/ca-bundle.crt
elif [ -e /etc/pki/tls/certs/ca-bundle.crt ]; then # Fedora, CentOS
    export NIX_SSL_CERT_FILE=/etc/pki/tls/certs/ca-bundle.crt
else
  # Fall back to what is in the nix profiles, favouring whatever is defined last.
  check_nix_profiles() {
    if [ -n "$ZSH_VERSION" ]; then
      # Zsh by default doesn't split words in unquoted parameter expansion.
      # Set local_options for these options to be reverted at the end of the function
      # and shwordsplit to force splitting words in $NIX_PROFILES below.
      setopt local_options shwordsplit
    fi
    for i in $NIX_PROFILES; do
      if [ -e "$i/etc/ssl/certs/ca-bundle.crt" ]; then
        export NIX_SSL_CERT_FILE=$i/etc/ssl/certs/ca-bundle.crt
      fi
    done
  }
  check_nix_profiles
  unset -f check_nix_profiles
fi
There's a bug in `scripts/nix-profile-daemon.sh.in` (and debatably all the other activation scripts) where on macOS, if you don't for some reason have system certificates in a path matching a Linux distribution (not a default configuration), it will try to find one in the default or user profile, which if you've accidentally misconfigured them without certificates, will then break, as there's no fallback for macOS. It will then set the environment variable to a "random" broken path within the last profile > specifically, there's a state where it runs the `/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh` without having set `NIX_SSL_CONF_FILE` first, and that's not darwin'ized, so if your profiles get fucked, the fallback in here fails: ```bash # Set $NIX_SSL_CERT_FILE so that Nixpkgs applications like curl work. if [ -n "${NIX_SSL_CERT_FILE:-}" ]; then : # Allow users to override the NIX_SSL_CERT_FILE elif [ -e /etc/ssl/certs/ca-certificates.crt ]; then # NixOS, Ubuntu, Debian, Gentoo, Arch export NIX_SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt elif [ -e /etc/ssl/ca-bundle.pem ]; then # openSUSE Tumbleweed export NIX_SSL_CERT_FILE=/etc/ssl/ca-bundle.pem elif [ -e /etc/ssl/certs/ca-bundle.crt ]; then # Old NixOS export NIX_SSL_CERT_FILE=/etc/ssl/certs/ca-bundle.crt elif [ -e /etc/pki/tls/certs/ca-bundle.crt ]; then # Fedora, CentOS export NIX_SSL_CERT_FILE=/etc/pki/tls/certs/ca-bundle.crt else # Fall back to what is in the nix profiles, favouring whatever is defined last. check_nix_profiles() { if [ -n "$ZSH_VERSION" ]; then # Zsh by default doesn't split words in unquoted parameter expansion. # Set local_options for these options to be reverted at the end of the function # and shwordsplit to force splitting words in $NIX_PROFILES below. setopt local_options shwordsplit fi for i in $NIX_PROFILES; do if [ -e "$i/etc/ssl/certs/ca-bundle.crt" ]; then export NIX_SSL_CERT_FILE=$i/etc/ssl/certs/ca-bundle.crt fi done } check_nix_profiles unset -f check_nix_profiles fi ```
lunaphied added the
bug
label 2024-04-06 00:52:37 +00:00
lunaphied added the
E/easy
E/help wanted
labels 2024-04-06 00:55:59 +00:00
Author
Owner

This is worse than expected for extremely silly reasons.

It turns out that on macOS, the daemon itself never even actually sees /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh because that file is loaded by (amongst other places that are unused) /etc/bashrc. Nix's default daemon is launched via non-interactive, non-login /bin/sh which runs /bin/bash in compatibility mode on macOS.

This means that it will not even see /etc/profile in the first place. So we try running it as a login shell right? Well. Not quite enough either. That will process /etc/profile and it will recognize itself as running under bash with $BASH being set, and properly source /etc/bashrc, except, that won't even get to the line that loads the environment for the Lix daemon, because it starts by checking if there's a $PS1 set already as a proxy for "are we running interactively".

What a mess. Let's just manually include the proper sourcing of the environment...

This is worse than expected for extremely silly reasons. It turns out that on macOS, the daemon itself never even actually *sees* `/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh` because that file is loaded by (amongst other places that are unused) `/etc/bashrc`. Nix's default daemon is launched via non-interactive, non-login `/bin/sh` which runs `/bin/bash` in compatibility mode on macOS. This means that it will not even *see* `/etc/profile` in the first place. So we try running it as a login shell right? Well. Not quite enough either. That will process `/etc/profile` and it will recognize itself as running under bash with `$BASH` being set, and properly source `/etc/bashrc`, except, that won't even get to the line that loads the environment for the Lix daemon, because it starts by checking if there's a `$PS1` set already as a proxy for "are we running interactively". What a mess. Let's just manually include the proper sourcing of the environment...
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lix-project/lix#226
No description provided.