From 365b16c380db387db60baedff4e9f17a4c27deb9 Mon Sep 17 00:00:00 2001 From: Kaare Hoff Skovgaard Date: Thu, 10 Jul 2025 21:42:33 +0200 Subject: [PATCH] Begin working on nginx setup --- nix/modules/nixos/security/acme/default.nix | 61 +++++++++++++++++++ nix/modules/nixos/services/nginx/default.nix | 41 +++++++++++++ .../default.nix | 1 + .../nixos/services/vault-agent/default.nix | 11 ++++ 4 files changed, 114 insertions(+) create mode 100644 nix/modules/nixos/security/acme/default.nix create mode 100644 nix/modules/nixos/services/nginx/default.nix diff --git a/nix/modules/nixos/security/acme/default.nix b/nix/modules/nixos/security/acme/default.nix new file mode 100644 index 0000000..8b12928 --- /dev/null +++ b/nix/modules/nixos/security/acme/default.nix @@ -0,0 +1,61 @@ +{ config, lib, ... }: +let + cfg = config.khscodes.security.acme; + vaultAgentCredentialsFile = "/var/lib/vault-agent/acme/cloudflare-api-token"; + cloudflareSecret = "opentofu/data/cloudflare"; + acmeServicesToRestart = lib.lists.map (a: "acme-${a}.service") ( + lib.attrsets.attrNames config.security.certs + ); +in +{ + options.khscodes.security.acme = { + enable = lib.mkEnableOption "Enables acme"; + dns01Enabled = lib.mkOption { + type = lib.types.bool; + description = "Whether to use DNS01 instead of http-01 challenges. This will make the approle gain policy to retrieve the needed cloudflare secrets to manage dns."; + default = config.khscodes.infrastructure.khs-openstack-instance.enable; + }; + }; + config = lib.mkIf cfg.enable { + security.acme = { + acceptTerms = true; + defaults = + { + email = "kaare@kaareskovgaard.net"; + } + // lib.attrsets.optionalAttrs cfg.dns01Enabled { + dnsProvider = "cloudflare"; + dnsResolver = "1.1.1.1:53"; + credentialsFile = vaultAgentCredentialsFile; + }; + }; + khscodes.infrastructure.vault-server-approle = { + enable = true; + policy = [ + { + "${cloudflareSecret}" = { + capabilities = [ "read" ]; + }; + } + ]; + }; + khscodes.services.vault-agent = (cfg.dns01Enabled && acmeServicesToRestart != [ ]) { + enable = true; + templates = [ + { + contents = '' + {{- with secret "${cloudflareSecret}" -}} + CLOUDFLARE_DNS_API_TOKEN={{ .Data.data.TF_VAR_cloudflare_token }} + CLOUDFLARE_DNS_EMAIL={{ .Data.data.TF_VAR_cloudflare_email }} + {{- end -}} + ''; + destination = vaultAgentCredentialsFile; + perms = "0600"; + owner = "acme"; + group = "acme"; + restartUnits = acmeServicesToRestart; + } + ]; + }; + }; +} diff --git a/nix/modules/nixos/services/nginx/default.nix b/nix/modules/nixos/services/nginx/default.nix new file mode 100644 index 0000000..dfb1dd5 --- /dev/null +++ b/nix/modules/nixos/services/nginx/default.nix @@ -0,0 +1,41 @@ +{ + config, + lib, + pkgs, + ... +}: +let + cfg = config.khscodes.services.nginx; + vhostOption = lib.khscodes.mkSubmodule { + description = "nginx vhost"; + options = { + useACMEHost = lib.mkOption { + type = lib.types.nullOr lib.types.str; + description = "Makes the virtual host use the certificate of another acme host"; + }; + }; + }; +in +{ + options.khscodes.services.nginx = { + enable = lib.mkEnableOption "Enables nginx"; + virtualHosts = lib.mkOption { + type = lib.types.attrsOf vhostOption; + description = "Virtual hosts settings"; + default = { }; + }; + }; + config = lib.mkIf cfg.enable { + khscodes.security.acme.enable = true; + services.nginx = { + enable = true; + package = lib.mkDefault pkgs.nginxStable; + sslDhparam = lib.mkDefault "${config.security.dhparams.params."nginx".path}"; + recommendedTlsSettings = lib.mkDefault true; + recommendedGzipSettings = lib.mkDefault true; + recommendedOptimisation = lib.mkDefault true; + recommendedZstdSettings = lib.mkDefault true; + recommendedProxySettings = lib.mkDefault true; + }; + }; +} diff --git a/nix/modules/nixos/services/openstack-read-vault-auth-from-userdata/default.nix b/nix/modules/nixos/services/openstack-read-vault-auth-from-userdata/default.nix index 480c60e..4e4135e 100644 --- a/nix/modules/nixos/services/openstack-read-vault-auth-from-userdata/default.nix +++ b/nix/modules/nixos/services/openstack-read-vault-auth-from-userdata/default.nix @@ -19,6 +19,7 @@ in roleIdFilePath = config.khscodes.services.vault-agent.vault.roleIdFilePath; in { + services.khscodes.vault-agent.enable = true; systemd.services."openstack-read-vault-auth-from-userdata" = { enable = true; wantedBy = [ "multi-user.target" ]; diff --git a/nix/modules/nixos/services/vault-agent/default.nix b/nix/modules/nixos/services/vault-agent/default.nix index 2b88c6a..ac5db94 100644 --- a/nix/modules/nixos/services/vault-agent/default.nix +++ b/nix/modules/nixos/services/vault-agent/default.nix @@ -34,6 +34,7 @@ let name = "restart-command"; runtimeInputs = [ pkgs.systemd ]; text = '' + chown ${lib.escapeShellArg template.owner}:${lib.escapeShellArg template.group} ${lib.escapeShellArg template.destination} ${restartUnits template.restartUnits} ${reloadOrRestartUnits template.reloadOrRestartUnits} ${template.exec} @@ -133,6 +134,16 @@ in description = "Permissions of the generated file, by default will only be readable by root"; default = "0600"; }; + owner = lib.mkOption { + type = lib.types.str; + description = "Owner (user) of the generated file"; + default = "root"; + }; + group = lib.mkOption { + type = lib.types.str; + description = "Group of the generated file"; + default = "root"; + }; exec = lib.mkOption { type = lib.types.lines; default = '''';