diff --git a/base.nix b/base.nix index c0ae045..19dad92 100644 --- a/base.nix +++ b/base.nix @@ -3,6 +3,7 @@ { imports = [ ./users + ./modules/snakeoil-certs.nix ]; networking.domain = "pvv.ntnu.no"; @@ -82,29 +83,37 @@ settings.PermitRootLogin = "yes"; }; - # nginx 404 for nonexistent virtualhosts sops.age = { sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ]; keyFile = "/var/lib/sops-nix/key.txt"; generateKey = true; }; - sops.secrets = lib.mkIf (config.services.nginx.enable) { - "snakeoil_cert/public" = { + # nginx 404 for nonexistent virtualhosts + + # sops.secrets = lib.mkIf (config.services.nginx.enable) { + # "snakeoil_cert/public" = { + # owner = "nginx"; + # group = "nginx"; + # sopsFile = ./secrets/common.yaml; + # }; + # "snakeoil_cert/private" = { + # owner = "nginx"; + # group = "nginx"; + # sopsFile = ./secrets/common.yaml; + # }; + # }; + + environment.snakeoil-certs = lib.mkIf (config.services.nginx.enable) { + "/etc/certs/nginx" = { owner = "nginx"; group = "nginx"; - sopsFile = ./secrets/common.yaml; - }; - "snakeoil_cert/private" = { - owner = "nginx"; - group = "nginx"; - sopsFile = ./secrets/common.yaml; }; }; services.nginx.virtualHosts."_" = lib.mkIf (config.services.nginx.enable) { - sslCertificate = config.sops.secrets."snakeoil_cert/public".path; - sslCertificateKey = config.sops.secrets."snakeoil_cert/private".path; + sslCertificate = "/etc/certs/nginx.crt"; + sslCertificateKey = "/etc/certs/nginx.key"; addSSL = true; extraConfig = "return 444;"; }; diff --git a/modules/snakeoil-certs.nix b/modules/snakeoil-certs.nix new file mode 100644 index 0000000..e368ecd --- /dev/null +++ b/modules/snakeoil-certs.nix @@ -0,0 +1,78 @@ +{ config, pkgs, lib, ... }: +let + cfg = config.environment.snakeoil-certs; +in +{ + options.environment.snakeoil-certs = lib.mkOption { + default = { }; + description = "TODO"; + type = lib.types.attrsOf (lib.types.submodule ({ name, ... }: { + options = { + owner = lib.mkOption { + type = lib.types.str; + default = "root"; + }; + group = lib.mkOption { + type = lib.types.str; + default = "root"; + }; + mode = lib.mkOption { + type = lib.types.str; + default = "0770"; + }; + daysValid = lib.mkOption { + type = lib.types.str; + default = "90"; + }; + opensslOptions = lib.mkOption { + type = with lib.types; listOf str; + default = [ ]; + }; + certificate = lib.mkOption { + type = lib.types.str; + default = "${name}.crt"; + }; + certificateKey = lib.mkOption { + type = lib.types.str; + default = "${name}.key"; + }; + }; + })); + }; + + config = { + systemd.services."gen-snakeoil-certs" = { + enable = true; + serviceConfig.Type = "oneshot"; + script = let + openssl = lib.getExe pkgs.openssl; + in lib.concatMapStringsSep "\n" ({ name, value }: '' + mkdir -p $(dirname "${value.certificate}") $(dirname "${value.certificateKey}") + if ! ${openssl} x509 -checkend 86400 -noout -in ${value.certificate} + then + echo "Regenerating '${value.certificate}'" + ${openssl} req \ + -newkey rsa:4096 \ + -new -x509 \ + -days "${toString value.daysValid}" \ + -nodes \ + -out "${value.certificate}" \ + -keyout "${value.certificateKey}" \ + ${lib.escapeShellArgs value.opensslOptions} + fi + chown "${value.owner}:${value.group}" "${value.certificate}" + chown "${value.owner}:${value.group}" "${value.certificateKey}" + chmod "${value.mode}" "${value.certificate}" + chmod "${value.mode}" "${value.certificateKey}" + '') (lib.attrsToList cfg); + }; + systemd.timers."gen-snakeoil-certs" = { + wantedBy = [ "timers.target" ]; + timerConfig = { + OnCalendar = "*-*-* 02:00:00"; + Persistent = true; + Unit = "gen-snakeoil-certs.service"; + }; + }; + }; +}