Adding a new CA certificate to included bundle

Hello all.

I am using Nix on my work computer (macOS, single-user installation). My work has their own custom CA for MITM interception. I’ve had a lot of certificate difficulties because of this, but what I’ve found that works is simply appending my work’s certificate onto the included CA bundle that Nix provides.

This feels a bit hacky and not very “Nix-ish”. I’m curious if there is a way to specify to Nix a list of custom CA certificates that should be included alongside the default bundle from nixpkgs.cacert.

I have read through "SSL peer certificate or SSH remote key was not OK" error on fresh Nix install on macOS - #14 by duff and I tried setting NIX_SSL_CERT_FILE to the certificate bundle included on my system (/etc/ssl/cert.pem) which does include my work’s custom CA file, but that caused the dreaded “SSL peer certificate or SSH remote key was not OK” error message, presumably because my system’s default CA bundle is missing some other certificates that the nixpkgs.cacert package provides. So the best solution would be to simply append my work’s CA file onto that.

Thanks!

2 Likes

Are you looking for security.pki.certificateFiles?

That is only a NixOS configuration option, no? I am using Nix on macOS.

Ah, I see, looks like I skimmed past that, sorry!

I’m also having the same issue. @gpanders did you manage to solve it?

I’m also having this issue, was anyone able to solve it?

I don’t know if this will work on Nix/OSX

however it’s worth a shot,

Thank you. However I still cannot get my TLS cert to be recognized.

My use-case is not trivial (I think).

I am setting up my CI system with gitea and gitea actions, and I want to build nix derivations with it. I’ve found this flake: https://icewind.nl/entry/gitea-actions-nix/ and I’ve setup everything in the gitea part.

The issue is that everything is self hosted, and I have my own TLS certificates, and my own CA.

I managed to add cacert from nixpkgs to add my own crt file, and I updated the env variables to point to the list of CAs with mine.

{
  inputs = {
    nix.url = "github:/nixos/nix?ref=2.18.1";
    nix.inputs.nixpkgs.follows = "nixpkgs";
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.05";
    flake-utils.url = "github:numtide/flake-utils";
  };

  outputs = {
    self,
    flake-utils,
    nix,
    nixpkgs,
    ...
  }:
    flake-utils.lib.eachDefaultSystem (system: let
      pkgs = (import nixpkgs) {
        inherit system;
      };
      lib = pkgs.lib;

      # trust TLS certficates
      private_cacert = pkgs.cacert.override {
        extraCertificateFiles = [ ./philt3r.crt ];
      };
    in rec {
      packages = rec {
        # a modified version of the nixos/nix image
        # re-using the upstream nix docker image generation code
        base = import (nix + "/docker.nix") {
          inherit pkgs;
          name = "nix-ci-base";
          maxLayers = 10;
          extraPkgs = [
            pkgs.nodejs_20 # nodejs is needed for running most 3rdparty actions
            # add any other pre-installed packages here
          ];
          # change this is you want
          channelURL = "https://nixos.org/channels/nixpkgs-23.05";
          nixConf = {
            substituters = [
              "https://cache.nixos.org/"
              "https://nix-community.cachix.org"
              # insert any other binary caches here
            ];
            trusted-public-keys = [
              "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
              "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
              # insert the public keys for those binary caches here
            ];
            # allow using the new flake commands in our workflows
            experimental-features = ["nix-command" "flakes"];
          };
        };
        # make /bin/sleep available on the image
        runner = pkgs.dockerTools.buildImage {
          name = "nix-runner";
          tag = "latest";

          fromImage = base;
          fromImageName = null;
          fromImageTag = "latest";

          copyToRoot = pkgs.buildEnv {
            name = "image-root";
            paths = [
              pkgs.coreutils-full
            ];
            pathsToLink = [
              "/bin" # add coreutuls (which includes sleep) to /bin
            ];
          };

          config = {
            Env = [
              "SSL_CERT_FILE=${private_cacert}/etc/ssl/certs/ca-bundle.crt"
              "GIT_SSL_CAINFO=${private_cacert}/etc/ssl/certs/ca-bundle.crt"
              "NIX_SSL_CERT_FILE=${private_cacert}/etc/ssl/certs/ca-bundle.crt"
              "CURL_CA_BUNDLE=${private_cacert}/etc/ssl/certs/ca-bundle.crt"
            ];
          };
        };
      };
    });
}

But when I start some CI jobs with nix, I always get this error:

[command]/root/.nix-profile/bin/git -c protocol.version=2 fetch --no-tags --prune --progress --no-recurse-submodules --depth=1 origin +<githashgoeshere>:refs/remotes/origin/nix-ci
fatal: unable to access 'https://git.myprivatenetwork': SSL certificate problem: unable to get local issuer certificate

I am running out of ideas now, but it’s my first time with nix so I’m sure I’m not getting started with the easiest of things :slight_smile:

If anyone has any idea I’m taking it ! cheers

1 Like

I’m not familiar with what you’re trying to do and I wasn’t aware of pkgs.cacerts (which will probably help me in the future, thanks for sharing). My painful experience with setting up certificate is that there’s always one extra place to set them up :(. I haven’t had this exact error yet though.

Have you confirmed that you the generated bundle is where you expect and works? Is the problem only with nix and/or git?

If yes, I’d try to get more log about what git is using, maybe try GIT_CURL_VERBOSE=1.