2023-07-12 23:36:57 +02:00
|
|
|
{ pkgs, lib, config, secrets, inputs, ... }:
|
2022-10-13 23:42:42 +02:00
|
|
|
{
|
2023-03-08 14:32:39 +01:00
|
|
|
sops.secrets."cloudflare/api-key" = {};
|
2022-10-13 23:42:42 +02:00
|
|
|
|
2023-03-08 14:32:39 +01:00
|
|
|
security.acme = {
|
|
|
|
acceptTerms = true;
|
|
|
|
defaults = {
|
|
|
|
email = "h7x4@nani.wtf";
|
|
|
|
dnsProvider = "cloudflare";
|
|
|
|
credentialsFile = config.sops.secrets."cloudflare/api-key".path;
|
|
|
|
dnsPropagationCheck = true;
|
|
|
|
};
|
|
|
|
certs."nani.wtf" = {
|
|
|
|
extraDomainNames = [ "*.nani.wtf" ];
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
users.groups.${config.security.acme.certs."nani.wtf".group}.members = [ "nginx" ];
|
2022-10-13 23:42:42 +02:00
|
|
|
|
|
|
|
services.nginx = let
|
|
|
|
generateServerAliases =
|
|
|
|
domains: subdomains:
|
|
|
|
lib.lists.flatten (map (s: map (d: "${s}.${d}") domains) subdomains);
|
2023-07-28 21:58:17 +02:00
|
|
|
|
2022-10-13 23:42:42 +02:00
|
|
|
s = toString;
|
|
|
|
in {
|
|
|
|
enable = true;
|
|
|
|
enableReload = true;
|
2023-07-28 21:58:17 +02:00
|
|
|
|
2022-10-13 23:42:42 +02:00
|
|
|
statusPage = true;
|
|
|
|
|
2023-07-28 21:58:17 +02:00
|
|
|
recommendedBrotliSettings = true;
|
2022-10-13 23:42:42 +02:00
|
|
|
recommendedGzipSettings = true;
|
|
|
|
recommendedOptimisation = true;
|
|
|
|
recommendedProxySettings = true;
|
|
|
|
recommendedTlsSettings = true;
|
2023-07-28 21:58:17 +02:00
|
|
|
recommendedZstdSettings = true;
|
2022-10-13 23:42:42 +02:00
|
|
|
|
2023-07-28 21:58:17 +02:00
|
|
|
upstreams = let
|
|
|
|
inherit (secrets) ips ports;
|
|
|
|
srv = config.services;
|
2023-07-28 21:50:38 +02:00
|
|
|
sa = config.local.socketActivation;
|
2023-07-28 21:58:17 +02:00
|
|
|
in {
|
2023-10-06 13:43:24 +02:00
|
|
|
"atuin".servers."unix:${sa.atuin.newSocketAddress}" = { };
|
2023-07-12 23:36:57 +02:00
|
|
|
"dynmap".servers."localhost:${s ports.minecraft.dynmap}" = { };
|
|
|
|
"grafana".servers."unix:/run/grafana/grafana.sock" = { };
|
2023-07-28 21:58:17 +02:00
|
|
|
"headscale".servers."localhost:${s srv.headscale.port}" = { };
|
|
|
|
"hedgedoc".servers."unix:${srv.hedgedoc.settings.path}" = { };
|
2023-07-12 23:36:57 +02:00
|
|
|
"idrac".servers."${ips.idrac}" = { };
|
2023-10-06 13:48:52 +02:00
|
|
|
"invidious".servers."unix:${sa.invidious.newSocketAddress}" = { };
|
2023-07-12 23:36:57 +02:00
|
|
|
"kanidm".servers."localhost:8300" = { };
|
2023-07-28 21:50:38 +02:00
|
|
|
"navidrome".servers."unix:${sa.navidrome.newSocketAddress}" = { };
|
2023-07-12 23:36:57 +02:00
|
|
|
"osuchan".servers."localhost:${s ports.osuchan}" = { };
|
|
|
|
"plex".servers."localhost:${s ports.plex}" = { };
|
2023-10-06 13:42:11 +02:00
|
|
|
"vaultwarden".servers."unix:${sa.vaultwarden.newSocketAddress}" = { };
|
2023-07-12 23:36:57 +02:00
|
|
|
};
|
|
|
|
|
2022-10-13 23:42:42 +02:00
|
|
|
virtualHosts = let
|
|
|
|
inherit (lib.attrsets) nameValuePair listToAttrs recursiveUpdate;
|
|
|
|
inherit (lib.lists) head drop;
|
|
|
|
inherit (secrets) domains keys;
|
|
|
|
|
|
|
|
cloudflare-origin-pull-ca = builtins.fetchurl {
|
|
|
|
url = "https://developers.cloudflare.com/ssl/static/authenticated_origin_pull_ca.pem";
|
|
|
|
sha256 = "0hxqszqfzsbmgksfm6k0gp0hsx9k1gqx24gakxqv0391wl6fsky1";
|
|
|
|
};
|
|
|
|
|
|
|
|
host =
|
|
|
|
subdomains: extraSettings: let
|
|
|
|
settings = with keys.certificates; {
|
|
|
|
serverAliases = drop 1 (generateServerAliases domains subdomains);
|
2023-03-08 14:32:39 +01:00
|
|
|
useACMEHost = "nani.wtf";
|
|
|
|
forceSSL = true;
|
2023-07-28 21:58:17 +02:00
|
|
|
kTLS = true;
|
2022-10-13 23:42:42 +02:00
|
|
|
|
|
|
|
extraConfig = ''
|
|
|
|
ssl_client_certificate ${cloudflare-origin-pull-ca};
|
|
|
|
ssl_verify_client on;
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
in
|
|
|
|
nameValuePair "${head subdomains}.${head domains}" (recursiveUpdate settings extraSettings);
|
|
|
|
|
|
|
|
proxy =
|
|
|
|
subdomains: url: extraSettings:
|
|
|
|
host subdomains (recursiveUpdate { locations."/".proxyPass = url; } extraSettings);
|
|
|
|
|
2023-07-12 23:36:57 +02:00
|
|
|
enableWebsockets = { locations."/".proxyWebsockets = true; };
|
2023-01-03 22:45:41 +01:00
|
|
|
in (listToAttrs ([
|
2022-10-13 23:42:42 +02:00
|
|
|
{
|
|
|
|
name = "nani.wtf";
|
|
|
|
value = {
|
|
|
|
locations = {
|
2022-11-08 14:28:59 +01:00
|
|
|
"= /".return = "301 https://www.nani.wtf/";
|
2022-10-13 23:42:42 +02:00
|
|
|
"/.well-known/".alias = "${./well-known}/";
|
|
|
|
"/.well-known/openpgpkey/hu/" = {
|
|
|
|
alias = "${./well-known/openpgpkey/hu}/";
|
|
|
|
extraConfig = ''
|
|
|
|
default_type application/octet-stream;
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2023-03-08 14:32:39 +01:00
|
|
|
useACMEHost = "nani.wtf";
|
|
|
|
forceSSL = true;
|
2022-10-13 23:42:42 +02:00
|
|
|
|
|
|
|
extraConfig = ''
|
|
|
|
add_header Access-Control-Allow-Origin *;
|
|
|
|
default_type text/plain;
|
2023-03-08 14:32:39 +01:00
|
|
|
ssl_client_certificate ${cloudflare-origin-pull-ca};
|
|
|
|
ssl_verify_client on;
|
2022-10-13 23:42:42 +02:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
}
|
2023-07-12 01:39:50 +02:00
|
|
|
# (host ["www"] { root = "${inputs.website.packages.${pkgs.system}.default}/"; })
|
|
|
|
(host ["www"] {
|
|
|
|
locations."/" = {
|
|
|
|
tryFiles = "$uri /index.html";
|
2023-07-12 23:36:57 +02:00
|
|
|
root = pkgs.writeTextDir "index.html" (lib.fileContents ./temp-website.html);
|
2023-07-12 01:39:50 +02:00
|
|
|
};
|
|
|
|
})
|
2023-07-12 23:36:57 +02:00
|
|
|
# (proxy ["matrix"] "http://localhost:${s ports.matrix.listener}" {})
|
|
|
|
(host ["matrix"] {
|
|
|
|
enableACME = lib.mkForce false;
|
|
|
|
locations."/_synapse".proxyPass = "http://$synapse_backend";
|
2023-07-12 01:35:47 +02:00
|
|
|
})
|
2023-07-12 23:36:57 +02:00
|
|
|
(host ["madmin"] { root = "${pkgs.synapse-admin}/"; })
|
|
|
|
# This one gets properly configured by the nextcloud module itself.
|
|
|
|
# It just needs the cloudflare and SSL settings.
|
|
|
|
(host ["cloud"] {})
|
|
|
|
# (host ["cache"] { root = "/var/lib/nix-cache"; })
|
|
|
|
# (proxy ["slack-bot"] "http://localhost:9898" {})
|
|
|
|
(proxy ["atuin"] "http://atuin" {})
|
|
|
|
(proxy ["auth"] "https://kanidm" { extraConfig = "proxy_ssl_verify off;"; })
|
|
|
|
(proxy ["bw"] "http://vaultwarden" {})
|
|
|
|
(proxy ["docs"] "http://hedgedoc" {})
|
2024-06-09 15:49:03 +02:00
|
|
|
(host ["git"] {
|
|
|
|
locations."/".extraConfig = ''
|
|
|
|
location /h7x4 {
|
|
|
|
location ~ /h7x4/(?<project>[a-zA-Z0-9\./_-]*) {
|
|
|
|
return 301 $scheme://git.pvv.ntnu.no/oysteikt/$project;
|
|
|
|
}
|
|
|
|
return 301 $scheme://git.pvv.ntnu.no/oysteikt/;
|
|
|
|
}
|
|
|
|
location ~ /[Ss]chool[Ww]ork {
|
|
|
|
location ~ /[Ss]chool[Ww]ork/(?<project>[a-zA-Z0-9\./_-]*) {
|
|
|
|
return 301 $scheme://git.pvv.ntnu.no/oysteikt-skolearbeid/$project;
|
|
|
|
}
|
|
|
|
return 301 $scheme://git.pvv.ntnu.no/oysteikt-skolearbeid/;
|
|
|
|
}
|
|
|
|
return 301 $scheme://git.pvv.ntnu.no$request_uri;
|
|
|
|
'';
|
|
|
|
})
|
2023-07-12 23:36:57 +02:00
|
|
|
(proxy ["idrac"] "https://idrac" {})
|
|
|
|
(proxy ["log"] "http://grafana" enableWebsockets)
|
|
|
|
(proxy ["map"] "http://dynmap" {})
|
|
|
|
(proxy ["osu"] "http://osuchan" {})
|
|
|
|
(proxy ["plex"] "http://plex" {})
|
2023-07-28 21:50:38 +02:00
|
|
|
(proxy ["mus"] "http://navidrome" enableWebsockets)
|
2023-07-12 23:36:57 +02:00
|
|
|
(proxy ["vpn"] "http://headscale" enableWebsockets)
|
|
|
|
(proxy ["yt"] "http://invidious" {})
|
2023-10-06 13:25:45 +02:00
|
|
|
|
|
|
|
(host ["h7x4-stickers"] {})
|
|
|
|
(host ["pingu-stickers"] {})
|
|
|
|
]));
|
2023-07-12 23:36:57 +02:00
|
|
|
|
|
|
|
streamConfig = ''
|
|
|
|
server {
|
|
|
|
listen 0.0.0.0:53589;
|
|
|
|
listen [::0]:53589;
|
|
|
|
proxy_pass localhost:${s config.services.taskserver.listenPort};
|
|
|
|
}
|
|
|
|
'';
|
2022-10-13 23:42:42 +02:00
|
|
|
};
|
|
|
|
|
2023-07-12 23:36:57 +02:00
|
|
|
# NOTE: This is needed for nginx to be able
|
|
|
|
# to connect to sockets in /run
|
|
|
|
systemd.services.nginx.serviceConfig.ProtectHome = false;
|
|
|
|
|
2022-10-13 23:42:42 +02:00
|
|
|
networking.firewall.allowedTCPPorts = [
|
|
|
|
80
|
|
|
|
443
|
|
|
|
];
|
|
|
|
}
|