From db5dc5aee6fe43aa02980fbee1b7dcc1ae7890c3 Mon Sep 17 00:00:00 2001 From: Jake Hillion Date: Thu, 1 Aug 2024 19:16:06 +0100 Subject: [PATCH] step-ca: enable server on sodium and load root certs --- hosts/sodium.pop.ts.hillion.co.uk/default.nix | 3 ++ modules/ca/README.md | 11 +++++ modules/ca/cert.pem | 13 ++++++ modules/ca/consumer.nix | 14 ++++++ modules/ca/default.nix | 8 ++++ modules/ca/service.nix | 45 +++++++++++++++++++ modules/default.nix | 1 + modules/defaults.nix | 1 + modules/impermanence.nix | 16 +++---- modules/services/authoritative_dns.nix | 1 + modules/services/downloads.nix | 10 ++++- 11 files changed, 113 insertions(+), 10 deletions(-) create mode 100644 modules/ca/README.md create mode 100644 modules/ca/cert.pem create mode 100644 modules/ca/consumer.nix create mode 100644 modules/ca/default.nix create mode 100644 modules/ca/service.nix diff --git a/hosts/sodium.pop.ts.hillion.co.uk/default.nix b/hosts/sodium.pop.ts.hillion.co.uk/default.nix index 7479fdc..0abd12d 100644 --- a/hosts/sodium.pop.ts.hillion.co.uk/default.nix +++ b/hosts/sodium.pop.ts.hillion.co.uk/default.nix @@ -30,6 +30,9 @@ chmod +t /cache/tmp ''; + ## CA server + custom.ca.service.enable = true; + ### nix only supports build-dir from 2.22. bind mount /tmp to something persistent instead. fileSystems."/tmp" = { device = "/cache/tmp"; diff --git a/modules/ca/README.md b/modules/ca/README.md new file mode 100644 index 0000000..aadacd7 --- /dev/null +++ b/modules/ca/README.md @@ -0,0 +1,11 @@ +# ca + +Getting the certificates in the right place is a manual process (for now, at least). This is to keep the most control over the root certificate's key and allow manual cycling. The manual commands should be run on a trusted machine. + +Creating a 10 year root certificate: + + nix run nixpkgs#step-cli -- certificate create 'Hillion ACME' cert.pem key.pem --kty=EC --curve=P-521 --profile=root-ca --not-after=87600h + +Creating the intermediate key: + + nix run nixpkgs#step-cli -- certificate create 'Hillion ACME (sodium.pop.ts.hillion.co.uk)' intermediate_cert.pem intermediate_key.pem --kty=EC --curve=P-521 --profile=intermediate-ca --not-after=8760h --ca=$NIXOS_ROOT/modules/ca/cert.pem --ca-key=DOWNLOADED_KEY.pem diff --git a/modules/ca/cert.pem b/modules/ca/cert.pem new file mode 100644 index 0000000..7fe3d71 --- /dev/null +++ b/modules/ca/cert.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB+TCCAVqgAwIBAgIQIZdaIUsuJdjnu7DQP1N8oTAKBggqhkjOPQQDBDAXMRUw +EwYDVQQDEwxIaWxsaW9uIEFDTUUwHhcNMjQwODAxMjIyMjEwWhcNMzQwNzMwMjIy +MjEwWjAXMRUwEwYDVQQDEwxIaWxsaW9uIEFDTUUwgZswEAYHKoZIzj0CAQYFK4EE +ACMDgYYABAAJI3z1PrV97EFc1xaENcr6ML1z6xdXTy+ReHtf42nWsw+c3WDKzJ45 ++xHJ/p2BTOR5+NQ7RGQQ68zmFJnEYTYDogAw6U9YzxxDGlG1HlgnZ9PPmXoF+PFl +Zy2WZCiDPx5KDJcjTPzLV3ITt4fl3PMA12BREVeonvrvRLcpVrMfS2b7wKNFMEMw +DgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwHQYDVR0OBBYEFFBT +fMT0uUbS+lVUbGKK8/SZHPISMAoGCCqGSM49BAMEA4GMADCBiAJCAPNIwrQztPrN +MaHB3J0lNVODIGwQWblt99vnjqIWOKJhgckBxaElyInsyt8dlnmTCpOCJdY4BA+K +Nr87AfwIWdAaAkIBV5i4zXPXVKblGKnmM0FomFSbq2cYE3pmi5BO1StakH1kEHlf +vbkdwFgkw2MlARp0Ka3zbWivBG9zjPoZtsL/8tk= +-----END CERTIFICATE----- diff --git a/modules/ca/consumer.nix b/modules/ca/consumer.nix new file mode 100644 index 0000000..a47b1ab --- /dev/null +++ b/modules/ca/consumer.nix @@ -0,0 +1,14 @@ +{ config, pkgs, lib, ... }: + +let + cfg = config.custom.ca.consumer; +in +{ + options.custom.ca.consumer = { + enable = lib.mkEnableOption "ca.service"; + }; + + config = lib.mkIf cfg.enable { + security.pki.certificates = [ (builtins.readFile ./cert.pem) ]; + }; +} diff --git a/modules/ca/default.nix b/modules/ca/default.nix new file mode 100644 index 0000000..1f79cf5 --- /dev/null +++ b/modules/ca/default.nix @@ -0,0 +1,8 @@ +{ ... }: + +{ + imports = [ + ./consumer.nix + ./service.nix + ]; +} diff --git a/modules/ca/service.nix b/modules/ca/service.nix new file mode 100644 index 0000000..f6dca74 --- /dev/null +++ b/modules/ca/service.nix @@ -0,0 +1,45 @@ +{ config, pkgs, lib, ... }: + +let + cfg = config.custom.ca.service; +in +{ + options.custom.ca.service = { + enable = lib.mkEnableOption "ca.service"; + }; + + config = lib.mkIf cfg.enable { + services.step-ca = { + enable = true; + + address = config.custom.dns.tailscale.ipv4; + port = 8443; + + intermediatePasswordFile = "/data/system/ca/intermediate.psk"; + + settings = { + root = ./cert.pem; + crt = "/data/system/ca/intermediate.crt"; + key = "/data/system/ca/intermediate.pem"; + + dnsNames = [ "ca.ts.hillion.co.uk" ]; + + logger = { format = "text"; }; + + db = { + type = "badgerv2"; + dataSource = "/var/lib/step-ca/db"; + }; + + authority = { + provisioners = [ + { + type = "ACME"; + name = "acme"; + } + ]; + }; + }; + }; + }; +} diff --git a/modules/default.nix b/modules/default.nix index 041a4b4..9fdcbe8 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -3,6 +3,7 @@ { imports = [ ./backups/default.nix + ./ca/default.nix ./chia.nix ./defaults.nix ./desktop/awesome/default.nix diff --git a/modules/defaults.nix b/modules/defaults.nix index f7240b8..1923274 100644 --- a/modules/defaults.nix +++ b/modules/defaults.nix @@ -54,6 +54,7 @@ networking.firewall.enable = true; # Delegation + custom.ca.consumer.enable = true; custom.dns.enable = true; custom.home.defaults = true; custom.hostinfo.enable = true; diff --git a/modules/impermanence.nix b/modules/impermanence.nix index b01c02f..49a661d 100644 --- a/modules/impermanence.nix +++ b/modules/impermanence.nix @@ -2,7 +2,6 @@ let cfg = config.custom.impermanence; - listIf = (enable: x: if enable then x else [ ]); in { options.custom.impermanence = { @@ -45,13 +44,14 @@ in directories = [ "/etc/nixos" - ] ++ (listIf config.services.tailscale.enable [ "/var/lib/tailscale" ]) ++ - (listIf config.services.zigbee2mqtt.enable [ config.services.zigbee2mqtt.dataDir ]) ++ - (listIf config.services.postgresql.enable [ config.services.postgresql.dataDir ]) ++ - (listIf config.hardware.bluetooth.enable [ "/var/lib/bluetooth" ]) ++ - (listIf config.custom.services.unifi.enable [ "/var/lib/unifi" ]) ++ - (listIf (config.virtualisation.oci-containers.containers != { }) [ "/var/lib/containers" ]) ++ - (listIf config.services.tang.enable [ "/var/lib/private/tang" ]); + ] ++ (lib.lists.optional config.services.tailscale.enable "/var/lib/tailscale") ++ + (lib.lists.optional config.services.zigbee2mqtt.enable config.services.zigbee2mqtt.dataDir) ++ + (lib.lists.optional config.services.postgresql.enable config.services.postgresql.dataDir) ++ + (lib.lists.optional config.hardware.bluetooth.enable "/var/lib/bluetooth") ++ + (lib.lists.optional config.custom.services.unifi.enable "/var/lib/unifi") ++ + (lib.lists.optional (config.virtualisation.oci-containers.containers != { }) "/var/lib/containers") ++ + (lib.lists.optional config.services.tang.enable "/var/lib/private/tang") ++ + (lib.lists.optional config.services.step-ca.enable "/var/lib/step-ca/db"); }; home-manager.users = diff --git a/modules/services/authoritative_dns.nix b/modules/services/authoritative_dns.nix index bf89c2c..98b57a7 100644 --- a/modules/services/authoritative_dns.nix +++ b/modules/services/authoritative_dns.nix @@ -32,6 +32,7 @@ in 86400 NS ns1.hillion.co.uk. + ca 21600 CNAME sodium.pop.ts.hillion.co.uk. deluge.downloads 21600 CNAME tywin.storage.ts.hillion.co.uk. graphs.router.home 21600 CNAME router.home.ts.hillion.co.uk. prowlarr.downloads 21600 CNAME tywin.storage.ts.hillion.co.uk. diff --git a/modules/services/downloads.nix b/modules/services/downloads.nix index 3cc8f98..f125700 100644 --- a/modules/services/downloads.nix +++ b/modules/services/downloads.nix @@ -29,10 +29,16 @@ in virtualHosts = builtins.listToAttrs (builtins.map (x: { - name = "http://${x}.downloads.ts.hillion.co.uk"; + name = "${x}.downloads.ts.hillion.co.uk"; value = { listenAddresses = [ config.custom.dns.tailscale.ipv4 config.custom.dns.tailscale.ipv6 ]; - extraConfig = "reverse_proxy unix//${cfg.metadataPath}/caddy/caddy.sock"; + extraConfig = '' + reverse_proxy unix//${cfg.metadataPath}/caddy/caddy.sock + + tls { + ca https://ca.ts.hillion.co.uk:8443/acme/acme/directory + } + ''; }; }) [ "prowlarr" "sonarr" "radarr" "deluge" ]); };