Where can I get snakeoil certificates?

I’m trying to setup a local dev server to test something, and I want just a set of self-signed certs for test purposes. On systems like Ubuntu you can install ssl-cert package and you’ll get a set of “snakeoil” self-signed certs:

 > sudo apt install ssl-cert
 > sudo ls -l /etc/ssl/certs/ssl-cert-snakeoil.pem /etc/ssl/private/ssl-cert-snakeoil.key
-rw-r--r-- 1 root root     1115 Aug 20 16:31 /etc/ssl/certs/ssl-cert-snakeoil.pem
-rw-r----- 1 root ssl-cert 1704 Aug 20 16:31 /etc/ssl/private/ssl-cert-snakeoil.key

Is there an easy to use equivalent of this? I was hoping for something like:

services.nginx = {
  virtualHosts = {
    "test.example.org" = {
      sslCertificate = "${pkgs.snakeoil}/snakeoil.cert.pem";
      sslCertificateKey = "${pkgs.snakeoil}/snakeoil.key.pem";
      locations = { ... };
    };
  };
};

But I see no such package. I did find a service config for ACME, and that does include a set of self-signed certificates in its definition:

But I’m not really sure how to use that. It appears to be just used for tests.
I though that maybe I could use something like:

services.nginx = {
  virtualHosts = {
    "test.example.org" = {
      sslCertificate = <nixpkgs>/tests/common/acme/server/acme.test.cert.pem;
      sslCertificateKey = <nixpkgs>/tests/common/acme/server/acme.test.key.pem;
      locations = { ... };
    };
  };
};

But that does not work. Any suggestions would be welcome.

1 Like

I do this with a systemd unit, here’s a fragment of my code

      systemd.services."create-${name}-cert" = {
        description = "Create a certificate for ${name}";

        script = ''
          ${pkgs.libressl}/bin/openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes -subj '/CN=localhost'
          chmod 644 cert.pem
          chmod 640 key.pem
        '';

        wantedBy = [ "multi-user.target" "nginx.service" ] 
        
        unitConfig = {
          Before = [ "multi-user.target" "nginx.service" ]  ;
          ConditionPathExists = "!${cfg.path}/cert.pem";
        };

        serviceConfig = {
          User = cfg.user;
          Type = "oneshot";
          WorkingDirectory = cfg.path;
          RemainAfterExit = true;
        };
      };

You should also replace any substitution with your requirements, for example, cfg.user for the user you want to own the cert, and cfg.path for the path you want to install it to. (You should make sure it exists first, maybe using systemd.tmpfiles). And then add to your nginx attrset:

        sslCertificate = "${cfg.path}/cert.pem";
        sslCertificateKey = "${cfg.path}/key.pem";
2 Likes

Sorry but I was away and kinda forgot I made this post. Thanks for this suggestion. It’s a decent solution.

If you specifically want to use the snakeoil keys from the acme tests, this should work:

{ config, lib, pkgs, ... }: {
  services.nginx = {
    virtualHosts = {
      "test.example.org" = {
        sslCertificate = "${pkgs.path}/nixos/tests/common/acme/server/acme.test.cert.pem";
        sslCertificateKey = "${pkgs.path}/nixos/tests/common/acme/server/acme.test.key.pem";
        locations = { ... };
      };
    };
  };
}
2 Likes

Oh, that’s perfect. I really don’t care what kind of cert it is, one snake oil is same as another snake oil, it’s just for tests that require SSL. This is probably the simplest possible solution since it doesn’t require generating any certificates. Thanks!