Files
nixos/hosts/lax-01/default.nix

348 lines
9.3 KiB
Nix

{
config,
lib,
pkgs,
pkgsUnstable,
inputs,
...
}:
{
imports = [
./disko.nix
];
network-static = {
enable = true;
hardwareAddress = "F2:3C:95:DE:D7:CA";
staticAddresses = [
"172.233.156.108/24"
"2a01:7e03::2000:c2ff:fee5:70e7/64"
];
staticRoutes = [
{
Gateway = "172.233.156.1";
GatewayOnLink = true;
}
{
Gateway = "fe80::1";
}
];
};
qemu.enable = false;
spice.enable = false;
appserver.enable = true;
dbserver-postgresql.enable = true;
dockerserver.enable = true;
services.traefik = {
staticConfigOptions = {
entryPoints = {
gitea-ssh = {
address = ":2200";
};
};
certificatesResolvers = {
staging.acme = {
email = "eric.torres@its-et.me";
storage = "/var/lib/traefik/acme.json"; # TODO change this to a variable
caServer = "https://acme-staging-v02.api.letsencrypt.org/directory";
tlsChallenge = { };
};
production.acme = {
email = "eric.torres@its-et.me";
storage = "/var/lib/traefik/acme.json";
caServer = "https://acme-v02.api.letsencrypt.org/directory";
tlsChallenge = { };
};
};
};
dynamicConfigOptions = {
http.routers = {
bookstack = {
entrypoints = [ "websecure" ];
rule = "Host(`kb.its-et.me`)";
service = "proxy-to-appserver";
tls.certresolver = "production";
};
#eric-torres-com = {
# entrypoints = [ "websecure" ];
# rule = "Host(`eric-torres.com`)";
# service = "proxy-to-appserver";
# tls.certresolver = "production";
#};
changedetection = {
entrypoints = [ "websecure" ];
rule = "Host(`change.its-et.me`)";
middlewares = [ "authentik@file" ];
service = "proxy-to-appserver";
tls.certresolver = "production";
};
gitea = {
entrypoints = [ "websecure" ];
rule = "Host(`git.its-et.me`)";
service = "proxy-to-appserver";
tls.certresolver = "production";
};
hortusfox = {
entrypoints = [ "websecure" ];
rule = "Host(`plants.its-et.me`)";
middlewares = [ "authentik@file" ];
service = "proxy-to-appserver";
tls.certresolver = "production";
};
immich = {
entrypoints = [ "websecure" ];
rule = "Host(`photos.its-et.me`)";
service = "proxy-to-appserver";
tls.certresolver = "production";
};
its-et-me = {
entrypoints = [ "websecure" ];
rule = "Host(`its-et.me`)";
service = "proxy-to-webserver";
tls.certresolver = "production";
};
www-its-et-me = {
entrypoints = [ "websecure" ];
rule = "Host(`www.its-et.me`)";
middlewares = [ "strip-www" ];
service = "proxy-to-webserver";
tls.certresolver = "production";
};
karakeep = {
entrypoints = [ "websecure" ];
rule = "Host(`keep.its-et.me`)";
service = "proxy-to-appserver";
tls.certresolver = "production";
};
linkwarden = {
entrypoints = [ "websecure" ];
rule = "Host(`bookmarks.its-et.me`)";
service = "proxy-to-appserver";
tls.certresolver = "production";
};
lubelogger = {
entrypoints = [ "websecure" ];
rule = "Host(`ll.its-et.me`)";
service = "proxy-to-appserver";
tls.certresolver = "production";
};
mealie = {
entrypoints = [ "websecure" ];
rule = "Host(`recipes.its-et.me`)";
service = "proxy-to-appserver";
tls.certresolver = "production";
};
mealie2 = {
entrypoints = [ "websecure" ];
rule = "Host(`mealie.its-et.me`)";
middlewares = [ "redirect-mealie" ];
service = "proxy-to-appserver";
tls.certresolver = "production";
};
microbin = {
entrypoints = [ "websecure" ];
rule = "Host(`paste.its-et.me`)";
service = "proxy-to-appserver";
tls.certresolver = "production";
};
miniflux = {
entrypoints = [ "websecure" ];
rule = "Host(`reader.its-et.me`)";
service = "proxy-to-appserver";
tls.certresolver = "production";
};
paperless = {
entrypoints = [ "websecure" ];
rule = "Host(`paperless.its-et.me`)";
service = "proxy-to-appserver";
tls.certresolver = "production";
};
peppermint = {
entrypoints = [ "websecure" ];
rule = "Host(`tickets.its-et.me`)";
service = "proxy-to-appserver";
tls.certresolver = "production";
};
radicale = {
entrypoints = [ "websecure" ];
rule = "Host(`dav.its-et.me`)";
service = "proxy-to-appserver";
tls.certresolver = "production";
};
stirling-pdf = {
entrypoints = [ "websecure" ];
rule = "Host(`pdf.its-et.me`)";
service = "proxy-to-appserver";
tls.certresolver = "production";
};
vikunja = {
entrypoints = [ "websecure" ];
rule = "Host(`projects.its-et.me`)";
service = "proxy-to-appserver";
tls.certresolver = "production";
};
};
http.services = {
proxy-to-appserver = {
loadbalancer.servers = [
{
url = "http://app-01.tail755c5.ts.net";
}
];
};
proxy-to-webserver = {
loadbalancer.servers = [
{
url = "http://web-01.tail755c5.ts.net";
}
];
};
};
http.middlewares = {
authentik = {
forwardauth = {
address = "http://127.0.0.1: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"
];
};
};
compress-content = {
compress = { };
};
default-headers = {
headers = {
# ----- Security headers -----
browserXssFilter = true;
contentTypeNosniff = true;
forceSTSHeader = true;
stsIncludeSubdomains = true;
stsPreload = true;
# HSTS max-age attribute set to 1 year
stsSeconds = 31536000;
# We want to use same-origin, otherwise csrf verification fails for django
referrerPolicy = "same-origin";
# Disable for now, it breaks my websites
#contentSecurityPolicy= "default-src 'self'; script-src 'self'; connect-src 'self'; img-src 'self'; style-src 'self'; base-uri 'self'; form-action 'self'"
permissionsPolicy = "geolocation=(self 'https://its-et.me'), camera=(), microphone=(), payment=(), usb=(), vr=()";
customFrameOptionsValue = "SAMEORIGIN";
frameDeny = true;
# ----- Custom Headers -----
customRequestHeaders = {
X-Forwarded-Proto = "https";
};
customResponseHeaders = {
X-Powered-By = "";
};
};
};
ratelimit = {
rateLimit = {
average = 150;
burst = 75;
};
};
redirect-mealie = {
redirectRegex = {
regex = "^https?://mealie.its-et.me/(.*)";
replacement = "https://recipes.its-et.me/\${1}";
permanent = true;
};
};
strip-www = {
redirectRegex = {
regex = "^https?://www\\.(.*)";
replacement = "https://$1";
permanent = true;
};
};
};
tcp.routers = {
gitea-ssh = {
entrypoints = [ "gitea-ssh" ];
rule = "Hostsni(`*`)";
service = "gitea-ssh";
};
};
tcp.services = {
gitea-ssh = {
loadbalancer.servers = [
{
address = "app-01.tail755c5.ts.net:2200";
}
];
};
};
};
};
networking.firewall.allowedTCPPorts = [
80
443
2200 # for Gitea
];
#borg-config = {
# enable = true;
# backupLabel = "appserver";
# localRepoPath = "ssh://borg@borg-01.tail755c5.ts.net/./";
# remoteRepoPath = "ssh://fm1833@fm1833.rsync.net/./appdata";
# sourceDirectories = [
# "/mnt/data/docker-compose"
# "/mnt/data/services"
# ];
# hcPingUrlLocal = "https://hc.its-et.me/ping/PlGPBqq-0rLI4N4ya3jYmg/backup-appdata";
# hcPingUrlRemote = "https://hc.its-et.me/ping/PlGPBqq-0rLI4N4ya3jYmg/backup-appdata-remote";
#};
base.userSSHKeys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJc52bmxvqBOQJ8vRgI/Tz7PQU8a+4ai7/uB6j2tvJuP etorres@xenon"
];
}