Jack O'Sullivan
4e2c2f92f0
Some checks failed
CI / Check, build and cache Nix flake (push) Failing after 6m29s
502 lines
14 KiB
Nix
502 lines
14 KiB
Nix
{ lib, pkgs, config, ... }:
|
|
let
|
|
inherit (builtins) mapAttrs toJSON;
|
|
inherit (lib) mkMerge mkDefault genAttrs flatten concatStringsSep;
|
|
inherit (lib.my.c) pubDomain home;
|
|
inherit (lib.my.c.nginx) proxyHeaders;
|
|
inherit (config.networking) domain;
|
|
|
|
dualStackListen' = l: map (addr: l // { inherit addr; }) [ "0.0.0.0" "[::]" ];
|
|
dualStackListen = ll: flatten (map dualStackListen' ll);
|
|
|
|
ssoServer = i: {
|
|
extraConfig = ''
|
|
include /etc/nginx/includes/sso/server-${i}.conf;
|
|
'';
|
|
};
|
|
ssoLoc = i: {
|
|
extraConfig = ''
|
|
include /etc/nginx/includes/sso/location-${i}.conf;
|
|
'';
|
|
};
|
|
|
|
mkWellKnown = type: content: pkgs.writeTextFile {
|
|
name = "well-known-${type}";
|
|
destination = "/${type}";
|
|
text = content;
|
|
};
|
|
wellKnownRoot = pkgs.symlinkJoin {
|
|
name = "http-wellknown";
|
|
paths = [
|
|
# For federation
|
|
(mkWellKnown "matrix/server" (toJSON {
|
|
"m.server" = "matrix.nul.ie:443";
|
|
}))
|
|
# For clients
|
|
(mkWellKnown "matrix/client" (toJSON {
|
|
"m.homeserver".base_url = "https://matrix.nul.ie";
|
|
}))
|
|
];
|
|
};
|
|
wellKnown = {
|
|
"/.well-known/" = {
|
|
alias = "${wellKnownRoot}/";
|
|
extraConfig = ''
|
|
autoindex on;
|
|
add_header Access-Control-Allow-Origin *;
|
|
'';
|
|
};
|
|
"/.well-known/webfinger".return = "301 https://toot.nul.ie$request_uri";
|
|
"/.well-known/nodeinfo".return = "301 https://toot.nul.ie$request_uri";
|
|
"/.well-known/host-meta".return = "301 https://toot.nul.ie$request_uri";
|
|
};
|
|
in
|
|
{
|
|
my = {
|
|
nginx-sso.includes.instances = {
|
|
generic = {};
|
|
};
|
|
};
|
|
|
|
services.nginx.virtualHosts =
|
|
let
|
|
hosts = {
|
|
"_" = {
|
|
default = true;
|
|
forceSSL = true;
|
|
onlySSL = false;
|
|
locations = mkMerge [
|
|
{
|
|
"/".root = pkgs.linkFarm "nginx-root" [
|
|
{
|
|
name = "index.html";
|
|
path = ./default.html;
|
|
}
|
|
{
|
|
name = "cv.pdf";
|
|
path = builtins.fetchurl {
|
|
url = "https://github.com/devplayer0/cvos/releases/download/v0.1.3/bootable.pdf";
|
|
sha256 = "018wh6ps19n7323fi44njzj9yd4wqslc90dykbwfyscv7bgxhlar";
|
|
};
|
|
}
|
|
];
|
|
}
|
|
wellKnown
|
|
];
|
|
useACMEHost = pubDomain;
|
|
};
|
|
"localhost" = {
|
|
forceSSL = false;
|
|
onlySSL = false;
|
|
locations = {
|
|
"/status".extraConfig = ''
|
|
access_log off;
|
|
allow 127.0.0.1;
|
|
allow ::1;
|
|
deny all;
|
|
|
|
vhost_traffic_status_display;
|
|
vhost_traffic_status_display_format html;
|
|
'';
|
|
};
|
|
};
|
|
|
|
"sso.${pubDomain}" = {
|
|
locations."/".proxyPass = config.my.nginx-sso.includes.endpoint;
|
|
useACMEHost = pubDomain;
|
|
};
|
|
|
|
"netdata-colony.${pubDomain}" =
|
|
let
|
|
hosts = [
|
|
"vm"
|
|
"fw" "ctr" "oci"
|
|
"http" "jackflix-ctr" "chatterbox-ctr" "colony-psql-ctr"
|
|
];
|
|
matchHosts = concatStringsSep "|" hosts;
|
|
in
|
|
mkMerge [
|
|
{
|
|
locations = {
|
|
"= /".return = "301 https://$host/vm/";
|
|
"~ /(?<behost>${matchHosts})$".return = "301 https://$host/$behost/";
|
|
"~ /(?<behost>${matchHosts})/(?<ndpath>.*)" = mkMerge [
|
|
{
|
|
proxyPass = "http://$behost.${domain}:19999/$ndpath$is_args$args";
|
|
extraConfig = ''
|
|
proxy_pass_request_headers on;
|
|
${proxyHeaders}
|
|
proxy_set_header Connection "keep-alive";
|
|
proxy_store off;
|
|
|
|
gzip on;
|
|
gzip_proxied any;
|
|
gzip_types *;
|
|
'';
|
|
}
|
|
(ssoLoc "generic")
|
|
];
|
|
};
|
|
useACMEHost = pubDomain;
|
|
}
|
|
(ssoServer "generic")
|
|
];
|
|
|
|
"pass.${pubDomain}" =
|
|
let
|
|
upstream = "http://vaultwarden-ctr.${domain}:8080";
|
|
in
|
|
{
|
|
locations = {
|
|
"/".proxyPass = upstream;
|
|
"/notifications/hub" = {
|
|
proxyPass = upstream;
|
|
proxyWebsockets = true;
|
|
extraConfig = proxyHeaders;
|
|
};
|
|
"/notifications/hub/negotiate".proxyPass = upstream;
|
|
};
|
|
useACMEHost = pubDomain;
|
|
};
|
|
|
|
"matrix.nul.ie" = {
|
|
listen = dualStackListen [
|
|
{
|
|
port = 443;
|
|
ssl = true;
|
|
}
|
|
{
|
|
# Matrix federation
|
|
port = 8448;
|
|
ssl = true;
|
|
extraParameters = [ "default_server" ];
|
|
}
|
|
];
|
|
locations = mkMerge [
|
|
{
|
|
"/".proxyPass = "http://chatterbox-ctr.${domain}:8008";
|
|
"= /".return = "301 https://element.${pubDomain}";
|
|
}
|
|
wellKnown
|
|
];
|
|
useACMEHost = pubDomain;
|
|
};
|
|
|
|
"element.${pubDomain}" =
|
|
let
|
|
headers = ''
|
|
# TODO: why are these here?
|
|
#add_header X-Frame-Options SAMEORIGIN;
|
|
#add_header X-Content-Type-Options nosniff;
|
|
#add_header X-XSS-Protection "1; mode=block";
|
|
# This seems to break file downloads...
|
|
#add_header Content-Security-Policy "frame-ancestors 'none'";
|
|
'';
|
|
in
|
|
{
|
|
extraConfig = ''
|
|
${headers}
|
|
'';
|
|
root = pkgs.element-web.override {
|
|
# Currently it seems like single quotes aren't escaped like they should be...
|
|
conf = {
|
|
brand = "/dev/player0 Matrix";
|
|
show_labs_settings = true;
|
|
default_country_code = "IE";
|
|
disable_guests = true;
|
|
default_server_config = {
|
|
"m.homeserver" = {
|
|
base_url = "https://matrix.nul.ie";
|
|
server_name = "nul.ie";
|
|
};
|
|
};
|
|
room_directory.servers = [
|
|
"nul.ie"
|
|
"matrix.org"
|
|
];
|
|
};
|
|
};
|
|
locations = mkMerge [
|
|
{ }
|
|
(genAttrs [ "= /index.html" "= /version" "/config" ] (_: {
|
|
extraConfig = ''
|
|
# Gotta duplicate the headers...
|
|
# https://github.com/yandex/gixy/blob/master/docs/en/plugins/addheaderredefinition.md
|
|
${headers}
|
|
add_header Cache-Control "no-cache";
|
|
'';
|
|
}))
|
|
];
|
|
useACMEHost = pubDomain;
|
|
};
|
|
|
|
"torrents.${pubDomain}" = mkMerge [
|
|
{
|
|
locations."/" = mkMerge [
|
|
{
|
|
proxyPass = "http://jackflix-ctr.${domain}:9091";
|
|
}
|
|
(ssoLoc "generic")
|
|
];
|
|
useACMEHost = pubDomain;
|
|
}
|
|
(ssoServer "generic")
|
|
];
|
|
|
|
"jackett.${pubDomain}" = mkMerge [
|
|
{
|
|
locations."/" = mkMerge [
|
|
{
|
|
proxyPass = "http://jackflix-ctr.${domain}:9117";
|
|
}
|
|
(ssoLoc "generic")
|
|
];
|
|
useACMEHost = pubDomain;
|
|
}
|
|
(ssoServer "generic")
|
|
];
|
|
"radarr.${pubDomain}" = mkMerge [
|
|
{
|
|
locations."/" = mkMerge [
|
|
{
|
|
proxyPass = "http://jackflix-ctr.${domain}:7878";
|
|
proxyWebsockets = true;
|
|
extraConfig = proxyHeaders;
|
|
}
|
|
(ssoLoc "generic")
|
|
];
|
|
useACMEHost = pubDomain;
|
|
}
|
|
(ssoServer "generic")
|
|
];
|
|
"sonarr.${pubDomain}" = mkMerge [
|
|
{
|
|
locations."/" = mkMerge [
|
|
{
|
|
proxyPass = "http://jackflix-ctr.${domain}:8989";
|
|
proxyWebsockets = true;
|
|
extraConfig = proxyHeaders;
|
|
}
|
|
(ssoLoc "generic")
|
|
];
|
|
useACMEHost = pubDomain;
|
|
}
|
|
(ssoServer "generic")
|
|
];
|
|
"gib.${pubDomain}" = {
|
|
locations."/".proxyPass = "http://jackflix-ctr.${domain}:5055";
|
|
useACMEHost = pubDomain;
|
|
};
|
|
|
|
"jackflix.${pubDomain}" =
|
|
let
|
|
upstream = "http://jackflix-ctr.${domain}:8096";
|
|
in
|
|
{
|
|
extraConfig = ''
|
|
add_header X-Frame-Options "SAMEORIGIN";
|
|
add_header X-XSS-Protection "1; mode=block";
|
|
add_header X-Content-Type-Options "nosniff";
|
|
'';
|
|
locations = {
|
|
"/".proxyPass = upstream;
|
|
|
|
"= /".return = "302 https://$host/web/";
|
|
"= /web/".proxyPass = "${upstream}/web/index.html";
|
|
|
|
"/socket" = {
|
|
proxyPass = upstream;
|
|
proxyWebsockets = true;
|
|
extraConfig = proxyHeaders;
|
|
};
|
|
};
|
|
useACMEHost = pubDomain;
|
|
};
|
|
|
|
"toot.nul.ie" = {
|
|
locations."/" = {
|
|
proxyPass = "http://toot-ctr.${domain}:80";
|
|
proxyWebsockets = true;
|
|
extraConfig = proxyHeaders;
|
|
};
|
|
useACMEHost = pubDomain;
|
|
};
|
|
|
|
"share.${pubDomain}" = {
|
|
locations."/" = {
|
|
proxyPass = "http://object-ctr.${domain}:9090";
|
|
proxyWebsockets = true;
|
|
extraConfig = proxyHeaders;
|
|
};
|
|
useACMEHost = pubDomain;
|
|
};
|
|
|
|
"stuff.${pubDomain}" = {
|
|
locations."/" = {
|
|
basicAuthFile = config.age.secrets."middleman/htpasswd".path;
|
|
root = "/mnt/media/stuff";
|
|
extraConfig = ''
|
|
fancyindex on;
|
|
fancyindex_show_dotfiles on;
|
|
'';
|
|
};
|
|
useACMEHost = pubDomain;
|
|
};
|
|
"public.${pubDomain}" = {
|
|
serverAliases = [ "p.${pubDomain}" ];
|
|
locations."/" = {
|
|
root = "/mnt/media/public";
|
|
extraConfig = ''
|
|
fancyindex on;
|
|
fancyindex_show_dotfiles on;
|
|
'';
|
|
};
|
|
useACMEHost = pubDomain;
|
|
};
|
|
|
|
"mc-map.${pubDomain}" = {
|
|
locations."/".proxyPass = "http://simpcraft-oci.${domain}:8100";
|
|
useACMEHost = pubDomain;
|
|
};
|
|
"mc-rail.${pubDomain}" = {
|
|
locations."/".proxyPass = "http://simpcraft-oci.${domain}:3876";
|
|
useACMEHost = pubDomain;
|
|
};
|
|
|
|
"librespeed.${domain}" = {
|
|
locations."/".proxyPass = "http://localhost:8989";
|
|
};
|
|
"speed.${pubDomain}" = {
|
|
locations."/".proxyPass = "http://localhost:8989";
|
|
useACMEHost = pubDomain;
|
|
};
|
|
|
|
"md.${pubDomain}" = {
|
|
locations."/" = {
|
|
proxyPass = "http://object-ctr.${domain}:3000";
|
|
proxyWebsockets = true;
|
|
extraConfig = proxyHeaders;
|
|
};
|
|
useACMEHost = pubDomain;
|
|
};
|
|
"pb.${pubDomain}" = {
|
|
locations."/".proxyPass = "http://object-ctr.${domain}:8088";
|
|
useACMEHost = pubDomain;
|
|
};
|
|
"photos.${pubDomain}" = {
|
|
locations."/" = {
|
|
proxyPass = "http://jackflix-ctr.${domain}:2342";
|
|
proxyWebsockets = true;
|
|
extraConfig = proxyHeaders;
|
|
};
|
|
useACMEHost = pubDomain;
|
|
};
|
|
|
|
"pront.${pubDomain}" = mkMerge [
|
|
{
|
|
locations."/" = mkMerge [
|
|
{
|
|
proxyPass = "http://stream-hi.${home.domain}:5000";
|
|
proxyWebsockets = true;
|
|
extraConfig = proxyHeaders;
|
|
}
|
|
(ssoLoc "generic")
|
|
];
|
|
locations."~* ^/webcam/(.*)" = mkMerge [
|
|
{
|
|
proxyPass = "http://stream-hi.${home.domain}:5050/$1$is_args$args";
|
|
extraConfig = proxyHeaders;
|
|
}
|
|
(ssoLoc "generic")
|
|
];
|
|
useACMEHost = pubDomain;
|
|
}
|
|
(ssoServer "generic")
|
|
];
|
|
};
|
|
|
|
minio =
|
|
let
|
|
host = "object-ctr.${domain}";
|
|
s3Upstream = "http://${host}:9000";
|
|
extraConfig = ''
|
|
chunked_transfer_encoding off;
|
|
ignore_invalid_headers off;
|
|
'';
|
|
|
|
nixCacheableRegex = ''^\/(\S+\.narinfo|nar\/\S+\.nar.*|serve\/.+)$'';
|
|
nixCacheHeaders = ''
|
|
add_header Cache-Control $nix_cache_control;
|
|
add_header Expires $nix_expires;
|
|
|
|
brotli on;
|
|
brotli_types application/x-nix-archive;
|
|
'';
|
|
in
|
|
{
|
|
"minio.${pubDomain}" = {
|
|
inherit extraConfig;
|
|
locations = {
|
|
"/" = {
|
|
proxyPass = "http://${host}:9001";
|
|
};
|
|
"/ws" = {
|
|
proxyPass = "http://${host}:9001";
|
|
proxyWebsockets = true;
|
|
extraConfig = proxyHeaders;
|
|
};
|
|
};
|
|
useACMEHost = pubDomain;
|
|
};
|
|
"s3.${pubDomain}" = {
|
|
serverAliases = [ "*.s3.${pubDomain}" ];
|
|
inherit extraConfig;
|
|
locations = {
|
|
"/".proxyPass = s3Upstream;
|
|
"/gitea/packages/" = {
|
|
proxyPass = s3Upstream;
|
|
# HACK: Docker images need the MIME type to be correct for the manifest but Gitea
|
|
# doesn't tell S3... By hiding the header we can use add_header to set Content-Type
|
|
# (normally can't be set directly)
|
|
extraConfig = ''
|
|
proxy_hide_header Content-Type;
|
|
add_header Content-Type $upstream_http_content_type always;
|
|
if ($args ~ "response-content-disposition=.+filename%3D%22manifest\.json%22") {
|
|
add_header Content-Type "application/vnd.docker.distribution.manifest.v2+json";
|
|
}
|
|
'';
|
|
};
|
|
};
|
|
useACMEHost = pubDomain;
|
|
};
|
|
|
|
"nix-cache.${pubDomain}" = {
|
|
locations = {
|
|
"/" = {
|
|
proxyPass = "http://${host}:5000";
|
|
};
|
|
"~ ${nixCacheableRegex}" = {
|
|
proxyPass = "http://${host}:5000";
|
|
extraConfig = nixCacheHeaders;
|
|
};
|
|
};
|
|
useACMEHost = pubDomain;
|
|
};
|
|
};
|
|
|
|
defaultsFor = mapAttrs (n: _: {
|
|
onlySSL = mkDefault true;
|
|
useACMEHost = mkDefault "${domain}";
|
|
kTLS = mkDefault true;
|
|
http2 = mkDefault true;
|
|
});
|
|
in
|
|
mkMerge [
|
|
hosts
|
|
(defaultsFor hosts)
|
|
|
|
minio
|
|
(defaultsFor minio)
|
|
];
|
|
}
|