diff --git a/nixos/machines/frumar/default.nix b/nixos/machines/frumar/default.nix
index 35a31d0..a9c19b3 100644
--- a/nixos/machines/frumar/default.nix
+++ b/nixos/machines/frumar/default.nix
@@ -16,13 +16,13 @@
}) ];
systemd.tmpfiles.rules = lib.mkAfter [
- "d ${config.services.acme-sh.stateDir}/selfsign 0700 nginx nginx"
+ "d /var/lib/acme.sh/selfsign 0700 nginx nginx"
];
systemd.services."yori-selfsigned-ca" = {
description = "Generate self-signed fallback";
path = with pkgs; [ minica ];
unitConfig = {
- ConditionPathExists = "!${config.services.acme-sh.stateDir}/selfsign/selfsigned.local/key.pem";
+ ConditionPathExists = "!/var/lib/acme.sh/selfsign/selfsigned.local/key.pem";
StartLimitIntervalSec = 0;
};
serviceConfig = {
@@ -31,7 +31,7 @@
UMask = "0077";
Type = "oneshot";
PrivateTmp = true;
- WorkingDirectory = "${config.services.acme-sh.stateDir}/selfsign";
+ WorkingDirectory = "/var/lib/acme.sh/selfsign";
};
script = "minica --domains selfsigned.local";
};
@@ -40,19 +40,11 @@
after = [ "yori-selfsigned-ca.service" ];
};
- services.nginx = let
- cert = config.services.acme-sh.certs.wildcard-yori-cc;
- sslCertificate = cert.certPath;
- sslCertificateKey = cert.keyPath;
- in {
+ services.nginx = {
enable = true;
- recommendedOptimisation = true;
- recommendedTlsSettings = true;
- recommendedProxySettings = true;
- recommendedGzipSettings = true;
virtualHosts."unifi.yori.cc" = {
onlySSL = true;
- inherit sslCertificate sslCertificateKey;
+ useACMEHost = "wildcard.yori.cc";
locations."/" = {
proxyPass = "https://[::1]:8443";
proxyWebsockets = true;
@@ -64,7 +56,7 @@
};
virtualHosts."home-assistant.yori.cc" = {
onlySSL = true;
- inherit sslCertificate sslCertificateKey;
+ useACMEHost = "wildcard.yori.cc";
locations."/" = {
proxyPass = "http://[::1]:8123";
proxyWebsockets = true;
@@ -72,10 +64,8 @@
};
virtualHosts."frumar.yori.cc" = {
enableACME = lib.mkForce false;
- forceSSL = true;
sslCertificate = "/var/lib/acme.sh/selfsign/selfsigned.local/cert.pem";
sslCertificateKey = "/var/lib/acme.sh/selfsign/selfsigned.local/key.pem";
- default = true;
};
};
boot.supportedFilesystems = [ "zfs" ];
@@ -235,11 +225,10 @@
age.secrets = {
grafana.file = ../../../secrets/grafana.env.age;
frumar-mail-pass.file = ../../../secrets/frumar-mail-pass.age;
- transip-key = {
+ acme-transip-key = {
file = ../../../secrets/transip-key.age;
mode = "770";
- owner = "nginx";
- group = "nginx";
+ group = "acme";
};
};
systemd.services.grafana.serviceConfig.EnvironmentFile = config.age.secrets.grafana.path;
@@ -324,16 +313,15 @@
unzip
yscripts.absorb
];
- services.acme-sh.certs.wildcard-yori-cc = {
- mainDomain = "*.yori.cc";
- dns = "dns_transip";
- production = true;
- postRun = "systemctl reload nginx || true";
- inherit (config.services.nginx) user group;
+ security.acme.certs."wildcard.yori.cc" = {
+ domain = "*.yori.cc";
+ dnsProvider = "transip";
+ reloadServices = [ "nginx.service" ];
};
- systemd.services.acme-sh-wildcard-yori-cc.environment = {
- TRANSIP_Username = "yorickvp";
- TRANSIP_Key_File = config.age.secrets.transip-key.path;
+ users.users.nginx.extraGroups = [ "acme" ];
+ systemd.services."acme-wildcard.yori.cc".environment = {
+ TRANSIP_ACCOUNT_NAME = "yorickvp";
+ TRANSIP_PRIVATE_KEY_PATH = config.age.secrets.acme-transip-key.path;
};
programs.msmtp = {
enable = true;
diff --git a/nixos/modules/acme-sh.nix b/nixos/modules/acme-sh.nix
deleted file mode 100644
index d7c19ce..0000000
--- a/nixos/modules/acme-sh.nix
+++ /dev/null
@@ -1,166 +0,0 @@
-# SPDX-FileCopyrightText: 2020 Serokell
-#
-# SPDX-License-Identifier: MPL-2.0
-
-{ config, lib, pkgs, ... }:
-
-let
- cfg = config.services.acme-sh;
- # todo: upstream into serokell.nix
- dnstype = lib.types.enum [ "dns_aws" "dns_dnsimple" "dns_transip" ];
- submod = with lib; config: {
- domains = mkOption {
- type = types.coercedTo
- (types.listOf types.str)
- (f: lib.genAttrs f (x: config.dns)) (types.attrsOf dnstype);
- default = { "${config.mainDomain}" = config.dns; };
- };
- mainDomain = mkOption {
- type = types.str;
- description = "domain to use as primary domain for the cert";
- };
- postRun = mkOption {
- type = types.str;
- default = "true";
- };
- keyFile = mkOption {
- type = types.str;
- default = "/dev/null";
- };
- user = mkOption {
- type = types.str;
- default = "root";
- description = "User running the ACME client.";
- };
-
- group = mkOption {
- type = types.str;
- default = "root";
- description = "Group running the ACME client.";
- };
-
- server = mkOption {
- type = types.str;
- default = "letsencrypt";
- description = "Certificate Authority to use";
- };
- dns = mkOption {
- type = dnstype;
- };
- renewInterval = mkOption {
- type = types.str;
- default = "weekly";
- description = ''
- Systemd calendar expression when to check for renewal. See
- systemd.time
- 7.
- '';
- };
- production = mkOption {
- type = types.bool;
- default = true;
- };
- statePath = mkOption {
- readOnly = true;
- type = types.str;
- };
- keyPath = mkOption {
- readOnly = true;
- type = types.str;
- };
- certPath = mkOption {
- readOnly = true;
- type = types.str;
- };
- consulLock = mkOption {
- type = types.nullOr types.str;
- default = null;
- example = "vault";
- };
-};
-in
-{
- options.services.acme-sh = with lib; {
- stateDir = lib.mkOption {
- type = types.str;
- default = "/var/lib/acme.sh";
- };
- certs = lib.mkOption {
- type = types.attrsOf (types.submodule ({config, name, ...}: (with config; {
- options = submod config;
- config.statePath = "${cfg.stateDir}/${name}";
- config.keyPath = "${statePath}/${mainDomain}_ecc/${mainDomain}.key";
- config.certPath = "${statePath}/${mainDomain}_ecc/fullchain.cer";
- })));
- default = {};
- };
- };
- config = {
- systemd.tmpfiles.rules = if cfg.certs != {} then [
- "d ${cfg.stateDir} 0755 root root"
- ] else [];
- systemd.services = lib.mapAttrs' (name: value: lib.nameValuePair "acme-sh-${name}" (with value; {
- description = "Renew ACME Certificate for ${name}";
- after =
- [ "network.target" "network-online.target" ]
- # wait for consul if we use it for locking
- ++ lib.optionals (consulLock != null) [ "consul.service" ];
- wants = [ "network-online.target" ];
- serviceConfig = {
- Type = "oneshot";
- PermissionsStartOnly = true;
- User = user;
- Group = group;
- PrivateTmp = true;
- EnvironmentFile = keyFile;
- SuccessExitStatus = "0 2";
- };
- path = with pkgs; [ acme-sh systemd util-linuxMinimal procps ];
- preStart = ''
- mkdir -p "${statePath}"
- chown -R '${user}:${group}' "${statePath}"
- chmod 750 "${statePath}"
- rm -f "${statePath}/renewed"
- '';
- environment.LE_WORKING_DIR = statePath;
- environment.SHELL = "${pkgs.bash}/bin/bash";
- script = let
- mapDomain = name: dns: ''-d "${name}" --dns ${dns}'';
- primary = mapDomain mainDomain domains."${mainDomain}";
- domainsStr = lib.concatStringsSep " " ([primary] ++ (lib.remove primary (lib.mapAttrsToList mapDomain domains)));
- cmd = ''acme.sh --server ${server} --issue ${lib.optionalString (!production) "--test"} ${domainsStr} --reloadcmd "touch ${statePath}/renewed" --syslog 6 > /dev/null'';
- in
- if consulLock == null then ''
- ${cmd}
- rm -f "$LE_WORKING_DIR/account.conf"
- '' else ''
- # consul lock does not expose the exit code, because of platform compatiblity or something
- # write it to the 'ecode' file, or exit 1 if it fails altogether
- if ${config.services.consul.package}/bin/consul lock -verbose "${consulLock}" '${cmd}; echo $? > ${statePath}/ecode'; then
- rm -f "$LE_WORKING_DIR/account.conf"
- exit $(cat ${statePath}/ecode)
- else
- rm -f "$LE_WORKING_DIR/account.conf"
- exit 1
- fi
- '';
- postStart = ''
- if [ -e "${statePath}/renewed" ]; then
- ${postRun}
- rm -f "${statePath}/renewed"
- fi
- '';
- })) cfg.certs;
- systemd.timers = lib.mapAttrs' (name: value: lib.nameValuePair "acme-sh-${name}" (with value; {
- wantedBy = [ "timers.target" ];
- timerConfig = {
- OnCalendar = renewInterval;
- Unit = "acme-sh-${name}.service";
- Persistent = "yes";
- AccuracySec = "5m";
- RandomizedDelaySec = "1h";
- };
- })) cfg.certs;
- };
-
-}
diff --git a/nixos/modules/nginx.nix b/nixos/modules/nginx.nix
index b8608cf..e201465 100644
--- a/nixos/modules/nginx.nix
+++ b/nixos/modules/nginx.nix
@@ -1,14 +1,6 @@
{ config, lib, pkgs, ... }:
-let
- sslcfg = dir: ''
- ssl on;
- ssl_certificate_key ${dir}/key.pem;
- ssl_certificate ${dir}/fullchain.pem;
- ssl_trusted_certificate ${dir}/fullchain.pem;
- add_header Strict-Transport-Security max-age=15768000;
- '';
-in {
+{
config = lib.mkIf config.services.nginx.enable {
services.nginx = {
recommendedTlsSettings = true;
diff --git a/nixos/roles/default.nix b/nixos/roles/default.nix
index ece1c3d..1c935ef 100644
--- a/nixos/roles/default.nix
+++ b/nixos/roles/default.nix
@@ -5,7 +5,6 @@ let
in {
imports = [
inputs.agenix.nixosModules.default
- ../modules/acme-sh.nix
../modules/tor-hidden-service.nix
../modules/nginx.nix
../modules/lumi-cache.nix