blob: d90f4dd47f21b0c85f1440a2b4cf155f047473ea [file] [log] [blame]
Skyler Greyd7e1acd2024-06-22 14:42:11 +00001# SPDX-FileCopyrightText: 2024 Clicks Codes
2#
3# SPDX-License-Identifier: GPL-3.0-only
4
5{ lib, config, ... }:
6let
7 cfg = config.clicks.services.nginx;
8in
9{
10 options.clicks.services.nginx = {
11 enable = lib.mkEnableOption "Enable Nginx routing";
12 hosts = lib.options.mkOption {
13 type = lib.types.attrsOf (lib.clicks.types.nginx.host config);
14 description = "Attrset of web domain to host data";
15 default = {};
16 };
17 defaultDnsProvider = lib.options.mkOption {
18 type = lib.types.nullOr lib.types.str;
19 description = "Default provider for getting web certificates";
20 default = null;
21 };
Skyler Greyd7e1acd2024-06-22 14:42:11 +000022 };
23
24 config = lib.modules.mkIf cfg.enable (let
25 processedHosts = lib.clicks.nginx.http.internal.serviceTranslation cfg.hosts;
26 hostsList = lib.attrsets.attrsToList processedHosts;
27 nginxHosts = lib.attrsets.mapAttrs (_: host: lib.attrsets.removeAttrs host [ "authWith" "dnsProvider" ]) processedHosts;
Skyler Grey41237592024-08-08 22:07:15 +000028 acmeCerts = lib.attrsets.mapAttrs (name: host: {
Skyler Greyd7e1acd2024-06-22 14:42:11 +000029 inherit (host) dnsProvider;
Skyler Grey7e63dd52024-08-08 21:15:49 +000030 webroot = if host.dnsProvider != null
31 then null
Skyler Grey41237592024-08-08 22:07:15 +000032 else if (config.services.nginx.virtualHosts.${name}.acmeRoot or null) != null
33 then config.services.nginx.virtualHosts.${name}.acmeRoot
Skyler Grey7e63dd52024-08-08 21:15:49 +000034 else config.security.acme.defaults.webroot;
Skyler Greyd7e1acd2024-06-22 14:42:11 +000035 }) processedHosts;
36 tailscaleAuthHosts = lib.pipe hostsList [
37 (lib.lists.filter (host: host.value.authWith == "tailscale"))
38 (map (host: host.name))
39 ];
40 in {
41 services.nginx = {
42 enable = true;
43 enableReload = true;
44 virtualHosts = {
45 "default_server_ssl" = {
46 listen = [
47 {
48 ssl = true;
49 port = 443;
50 addr = "0.0.0.0";
51 extraParameters = [
52 "default_server"
53 ];
54 }
55 ];
56
57 rejectSSL = true;
58 };
59 "default_server" = {
60 listen = [
61 {
62 port = 80;
63 addr = "0.0.0.0";
64 extraParameters = [
65 "default_server"
66 ];
67 }
68 ];
69
70 locations."/" = {
71 return = 444;
72 };
73 };
74 } // nginxHosts;
75 };
76
77 security.acme.certs = acmeCerts;
78
79 clicks.services.tailscaleAuth = lib.mkIf (lib.lists.length tailscaleAuthHosts > 0) {
80 enable = true;
81
82 hosts = tailscaleAuthHosts;
83 };
84
85 networking.firewall.allowedTCPPorts = [ 80 443 ];
86 });
87}