blob: 90d6405d90f77cc2b12362b339661a20364ae015 [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 };
22 xClacksOverhead.enable = lib.options.mkOption {
23 type = lib.types.bool;
24 description = "Write the header `X-Clacks-Overhead: GNU Terry Pratchett` on all virtual host locations";
25 default = true;
26 };
27 };
28
29 config = lib.modules.mkIf cfg.enable (let
30 processedHosts = lib.clicks.nginx.http.internal.serviceTranslation cfg.hosts;
31 hostsList = lib.attrsets.attrsToList processedHosts;
32 nginxHosts = lib.attrsets.mapAttrs (_: host: lib.attrsets.removeAttrs host [ "authWith" "dnsProvider" ]) processedHosts;
33 acmeCerts = lib.attrsets.mapAttrs (_: host: {
34 inherit (host) dnsProvider;
35 webroot = if host.dnsProvider == null
36 then config.security.acme.defaults.webroot
37 else null;
38 }) processedHosts;
39 tailscaleAuthHosts = lib.pipe hostsList [
40 (lib.lists.filter (host: host.value.authWith == "tailscale"))
41 (map (host: host.name))
42 ];
43 in {
44 services.nginx = {
45 enable = true;
46 enableReload = true;
47 virtualHosts = {
48 "default_server_ssl" = {
49 listen = [
50 {
51 ssl = true;
52 port = 443;
53 addr = "0.0.0.0";
54 extraParameters = [
55 "default_server"
56 ];
57 }
58 ];
59
60 rejectSSL = true;
61 };
62 "default_server" = {
63 listen = [
64 {
65 port = 80;
66 addr = "0.0.0.0";
67 extraParameters = [
68 "default_server"
69 ];
70 }
71 ];
72
73 locations."/" = {
74 return = 444;
75 };
76 };
77 } // nginxHosts;
78 };
79
80 security.acme.certs = acmeCerts;
81
82 clicks.services.tailscaleAuth = lib.mkIf (lib.lists.length tailscaleAuthHosts > 0) {
83 enable = true;
84
85 hosts = tailscaleAuthHosts;
86 };
87
88 networking.firewall.allowedTCPPorts = [ 80 443 ];
89 });
90}