Files
nix-config/hosts/nas/apps/traefik/default.nix
2025-04-21 14:12:29 -05:00

323 lines
9.3 KiB
Nix
Executable File

{ config, ... }:
let
domain = "mjallen.dev";
authUrl = "http://10.0.1.18:9000/outpost.goauthentik.io";
authentikUrl = "http://10.0.1.18:9000";
onlyofficeUrl = "http://10.0.2.18:9980";
cloudUrl = "http://10.0.2.18:80";
jellyfinUrl = "http://10.0.1.18:8096";
jellyseerrUrl = "http://10.0.1.52:5055";
hassUrl = "http://homeassistant.local:8123";
openWebUIUrl = "http://10.0.1.18:8888";
paperlessUrl = "http://10.0.1.20:28981";
cacheUrl = "http://10.0.1.18:5000";
giteaUrl = "http://10.0.1.18:3000";
actualUrl = "http://10.0.1.18:3333";
in
{
networking.firewall = {
allowedTCPPorts = [
80
443
8080
];
allowedUDPPorts = [
80
443
8080
];
};
services.traefik = {
enable = true;
dataDir = "/media/nas/ssd/nix-app-data/traefik";
group = "jallen-nas";
environmentFiles = [ "${config.services.traefik.dataDir}/traefik.env" ]; # todo: sops
staticConfigOptions = {
entryPoints = {
web = {
address = ":80";
asDefault = true;
http.redirections.entrypoint = {
to = "websecure";
scheme = "https";
};
};
websecure = {
address = ":443";
asDefault = true;
http.tls.certResolver = "letsencrypt";
};
metrics = {
address = ":8082"; # Port for metrics
};
};
log = {
level = "INFO";
};
metrics = {
prometheus = {
entryPoint = "metrics";
addEntryPointsLabels = true;
addServicesLabels = true;
buckets = [0.1 0.3 1.2 5.0]; # Response time buckets
};
};
certificatesResolvers.letsencrypt.acme = {
email = "jalle008@proton.me";
storage = "${config.services.traefik.dataDir}/acme.json";
dnsChallenge = {
provider = "cloudflare";
resolvers = [
"1.1.1.1:53"
"8.8.8.8:53"
];
};
};
api.dashboard = true;
# Access the Traefik dashboard on <Traefik IP>:8080 of your server
api.insecure = true;
experimental = {
plugins = {
bouncer = {
moduleName = "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin";
version = "v1.4.2";
};
geoblock = {
moduleName = "github.com/PascalMinder/geoblock";
version = "v0.2.5";
};
};
};
};
dynamicConfigOptions = {
http = {
middlewares = {
authentik = {
forwardAuth = {
tls.insecureSkipVerify = true;
address = "http://10.0.1.18:9000/outpost.goauthentik.io/auth/traefik";
trustForwardHeader = true;
authResponseHeaders = [
"X-authentik-username"
"X-authentik-groups"
"X-authentik-email"
"X-authentik-name"
"X-authentik-uid"
"X-authentik-jwt"
"X-authentik-meta-jwks"
"X-authentik-meta-outpost"
"X-authentik-meta-provider"
"X-authentik-meta-app"
"X-authentik-meta-version"
];
};
};
onlyoffice-websocket = {
headers.customrequestheaders = {
X-Forwarded-Proto = "https";
};
};
crowdsec = {
plugin = {
bouncer = {
crowdsecAppsecEnabled = true;
crowdsecAppsecHost = "10.0.1.18:7422";
crowdsecAppsecFailureBlock = true;
crowdsecAppsecUnreachableBlock = true;
crowdsecLapiKey = "1daH89qmJ41r2Lpd9hvDw4sxtOAtBzaj3aKFOFqE";
};
};
};
whitelist-geoblock = {
plugin = {
geoblock = {
silentStartUp = false;
allowLocalRequests = true;
logLocalRequests = false;
logAllowedRequests = false;
logApiRequests = false;
api = "https://get.geojs.io/v1/ip/country/{ip}";
apiTimeoutMs = 500;
cacheSize = 25;
forceMonthlyUpdate = true;
allowUnknownCountries = false;
unknownCountryApiResponse = "nil";
blackListMode = false;
countries = [
"CA"
"US"
];
};
};
};
};
services = {
auth.loadBalancer.servers = [
{
url = authUrl;
}
];
authentik.loadBalancer.servers = [
{
url = authentikUrl;
}
];
onlyoffice.loadBalancer.servers = [
{
url = onlyofficeUrl;
}
];
cloud.loadBalancer.servers = [
{
url = cloudUrl;
}
];
jellyfin.loadBalancer.servers = [
{
url = jellyfinUrl;
}
];
jellyseerr.loadBalancer.servers = [
{
url = jellyseerrUrl;
}
];
hass.loadBalancer.servers = [
{
url = hassUrl;
}
];
chat.loadBalancer.servers = [
{
url = openWebUIUrl;
}
];
cache.loadBalancer.servers = [
{
url = cacheUrl;
}
];
paperless.loadBalancer.servers = [
{
url = paperlessUrl;
}
];
gitea.loadBalancer.servers = [
{
url = giteaUrl;
}
];
actual.loadBalancer.servers = [
{
url = actualUrl;
}
];
};
routers = {
auth = {
entryPoints = [ "websecure" ];
rule = "HostRegexp(`{subdomain:[a-z]+}.mjallen.dev`) && PathPrefix(`/outpost.goauthentik.io/`)";
service = "auth";
middlewares = [ "crowdsec" "whitelist-geoblock" ];
priority = 15;
tls.certResolver = "letsencrypt";
};
authentik = {
entryPoints = [ "websecure" ];
rule = "Host(`authentik.${domain}`)";
service = "authentik";
middlewares = [ "crowdsec" "whitelist-geoblock" ];
tls.certResolver = "letsencrypt";
};
onlyoffice = {
entryPoints = [ "websecure" ];
rule = "Host(`office.${domain}`)";
service = "onlyoffice";
middlewares = [ "crowdsec" "whitelist-geoblock" "onlyoffice-websocket" ];
tls.certResolver = "letsencrypt";
};
cloud = {
entryPoints = [ "websecure" ];
rule = "Host(`cloud.${domain}`)";
service = "cloud";
middlewares = [ "crowdsec" "whitelist-geoblock" ];
tls.certResolver = "letsencrypt";
};
jellyfin = {
entryPoints = [ "websecure" ];
rule = "Host(`jellyfin.${domain}`)";
service = "jellyfin";
middlewares = [ "crowdsec" "whitelist-geoblock" ];
tls.certResolver = "letsencrypt";
};
jellyseerr = {
entryPoints = [ "websecure" ];
rule = "Host(`jellyseerr.${domain}`)";
service = "jellyseerr";
middlewares = [ "crowdsec" "whitelist-geoblock" ];
tls.certResolver = "letsencrypt";
};
gitea = {
entryPoints = [ "websecure" ];
rule = "Host(`gitea.${domain}`)";
service = "gitea";
middlewares = [ "crowdsec" "whitelist-geoblock" ];
tls.certResolver = "letsencrypt";
};
actual = {
entryPoints = [ "websecure" ];
rule = "Host(`actual.${domain}`)";
service = "actual";
middlewares = [ "crowdsec" "whitelist-geoblock" ];
tls.certResolver = "letsencrypt";
};
hass = {
entryPoints = [ "websecure" ];
rule = "Host(`hass.${domain}`)";
service = "hass";
middlewares = [ "crowdsec" "whitelist-geoblock" "authentik" ];
priority = 10;
tls.certResolver = "letsencrypt";
};
# open-webui = {
# entryPoints = [ "websecure" ];
# rule = "Host(`chat.${domain}`)";
# service = "chat";
# middlewares = [ "authentik" "whitelist-geoblock" ];
# priority = 10;
# tls.certResolver = "letsencrypt";
# };
cache = {
entryPoints = [ "websecure" ];
rule = "Host(`cache.${domain}`)";
service = "cache";
middlewares = [ "crowdsec" "whitelist-geoblock" "authentik" ];
priority = 10;
tls.certResolver = "letsencrypt";
};
# paperless = {
# entryPoints = ["websecure"];
# rule = "Host(`paperless.${domain}`)";
# service = "paperless";
# middlewares = [ "crowdsec" "whitelist-geoblock" ];
# tls.certResolver = "letsencrypt";
# };
};
};
};
};
}