Files
nix-config/modules/services/nginx.nix
2025-12-09 16:34:00 +01:00

154 lines
4.9 KiB
Nix

{
config,
pkgs,
lib,
inputs,
...
}:
with lib;
let
cfg = config.custom.services.nginx;
in
{
options.custom.services.nginx = {
enable = mkEnableOption "Enables nginx";
https = mkOption {
type = types.bool;
default = true;
description = "Should it use https?";
};
};
config = lib.mkIf cfg.enable {
networking.firewall.allowedTCPPorts = [
80
443
];
networking.firewall.allowedUDPPorts = [
80
443
];
age.secrets.stash-auth = {
file = ../../secrets/stash-auth.age;
owner = "nginx";
};
systemd.tmpfiles.rules = [
"d /var/www 0740 nginx nginx -"
"d /var/www/misc-files 0740 nginx nginx -"
];
services.nginx = {
enable = true;
additionalModules = [ pkgs.nginxModules.moreheaders ];
# Use recommended settings
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
statusPage = lib.mkIf config.services.prometheus.exporters.nginx.enable true;
# Only allow PFS-enabled ciphers with AES256
sslCiphers = "AES256+EECDH:AES256+EDH:!aNULL";
appendHttpConfig = ''
more_set_headers 'Strict-Transport-Security: max-age=31536000; includeSubDomains';
more_set_headers 'X-XSS-Protection 1; mode=block';
# add_header X-Frame-Options 'ALLOW-FROM kopatz.ddns.net';
more_set_headers 'X-Content-Type-Options nosniff';
more_set_headers "Content-Security-Policy: frame-ancestors https://kopatz.ddns.net https://kop.oasch.net https://kopatz.dev";
more_set_headers "Referrer-Policy: same-origin";
more_set_headers "Permissions-Policy: geolocation=(), microphone=()";
'';
virtualHosts =
let
kopConfig = {
root = pkgs.kop-website;
forceSSL = cfg.https;
enableACME = cfg.https;
quic = cfg.https;
http3 = cfg.https;
locations = {
"~* ^/assets/.*\\.(jpg|png)$".extraConfig = ''
add_header Access-Control-Allow-Origin *;
'';
"/stash" = {
basicAuthFile = config.age.secrets.stash-auth.path;
extraConfig = ''
client_max_body_size 20000M;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://localhost:7777;
'';
};
"/stash/files" = {
extraConfig = ''
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://localhost:7777;
'';
};
"/tracker-site" = {
tryFiles = "$uri $uri/ /tracker-site/index.html =404";
};
"/tracker-site/api" = {
extraConfig = ''
rewrite /tracker-site/api/(.*) /$1 break;
'';
proxyPass = "http://127.0.0.1:8080";
};
"/radicale/" = {
extraConfig = ''
proxy_set_header X-Script-Name /radicale;
'';
proxyPass = "http://localhost:5232/";
};
"/socket.io" = {
proxyPass = "http://localhost:9955";
proxyWebsockets = true;
};
"/comms/" = {
extraConfig = ''
more_set_headers "Permissions-Policy: geolocation=(), microphone=(self), camera=(self)";
'';
alias = "/comms/";
tryFiles = "$uri $uri/ /comms/index.html";
};
"/comms" = {
extraConfig = ''
return 301 /comms/;
'';
};
"/kavita-client" = {
extraConfig = ''
return 301 /kavita-client/;
'';
};
"/kavita-client/" = {
alias = "/kavita-client/";
};
"/misc-files/" = {
alias = "/var/www/misc-files/";
};
};
};
in
{
"kop.oasch.net" = kopConfig;
"kop.bobin.at" = kopConfig;
"kopatz.dev" = kopConfig;
};
};
};
}