Refactored how SSL certs are configured for nginx
Made a separate ACME module to handle requesting certs from multiple machines. Right now, the module only supports exactly one wildcard cert. It might make sense to have cache.kilonull.com use a cert specific to its subdomain rather than also requesting a wildcard cert (or maybe the nginx on its host shouldn't care about TLS and it should be node's responsibility).
This commit is contained in:
parent
60917107b1
commit
d5969ca923
|
@ -7,7 +7,7 @@
|
|||
}:
|
||||
with lib; let
|
||||
cfg = config.aa.nix;
|
||||
selfHostedCacheHost = "http://192.168.113.69/";
|
||||
selfHostedCacheHost = "https://cache.kilonull.com/";
|
||||
in {
|
||||
options.aa.nix = with types; {
|
||||
enable = mkEnableOption "manage nix configuration.";
|
||||
|
|
56
modules/security/acme/default.nix
Normal file
56
modules/security/acme/default.nix
Normal file
|
@ -0,0 +1,56 @@
|
|||
{
|
||||
options,
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
format,
|
||||
...
|
||||
}:
|
||||
with lib; let
|
||||
cfg = config.aa.security.acme;
|
||||
in {
|
||||
options.aa.security.acme = with types; {
|
||||
enable = mkEnableOption "Automatic Certificate Management Environment (ACME)";
|
||||
useStaging = mkOption {
|
||||
type = bool;
|
||||
description = ''
|
||||
Use the staging environment (use when configuring for the first time to
|
||||
avoid being locked out).
|
||||
'';
|
||||
default = false;
|
||||
};
|
||||
domainName = mkOption {
|
||||
type = str;
|
||||
description = "The domain to request a wildcard cert for.";
|
||||
};
|
||||
dnsCredentialsFile = mkOption {
|
||||
type = path;
|
||||
description = "The path to the credentials file for the DNS provider.";
|
||||
};
|
||||
};
|
||||
|
||||
# Only supports exactly one wildcard cert using Cloudflare (only use case I have)
|
||||
config = mkIf cfg.enable {
|
||||
security.acme = {
|
||||
acceptTerms = true;
|
||||
defaults = {
|
||||
email = config.aa.user.email;
|
||||
group = "nginx";
|
||||
server = mkIf cfg.useStaging "https://acme-staging-v02.api.letsencrypt.org/directory";
|
||||
};
|
||||
|
||||
# Wildcard cert
|
||||
certs."${cfg.domainName}" = {
|
||||
group = "nginx";
|
||||
dnsProvider = "cloudflare";
|
||||
# Private network resolves *.kilonull.com to private servers but `lego`
|
||||
# (acme client under the hood) needs to find the cloudflare nameservers
|
||||
# to determine the correct zone to apply changes in. Use cloudflare's
|
||||
# own DNS to make `lego` happy (will resolve names to a public IP).
|
||||
dnsResolver = "1.1.1.1:53";
|
||||
credentialsFile = cfg.dnsCredentialsFile;
|
||||
extraDomainNames = [("*." + cfg.domainName)];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -11,6 +11,14 @@ with lib; let
|
|||
in {
|
||||
options.aa.services.adguardhome = with types; {
|
||||
enable = mkEnableOption "adguardhome";
|
||||
acmeCertName = mkOption {
|
||||
type = str;
|
||||
default = "";
|
||||
description = ''
|
||||
If set to a non-empty string, forces SSL with the supplied acme
|
||||
certificate.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
@ -26,37 +34,16 @@ in {
|
|||
services.nginx = {
|
||||
enable = true;
|
||||
recommendedProxySettings = true;
|
||||
virtualHosts."adguardhome.kilonull.com" = {
|
||||
forceSSL = true;
|
||||
useACMEHost = "kilonull.com";
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:3000";
|
||||
virtualHosts."adguardhome.kilonull.com" =
|
||||
{
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:3000";
|
||||
};
|
||||
}
|
||||
// lib.optionalAttrs (cfg.acmeCertName != "") {
|
||||
forceSSL = true;
|
||||
useACMEHost = cfg.acmeCertName;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# So that nginx has access to the ACME certs
|
||||
users.users.nginx.extraGroups = ["acme"];
|
||||
|
||||
age.secrets.cf_dns_kilonull.file = ../../../secrets/cf_dns_kilonull.age;
|
||||
|
||||
security.acme = {
|
||||
# NOTE: Uncomment line below when testing changes
|
||||
# defaults.server = "https://acme-staging-v02.api.letsencrypt.org/directory";
|
||||
acceptTerms = true;
|
||||
defaults.email = "iam@alejandr0angul0.dev";
|
||||
|
||||
# Wildcard cert
|
||||
certs."kilonull.com" = {
|
||||
dnsProvider = "cloudflare";
|
||||
# Private network resolves *.kilonull.com to private servers but `lego`
|
||||
# (acme client under the hood) needs to find the cloudflare nameservers
|
||||
# to determine the correct zone to apply changes in. Use cloudflare's
|
||||
# own DNS to make `lego` happy (will resolve names to a public IP).
|
||||
dnsResolver = "1.1.1.1:53";
|
||||
credentialsFile = config.age.secrets.cf_dns_kilonull.path;
|
||||
extraDomainNames = ["*.kilonull.com"];
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall = {
|
||||
|
|
|
@ -11,6 +11,14 @@ with lib; let
|
|||
in {
|
||||
options.aa.services.nextcloud = with types; {
|
||||
enable = mkEnableOption "nextcloud";
|
||||
acmeCertName = mkOption {
|
||||
type = str;
|
||||
default = "";
|
||||
description = ''
|
||||
If set to a non-empty string, forces SSL with the supplied acme
|
||||
certificate.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
@ -47,9 +55,9 @@ in {
|
|||
};
|
||||
|
||||
# nextcloud module configures nginx, just need to specify SSL stuffs here
|
||||
services.nginx.virtualHosts.${config.services.nextcloud.hostName} = {
|
||||
services.nginx.virtualHosts.${config.services.nextcloud.hostName} = mkIf (cfg.acmeCertName != "") {
|
||||
forceSSL = true;
|
||||
useACMEHost = "kilonull.com";
|
||||
useACMEHost = cfg.acmeCertName;
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [80 443];
|
||||
|
|
|
@ -19,6 +19,14 @@ in {
|
|||
type = str;
|
||||
description = "The subdomain to use.";
|
||||
};
|
||||
acmeCertName = mkOption {
|
||||
type = str;
|
||||
default = "";
|
||||
description = ''
|
||||
If set to a non-empty string, forces SSL with the supplied acme
|
||||
certificate.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
@ -38,8 +46,8 @@ in {
|
|||
|
||||
nginx = {
|
||||
enable = true;
|
||||
virtualHosts = {
|
||||
"${cfg.subdomain_name}.${cfg.domain_name}" = {
|
||||
virtualHosts."${cfg.subdomain_name}.${cfg.domain_name}" =
|
||||
{
|
||||
serverAliases = ["${cfg.subdomain_name}"];
|
||||
locations."/".extraConfig = ''
|
||||
proxy_pass http://localhost:${toString config.services.nix-serve.port};
|
||||
|
@ -47,13 +55,16 @@ in {
|
|||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
'';
|
||||
}
|
||||
// lib.optionalAttrs (cfg.acmeCertName != "") {
|
||||
forceSSL = true;
|
||||
useACMEHost = cfg.acmeCertName;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall = {
|
||||
allowedTCPPorts = [80];
|
||||
allowedTCPPorts = [80 443];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
Binary file not shown.
|
@ -2,8 +2,9 @@ let
|
|||
# Remember to pass '--identity identities/me.txt` when using this key
|
||||
users.me = "age1yubikey1qdwgvfqrcqmyw56ux7azuvqr6f8nanszu27nztvxmn4utmplgxctzt90g25";
|
||||
|
||||
machines.gospel = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGDzjXVoQEfO9JIcFbp56EvQ0oBdr9Cmhxp4z0ih+ZEZ";
|
||||
machines.node = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIETLBnc8kJokmFiA28BaSYpeE7flY1W0SM5C1pWv/tOv";
|
||||
in {
|
||||
"cf_dns_kilonull.age".publicKeys = [users.me machines.node];
|
||||
"cf_dns_kilonull.age".publicKeys = [users.me machines.node machines.gospel];
|
||||
"nextcloud_admin.age".publicKeys = [users.me machines.node];
|
||||
}
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
./zfs.nix
|
||||
];
|
||||
|
||||
age.secrets.cf_dns_kilonull.file = ../../../secrets/cf_dns_kilonull.age;
|
||||
|
||||
aa = {
|
||||
nix.enable = true;
|
||||
|
||||
|
@ -19,11 +21,19 @@
|
|||
|
||||
apps.yubikey.enable = true;
|
||||
|
||||
security.acme = {
|
||||
enable = true;
|
||||
# useStaging = true;
|
||||
domainName = "kilonull.com";
|
||||
dnsCredentialsFile = config.age.secrets.cf_dns_kilonull.path;
|
||||
};
|
||||
|
||||
services.openssh.enable = true;
|
||||
services.nix-serve = {
|
||||
enable = true;
|
||||
domain_name = "kilonull.com";
|
||||
subdomain_name = "gospel";
|
||||
subdomain_name = "cache";
|
||||
acmeCertName = "kilonull.com";
|
||||
};
|
||||
services.printing.enable = true;
|
||||
services.tailscale = {
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
./zfs.nix
|
||||
];
|
||||
|
||||
age.secrets.cf_dns_kilonull.file = ../../../secrets/cf_dns_kilonull.age;
|
||||
|
||||
aa = {
|
||||
nix.enable = true;
|
||||
nix.useSelfhostedCache = true;
|
||||
|
@ -18,8 +20,20 @@
|
|||
configureServerRouting = true;
|
||||
};
|
||||
services.openssh.enable = true;
|
||||
services.adguardhome.enable = true;
|
||||
services.nextcloud.enable = true;
|
||||
services.adguardhome = {
|
||||
enable = true;
|
||||
acmeCertName = "kilonull.com";
|
||||
};
|
||||
services.nextcloud = {
|
||||
enable = true;
|
||||
acmeCertName = "kilonull.com";
|
||||
};
|
||||
|
||||
security.acme = {
|
||||
enable = true;
|
||||
domainName = "kilonull.com";
|
||||
dnsCredentialsFile = config.age.secrets.cf_dns_kilonull.path;
|
||||
};
|
||||
|
||||
system.zfs.enable = true;
|
||||
system.monitoring.enable = true;
|
||||
|
|
Loading…
Reference in a new issue