Skip to content

treewide: support NIX_SSL_CERT_FILE as an impureEnvVar#303307

Merged
lukegb merged 2 commits intoNixOS:stagingfrom
timbertson:https_proxy
Aug 23, 2024
Merged

treewide: support NIX_SSL_CERT_FILE as an impureEnvVar#303307
lukegb merged 2 commits intoNixOS:stagingfrom
timbertson:https_proxy

Conversation

@timbertson
Copy link
Contributor

(this is a reopened version of #271161 for technical reasons)

Description of changes

tl;dr this PR makes NIX_SSL_CERT_FILE the preferred way to control CA certificates throughout nix, by allowing it to be set as in impureEnvVar, including it in proxyImpureEnvVars, and ensuring fetchers support it.


Nix (the executable) as well as much of its packaged software respects NIX_SSL_CERT_FILE as the preferred way to specify a custom set of root certificates. Within derivations, this is typically done by the setup hook of cacert.

However, there's no way to inject this variable from outside (with impure env vars used in fetchers). This is required for most use cases of an an https proxy, as the proxy's own certificate will not likely be trusted by nix's builtin cacert package.

Functionality for injecting a custom trust store has been added to fetchgit, but because the setuphook will always override NIX_SSL_CERT_FILE, a different envvar had to be used (NIX_GIT_SSL_CAINFO). I have an open PR to add this same customisation to the go module fetcher.

However, it'd be preferable if we didn't invent a new envvar, and instead made NIX_SSL_CERT_FILE the single way to control this setting for both fetchers and nix itself.

For this to work, we need two small changes:

  • cacert should only set this variable if it's not already set, so that any impure version is not overwritten
    • this is in a setuphook so it's a mass rebuild
  • add "NIX_SSL_CERT_FILE" to proxyImpureEnvVars (fetcher.nix). It's not strictly a proxy-only variable, but:
    • this needs to be overridden for all HTTPS proxy use cases, and most things are https these days. Currently fetcher support for custom certs is patchy, because they're all doing their own thing (see below notes)
    • using the certificates the system has explicitly set for nix (if any) is inline with user expectations even outside proxy setups, and this only affects fixed-output derivations anyway

Various fetchers current (and updated) behaviour is oulined below:

  • fetchgit: previously added explicit support for NIX_GIT_SSL_CAINFO as the impure overrideable version. This is still supported, but the standard NIX_SSL_CERT_FILE now works and is preferred.
  • fetchurl: passes --insecure to curl for a fixed-output derivation, so I guess it doesn't need modification
  • fetchgomodule: previously no support for custom certs for git dependencies, now sets GIT_SSL_CAINFO to the value of NIX_SSL_CERT_FILE using whatever's provided by the user / setup hook

Looking through other fetchers, it seems most of them either have their own schemes or delegate to fetchurl. So this isn't a wide-reaching code change, but I think it's important to support NIX_SSL_CERT_FILE as an impureEnvVar, so that we don't force fetchers to invent their own envvars for this purpose.

Things done

Since this is a mass-rebuild, I tested locally by only applying these changes to the version of cacert used by fetchers. With these modifications I tested fetching over https (using custom certs) with:

  • fetchurl
  • fetchgit (over https)
  • go modules fetch (git https)
  • Built on platform(s)
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • For non-Linux: Is sandboxing enabled in nix.conf? (See Nix manual)
    • sandbox = relaxed
    • sandbox = true
  • Tested, as applicable:
  • Tested compilation of all packages that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage
  • Tested basic functionality of all binary files (usually in ./result/bin/)
  • 24.05 Release Notes (or backporting 23.05 and 23.11 Release notes)
    • (Package updates) Added a release notes entry if the change is major or breaking
    • (Module updates) Added a release notes entry if the change is significant
    • (Module addition) Added a release notes entry if adding a new NixOS module
  • Fits CONTRIBUTING.md.

@github-actions github-actions bot added 8.has: documentation This PR adds or changes documentation 6.topic: golang Go is a high-level general purpose programming language that is statically typed and compiled. 6.topic: fetch Fetchers (e.g. fetchgit, fetchsvn, ...) 6.topic: lib The Nixpkgs function library labels Apr 11, 2024
@timbertson
Copy link
Contributor Author

@roberth would you mind taking another look at this now that I've rebased?
(I had to close the old PR which you commented on previously, #271161 (comment))

@timbertson timbertson requested a review from vcunat April 11, 2024 08:29
@ofborg ofborg bot added 10.rebuild-darwin-stdenv This PR causes stdenv to rebuild on Darwin and must target a staging branch. 10.rebuild-darwin: 501+ This PR causes many rebuilds on Darwin and should normally target the staging branches. 10.rebuild-darwin: 5001+ This PR causes many rebuilds on Darwin and must target the staging branches. 10.rebuild-linux: 501+ This PR causes many rebuilds on Linux and should normally target the staging branches. 10.rebuild-linux: 5001+ This PR causes many rebuilds on Linux and must target the staging branches. labels Apr 11, 2024
@wegank wegank added the 2.status: merge conflict This PR has merge conflicts with the target branch label May 22, 2024
@timbertson
Copy link
Contributor Author

Suggestions applied and rebased, thanks for the review @3noch

@ofborg ofborg bot removed the 2.status: merge conflict This PR has merge conflicts with the target branch label Jun 27, 2024
This envvar is also added to lib.proxyImpureEnvVars since it's
typically required for https proxies.

This change also updates fetchgit and go module fetching to use this
envvar. NIX_GIT_SSL_CAINFO is still supported for backwards
compatibility in fetchgit.
@timbertson
Copy link
Contributor Author

Rebased again. I'd love to get this PR merged if anyone knows how to get any attention to it. It's been reviewed by a few people since I raised it nearly a year ago (as #271161), but I don't know who has authority to actually merge it. It is a bulk-rebuild, but it's also pretty small and should be a no-op in the typical case of "not using an HTTPS proxy".

@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/prs-ready-for-review/3032/4457

Copy link
Contributor

@lukegb lukegb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change seems reasonable - there's some potential for slightly wonky things happening inside a nix-shell, but I have no serious objection and I can't think of any particular circumstances in which that would make much of a difference.

@lukegb lukegb merged commit 54cb833 into NixOS:staging Aug 23, 2024
@@ -1,7 +1,7 @@
export NIX_SSL_CERT_FILE=@out@/etc/ssl/certs/ca-bundle.crt
export NIX_SSL_CERT_FILE="${NIX_SSL_CERT_FILE:-@out@/etc/ssl/certs/ca-bundle.crt}"
Copy link
Member

@arcnmx arcnmx Sep 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to check that the path in the env var is readable first before prioritizing its value over the built one?
I believe this change requires it to now be included in extra-sandbox-paths, which is unlikely to be the case in existing deployments using NIX_SSL_CERT_FILE prior to this change - and thus will suddenly point to something that doesn't exist as far as the builder is concerned.

It's worth noting that in recent versions, nix appears to bind-mount the file at NIX_SSL_CERT_FILE to /etc/ssl/certs/ca-certificates.crt, which means the builder may indeed have access to it but not at the path specified in the variable. There also may be interactions with remote builders to consider too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to check that the path in the env var is readable first before prioritizing its value over the built one?

Maybe? It wouldn't hurt, but I'm also surprised that you'd need to.

I believe this change requires it to now be included in extra-sandbox-paths, which is unlikely to be the case in existing deployments using NIX_SSL_CERT_FILE prior to this change

For build-daemon use cases, I've needed to work hard to set NIX_SSL_CERT_FILE. Either add it to the builder's env intentionally, or use the inpure-env config. So I assumed it wouldn't be accidentally set.

Maybe this is more common in a nixos deployment? It might be good to understand your use case and what happens after these changes, to confirm whether the right fix is "ignore NIX_SSL_CERT_FILE when it's not readable", or "don't do that thing you're doing". Maybe raise an issue and link it here for better visibility?

@mpleune-prattmiller
Copy link

I just ran down the whole rabbit hole here, after being confused why most packages built fine behind my corp internet, until finally I ran into ssl cert errors when I used fetchurl with an overridden src and fake hash. Suddenly, no --insecure is passed to curl, and instead of the normal "hey hash is wrong, here is what we got", you get a ssl error. I think fetchurl needs to be patched still to properly respect NIX_SSL_CERT_FILE when hashs are set with fakeHash.

Putting this comment here before creating a full issue because it will be some time before I collect enough documentation to open a proper issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

6.topic: fetch Fetchers (e.g. fetchgit, fetchsvn, ...) 6.topic: golang Go is a high-level general purpose programming language that is statically typed and compiled. 6.topic: lib The Nixpkgs function library 8.has: documentation This PR adds or changes documentation 10.rebuild-darwin: 501+ This PR causes many rebuilds on Darwin and should normally target the staging branches. 10.rebuild-darwin: 5001+ This PR causes many rebuilds on Darwin and must target the staging branches. 10.rebuild-darwin-stdenv This PR causes stdenv to rebuild on Darwin and must target a staging branch. 10.rebuild-linux: 501+ This PR causes many rebuilds on Linux and should normally target the staging branches. 10.rebuild-linux: 5001+ This PR causes many rebuilds on Linux and must target the staging branches.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants