diff --git a/lib/default.nix b/lib/default.nix index 3c22d83..ab24160 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -36,17 +36,11 @@ rec { mkVPNSubdomain = name: port: { luj.nginx.enable = true; - security.acme.certs."${name}.luj".server = "https://ca.luj/acme/acme/directory"; services.nginx.virtualHosts."${name}.luj" = { forceSSL = true; enableACME = true; locations."/" = { proxyPass = "http://localhost:${toString port}"; - extraConfig = '' - allow 100.100.45.0/24; - allow fd7a:115c:a1e0::/48; - deny all; - ''; }; }; }; diff --git a/lib/dns.nix b/lib/dns.nix index f3eca85..2de84b6 100644 --- a/lib/dns.nix +++ b/lib/dns.nix @@ -4,6 +4,16 @@ with lib; rec { + allowedDomains = [ + "luj.fr" + "julienmalka.me" + "malka.family" + "luj" + "malka.sh" + ]; + + isVPNDomain = hasSuffix "luj"; + hasSuffix' = flip strings.hasSuffix; domainToZone = allowedDomains: domain: (findFirst (hasSuffix' domain) null allowedDomains); diff --git a/modules/dns/default.nix b/modules/dns/default.nix index d0ed934..de36687 100644 --- a/modules/dns/default.nix +++ b/modules/dns/default.nix @@ -1,20 +1,9 @@ { lib, - config, dnsLib, ... }: let - cfg = config.machine.meta; - allowedDomains = [ - "luj.fr" - "julienmalka.me" - "malka.family" - "luj" - "malka.sh" - ]; - - isVPNDomain = domain: lib.dns.domainToZone [ "luj" ] domain != null; SOA = { nameServer = "ns"; adminEmail = "dns@malka.sh"; @@ -57,27 +46,4 @@ with lib; }; }; - config = - let - # list of domains that are defined in the current configuration through virtualHosts - domains = dns.domainsFromConfiguration allowedDomains config; - # AttrSet domain -> { records } - recordsPerDomain = map ( - domain: - mapAttrs' ( - n: v: - nameValuePair (dns.domainToZone allowedDomains n) ( - let - subdomain = dns.getDomainPrefix allowedDomains n; - in - if elem subdomain allowedDomains then v else { subdomains."${subdomain}" = v; } - ) - ) (dns.domainToRecords domain cfg (isVPNDomain domain)) - ) domains; - in - - { - machine.meta.zones = mkMerge recordsPerDomain; - }; - } diff --git a/modules/homepage/default.nix b/modules/homepage/default.nix index 6b2e7fa..a12e7d9 100644 --- a/modules/homepage/default.nix +++ b/modules/homepage/default.nix @@ -1,4 +1,9 @@ -{ lib, inputs, config, ... }: +{ + lib, + inputs, + config, + ... +}: with lib; let cfg = config.luj.homepage; @@ -8,21 +13,12 @@ in enable = mkEnableOption "enable homepage"; }; - config = mkIf cfg.enable - { - luj.nginx.enable = true; - services.nginx.virtualHosts."julienmalka.me" = { - enableACME = true; - forceSSL = true; - root = inputs.homepage; - }; - - services.nginx.virtualHosts."www.julienmalka.me" = { - enableACME = true; - forceSSL = true; - root = inputs.homepage; - }; - - + config = mkIf cfg.enable { + luj.nginx.enable = true; + services.nginx.virtualHosts."julienmalka.me" = { + enableACME = true; + forceSSL = true; + root = inputs.homepage; }; + }; } diff --git a/modules/nginx/default.nix b/modules/nginx/default.nix index 106df41..dd48a74 100644 --- a/modules/nginx/default.nix +++ b/modules/nginx/default.nix @@ -1,15 +1,74 @@ -{ lib, config, ... }: +systemArgs@{ lib, config, ... }: with lib; let cfg = config.luj.nginx; + mergeSub = + f: + lib.mkMerge ( + map (sub: f (sub.systemConfig systemArgs)) (lib.attrValues config.services.nginx.virtualHosts) + ); + + recordsFromDomain = + domain: + mapAttrs' ( + n: v: + nameValuePair (dns.domainToZone dns.allowedDomains n) ( + let + subdomain = dns.getDomainPrefix dns.allowedDomains n; + in + if elem subdomain dns.allowedDomains then v else { subdomains."${subdomain}" = v; } + ) + ) (dns.domainToRecords domain config.machine.meta (dns.isVPNDomain domain)); + in { - options.luj.nginx = { - enable = mkEnableOption "activate nginx service"; - email = mkOption { - type = types.str; - default = "julien@malka.sh"; + options = { + luj.nginx = { + enable = mkEnableOption "activate nginx service"; + email = mkOption { + type = types.str; + default = "julien@malka.sh"; + }; + }; + + # Awesome NixOS crimes + services.nginx.virtualHosts = lib.mkOption { + type = lib.types.attrsOf ( + lib.types.submodule ( + { + name, + ... + }: + { + options = { + systemConfig = lib.mkOption { + internal = true; + type = types.unspecified; # A function from module arguments to config. + }; + }; + config = { + locations."/".extraConfig = lib.mkIf (lib.hasSuffix "luj" name) '' + allow 100.100.45.0/24; + allow fd7a:115c:a1e0::/48; + deny all; + ''; + extraConfig = '' + ssl_stapling off; + ''; + + systemConfig = _: { + security.acme.certs = lib.optionalAttrs (hasSuffix "luj" name) { + "${name}".server = lib.mkIf (hasSuffix "luj" name) "https://ca.luj/acme/acme/directory"; + }; + + machine.meta.zones = lib.optionalAttrs (name != "default") (recordsFromDomain name); + + }; + }; + } + ) + ); }; }; @@ -19,8 +78,7 @@ in 80 443 ]; - security.acme.defaults.email = "${cfg.email}"; - security.acme.acceptTerms = true; + users.groups.nginx = { name = "nginx"; }; @@ -35,16 +93,45 @@ in commonHttpConfig = '' server_names_hash_bucket_size 128; ''; - }; - - services.nginx.virtualHosts."404.julienmalka.me" = { - default = true; - locations."/" = { - root = "${./404}"; + virtualHosts.default = { + default = true; + addSSL = true; + enableACME = false; + sslCertificate = "/var/lib/acme/default/cert.pem"; + sslCertificateKey = "/var/lib/acme/default/key.pem"; + extraConfig = '' + return 444; + ''; }; }; - machine.meta.zones."julienmalka.me".subdomains."404" = lib.mkForce { }; + security.acme.certs = mergeSub (c: c.security.acme.certs); + security.acme.defaults.email = "${cfg.email}"; + security.acme.acceptTerms = true; + + age.secrets.nginx-cert = { + file = ../../secrets/404-ssl-certificate-cert.age; + path = "/var/lib/acme/default/cert.pem"; + owner = "acme"; + group = "nginx"; + mode = "0640"; + symlink = false; + }; + + age.secrets.nginx-key = { + file = ../../secrets/404-ssl-certificate-key.age; + path = "/var/lib/acme/default/key.pem"; + owner = "acme"; + group = "nginx"; + mode = "0640"; + symlink = false; + }; + + systemd.tmpfiles.rules = [ + "d /var/lib/acme/default 0750 acme nginx - -" + ]; + + machine = mergeSub (c: c.machine); }; } diff --git a/secrets/404-ssl-certificate-cert.age b/secrets/404-ssl-certificate-cert.age new file mode 100644 index 0000000..9fe1025 Binary files /dev/null and b/secrets/404-ssl-certificate-cert.age differ diff --git a/secrets/404-ssl-certificate-key.age b/secrets/404-ssl-certificate-key.age new file mode 100644 index 0000000..c05d32b Binary files /dev/null and b/secrets/404-ssl-certificate-key.age differ diff --git a/secrets/secrets.nix b/secrets/secrets.nix index 1df5866..32cacc9 100644 --- a/secrets/secrets.nix +++ b/secrets/secrets.nix @@ -94,4 +94,6 @@ in gustave tower ]; + "404-ssl-certificate-cert.age".publicKeys = all; + "404-ssl-certificate-key.age".publicKeys = all; }