From e5fc654f50e2b99bcae186962b29c8754f382f3b Mon Sep 17 00:00:00 2001 From: lassulus Date: Thu, 9 Dec 2021 11:21:06 +0100 Subject: [PATCH] add ACME ca via ca.r --- krebs/2configs/acme.nix | 65 +++++++++++++++ krebs/2configs/default.nix | 3 + krebs/3modules/default.nix | 1 + krebs/3modules/krebs/default.nix | 1 + krebs/3modules/ssl.nix | 80 +++++++++++++++++++ .../default.nix | 29 +++++++ 6 files changed, 179 insertions(+) create mode 100644 krebs/2configs/acme.nix create mode 100644 krebs/3modules/ssl.nix create mode 100644 krebs/5pkgs/simple/generate-krebs-intermediate-ca/default.nix diff --git a/krebs/2configs/acme.nix b/krebs/2configs/acme.nix new file mode 100644 index 000000000..b5e51a1a2 --- /dev/null +++ b/krebs/2configs/acme.nix @@ -0,0 +1,65 @@ +# generate intermediate certificate with generate-krebs-intermediate-ca +{ config, lib, pkgs, ... }: let + domain = "ca.r"; +in { + security.acme = { + acceptTerms = true; # kinda pointless since we never use upstream + email = "spam@krebsco.de"; + certs.${domain}.server = "https://${domain}:1443/acme/acme/directory"; # use 1443 here cause bootstrapping loop + }; + services.nginx = { + enable = true; + recommendedProxySettings = true; + virtualHosts.${domain} = { + forceSSL = true; + enableACME = true; + locations."/" = { + proxyPass = "https://localhost:1443"; + }; + }; + }; + krebs.secret.files.krebsAcme = { + path = "/var/lib/step-ca/intermediate_ca.key"; + owner.name = "root"; + mode = "1444"; + source-path = builtins.toString + "/acme_ca.key"; + }; + services.step-ca = { + enable = true; + intermediatePasswordFile = "/dev/null"; + address = "0.0.0.0"; + port = 1443; + settings = { + root = pkgs.writeText "root.crt" config.krebs.ssl.rootCA; + crt = pkgs.writeText "intermediate.crt" config.krebs.ssl.intermediateCA; + key = "/var/lib/step-ca/intermediate_ca.key"; + dnsNames = [ domain ]; + logger.format = "text"; + db = { + type = "badger"; + dataSource = "/var/lib/step-ca/db"; + }; + authority = { + provisioners = [{ + type = "ACME"; + name = "acme"; + forceCN = true; + }]; + claims = { + maxTLSCertDuration = "2160h"; + defaultTLSCertDuration = "2160h"; + }; + backdate = "1m0s"; + }; + tls = { + cipherSuites = [ + "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" + ]; + minVersion = 1.2; + maxVersion = 1.3; + renegotiation = false; + }; + }; + }; +} diff --git a/krebs/2configs/default.nix b/krebs/2configs/default.nix index 8a84d4465..ad77e6581 100644 --- a/krebs/2configs/default.nix +++ b/krebs/2configs/default.nix @@ -16,6 +16,9 @@ with import ; krebs.enable = true; krebs.tinc.retiolum.enable = mkDefault true; + # trust krebs ACME CA + krebs.ssl.trustIntermediate = true; + krebs.build.user = mkDefault config.krebs.users.krebs; networking.hostName = config.krebs.build.host.name; diff --git a/krebs/3modules/default.nix b/krebs/3modules/default.nix index 0617e15b2..2772d8d37 100644 --- a/krebs/3modules/default.nix +++ b/krebs/3modules/default.nix @@ -48,6 +48,7 @@ let ./secret.nix ./setuid.nix ./shadow.nix + ./ssl.nix ./sync-containers.nix ./tinc.nix ./tinc_graphs.nix diff --git a/krebs/3modules/krebs/default.nix b/krebs/3modules/krebs/default.nix index f796f0323..35ed67f5f 100644 --- a/krebs/3modules/krebs/default.nix +++ b/krebs/3modules/krebs/default.nix @@ -76,6 +76,7 @@ in { "agenda.r" "build.r" "build.hotdog.r" + "ca.r" "cgit.hotdog.r" "irc.r" "wiki.r" diff --git a/krebs/3modules/ssl.nix b/krebs/3modules/ssl.nix new file mode 100644 index 000000000..5d28ac841 --- /dev/null +++ b/krebs/3modules/ssl.nix @@ -0,0 +1,80 @@ +{ config, lib, pkgs, ... }: let + cfg = config.krebs.ssl; +in { + options.krebs.ssl = { + rootCA = lib.mkOption { + type = lib.types.str; + readOnly = true; + default = '' + -----BEGIN CERTIFICATE----- + MIIC0jCCAjugAwIBAgIJAKeARo6lDD0YMA0GCSqGSIb3DQEBBQUAMIGBMQswCQYD + VQQGEwJaWjESMBAGA1UECAwJc3RhdGVsZXNzMRAwDgYDVQQKDAdLcmVic2NvMQsw + CQYDVQQLDAJLTTEWMBQGA1UEAwwNS3JlYnMgUm9vdCBDQTEnMCUGCSqGSIb3DQEJ + ARYYcm9vdC1jYUBzeW50YXgtZmVobGVyLmRlMB4XDTE0MDYxMTA4NTMwNloXDTM5 + MDIwMTA4NTMwNlowgYExCzAJBgNVBAYTAlpaMRIwEAYDVQQIDAlzdGF0ZWxlc3Mx + EDAOBgNVBAoMB0tyZWJzY28xCzAJBgNVBAsMAktNMRYwFAYDVQQDDA1LcmVicyBS + b290IENBMScwJQYJKoZIhvcNAQkBFhhyb290LWNhQHN5bnRheC1mZWhsZXIuZGUw + gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMs/WNyeQziccllLqom7bfCjlh6/ + /qx9p6UOqpw96YOOT3sh/mNSBLyNxIUJbWsU7dN5hT7HkR7GwzpfKDtudd9qiZeU + QNYQ+OL0HdOnApjdPqdspZfKxKTXyC1T1vJlaODsM1RBrjLK9RUcQZeNhgg3iM9B + HptOCrMI2fjCdZuVAgMBAAGjUDBOMB0GA1UdDgQWBBSKeq01+rAwp7yAXwzlwZBo + 3EGVLzAfBgNVHSMEGDAWgBSKeq01+rAwp7yAXwzlwZBo3EGVLzAMBgNVHRMEBTAD + AQH/MA0GCSqGSIb3DQEBBQUAA4GBAIWIffZuQ43ddY2/ZnjAxPCRpM3AjoKIwEj9 + GZuLJJ1sB9+/PAPmRrpmUniRkPLD4gtmolDVuoLDNAT9os7/v90yg5dOuga33Ese + 725musUbhEoQE1A1oVHrexBs2sQOplxHKsVXoYJp2/trQdqvaNaEKc3EeVnzFC63 + 80WiO952 + -----END CERTIFICATE----- + ''; + }; + intermediateCA = lib.mkOption { + type = lib.types.str; + readOnly = true; + default = '' + -----BEGIN CERTIFICATE----- + MIICWzCCAcSgAwIBAgIQVavHn7XtM7NJ8bnph6hGoTANBgkqhkiG9w0BAQsFADCB + gTELMAkGA1UEBhMCWloxEjAQBgNVBAgMCXN0YXRlbGVzczEQMA4GA1UECgwHS3Jl + YnNjbzELMAkGA1UECwwCS00xFjAUBgNVBAMMDUtyZWJzIFJvb3QgQ0ExJzAlBgkq + hkiG9w0BCQEWGHJvb3QtY2FAc3ludGF4LWZlaGxlci5kZTAeFw0yMTEyMDgxNTU5 + MDRaFw0yMTEyMDkxNTU5MDRaMBoxGDAWBgNVBAMTD0tyZWJzIEFDTUUgQ0EgMTBZ + MBMGByqGSM49AgEGCCqGSM49AwEHA0IABDOK4g3pJPhOErk49zQgpNKE1cAyoeLp + PqWXkHZVLIVg8CBzPyCYiHS8RtaJ1kwWxwo5OTypCDOLxf1isR5HgZOjgYAwfjAO + BgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUv758 + A4RPewsRtgjdB6AE1tn632swHwYDVR0jBBgwFoAUinqtNfqwMKe8gF8M5cGQaNxB + lS8wGAYDVR0eAQH/BA4wDKAKMAOCAXIwA4IBdzANBgkqhkiG9w0BAQsFAAOBgQAT + ewOSGWGTCWcJFGSxgnt8/WspMERq1hL1PikwwVMp7wzJmbHcbA0Es4fcrE5Xf8vQ + dGenlvyQjkQNahbsyGBoja7bpWpnw9qofLQkns1AZWp7q7GBqyKm30keM/E/stjH + YkgY4QaxlIL+6N0f4nKL3RSf6GQ1hWJOHf+RrboaMw== + -----END CERTIFICATE----- + ''; + }; + acmeURL = lib.mkOption { + type = lib.types.str; + readOnly = true; + default = "https://ca.r/acme/acme/directory"; + }; + trustRoot = lib.mkOption { + type = lib.types.bool; + default = false; + description = '' + whether to trust the krebs root CA. + This implies that krebs can forge a certficate for every domain + ''; + }; + trustIntermediate = lib.mkOption { + type = lib.types.bool; + default = false; + description = '' + whether to trust the krebs ACME CA. + this only trusts the intermediate cert for .w and .r domains + ''; + }; + }; + config = lib.mkMerge [ + (lib.mkIf cfg.trustRoot { + security.pki.certificates = [ cfg.rootCA ]; + }) + (lib.mkIf cfg.trustIntermediate { + security.pki.certificates = [ cfg.intermediateCA ]; + }) + ]; +} diff --git a/krebs/5pkgs/simple/generate-krebs-intermediate-ca/default.nix b/krebs/5pkgs/simple/generate-krebs-intermediate-ca/default.nix new file mode 100644 index 000000000..8cec54327 --- /dev/null +++ b/krebs/5pkgs/simple/generate-krebs-intermediate-ca/default.nix @@ -0,0 +1,29 @@ +{ pkgs }: +pkgs.writers.writeDashBin "generate-intermediate-ca" '' + TMPDIR=$(mktemp -d) + trap "rm -rf $TMPDIR;" INT TERM EXIT + mkdir -p "$TMPDIR/krebs" + brain show ca/ca.key > "$TMPDIR/krebs/ca.key" + brain show ca/ca.crt > "$TMPDIR/krebs/ca.crt" + export STEPPATH="$TMPDIR/step" + cat << EOF > "$TMPDIR/intermediate.tpl" + { + "subject": {{ toJson .Subject }}, + "keyUsage": ["certSign", "crlSign"], + "basicConstraints": { + "isCA": true, + "maxPathLen": 0 + }, + "nameConstraints": { + "critical": true, + "permittedDNSDomains": ["r" ,"w"] + } + } + EOF + + ${pkgs.step-cli}/bin/step certificate create "Krebs ACME CA" intermediate_ca.crt intermediate_ca.key \ + --template "$TMPDIR/intermediate.tpl" \ + --ca "$TMPDIR/krebs/ca.crt" \ + --ca-key "$TMPDIR/krebs/ca.key" \ + --no-password --insecure +''