{ pkgs, ... }: { imports = [ ./common.nix ]; networking.hostName = "axiomania"; # ============================================================================ # Firewall # ============================================================================ networking.firewall = { allowedTCPPorts = [ 22 80 443 2222 ]; allowedUDPPorts = [ 51820 ]; # Wireguard checkReversePath = "loose"; # Required for WireGuard NAT interfaces.wg0.allowedUDPPorts = [ 53 ]; # AdGuard DNS for VPN clients }; # ============================================================================ # Forgejo # ============================================================================ services.forgejo = { enable = true; database.type = "sqlite3"; settings = { DEFAULT.APP_NAME = "Axiomania Git"; server = { DOMAIN = "git.axiomania.org"; ROOT_URL = "https://git.axiomania.org/"; HTTP_ADDR = "127.0.0.1"; HTTP_PORT = 3000; SSH_DOMAIN = "git.axiomania.org"; SSH_PORT = 2222; START_SSH_SERVER = true; }; service = { DISABLE_REGISTRATION = true; DEFAULT_KEEP_EMAIL_PRIVATE = true; }; repository = { DEFAULT_PRIVATE = "private"; }; api = { ENABLE_SWAGGER = false; }; session = { COOKIE_SECURE = true; }; actions = { ENABLED = true; }; }; }; # ============================================================================ # Forgejo Actions Runner # ============================================================================ # Requires a registration token from Forgejo. # Generate one: ssh root@178.104.15.221, then: # forgejo-runner register (follow prompts) # Or via Forgejo web UI: Site Administration > Runners > Create Runner # Then put the token in /var/lib/forgejo-runner/token services.gitea-actions-runner.instances.default = { enable = true; name = "axiomania"; url = "https://git.axiomania.org"; tokenFile = "/var/lib/forgejo-runner/token"; labels = [ "native:host" ]; hostPackages = with pkgs; [ bash coreutils curl gawk git gnused nodejs nix ]; }; # ============================================================================ # Vaultwarden (Bitwarden-compatible password manager) # ============================================================================ services.vaultwarden = { enable = true; config = { DOMAIN = "https://vault.axiomania.org"; SIGNUPS_ALLOWED = false; ROCKET_ADDRESS = "127.0.0.1"; ROCKET_PORT = 8222; }; }; # ============================================================================ # Navidrome (music streaming) # ============================================================================ services.navidrome = { enable = true; settings = { Address = "127.0.0.1"; Port = 4533; MusicFolder = "/var/lib/navidrome/music"; }; }; # ============================================================================ # Syncthing (file sync) # ============================================================================ services.syncthing = { enable = true; openDefaultPorts = true; dataDir = "/var/lib/syncthing"; settings.gui.insecureSkipHostcheck = true; }; # ============================================================================ # Attic (Nix binary cache) # ============================================================================ # Requires a secret generated on the server: # openssl genrsa -traditional 4096 | base64 -w0 > /var/lib/atticd/token-secret # echo "ATTIC_SERVER_TOKEN_RS256_SECRET_BASE64=$(cat /var/lib/atticd/token-secret)" > /etc/atticd.env services.atticd = { enable = true; environmentFile = "/etc/atticd.env"; settings = { listen = "[::]:8080"; storage = { type = "local"; path = "/var/lib/atticd/storage"; }; garbage-collection = { default-retention-period = "3 months"; }; chunking = { nar-size-threshold = 65536; min-size = 16384; avg-size = 65536; max-size = 262144; }; }; }; # ============================================================================ # Kavita (ebook library) # ============================================================================ # Generate token on the server: # openssl rand -hex 128 > /var/lib/kavita/token-key services.kavita = { enable = true; settings.Port = 5000; tokenKeyFile = "/var/lib/kavita/token-key"; }; # ============================================================================ # Audiobookshelf # ============================================================================ services.audiobookshelf = { enable = true; port = 8234; host = "127.0.0.1"; }; # ============================================================================ # Paperless-ngx (document management) # ============================================================================ services.paperless = { enable = true; port = 28981; address = "127.0.0.1"; domain = "docs.axiomania.org"; }; # ============================================================================ # Adguard Home (DNS ad blocker) # ============================================================================ # Use as DNS server via Wireguard: set DNS = 10.100.0.1 in client config services.adguardhome = { enable = true; port = 3300; host = "127.0.0.1"; }; # ============================================================================ # SearXNG (private search engine) # ============================================================================ # Generate secret on the server: # echo "SEARX_SECRET=$(openssl rand -hex 32)" > /etc/searx/secrets.env services.searx = { enable = true; redisCreateLocally = true; settings = { server = { bind_address = "127.0.0.1"; port = 8888; secret_key = "$SEARX_SECRET"; }; }; environmentFile = "/etc/searx/secrets.env"; }; # ============================================================================ # Homepage (services dashboard) # ============================================================================ services.homepage-dashboard = { enable = true; listenPort = 8082; allowedHosts = "home.axiomania.org"; }; # ============================================================================ # Matrix Conduit (encrypted messaging) # ============================================================================ services.matrix-conduit = { enable = true; settings.global = { server_name = "axiomania.org"; port = 6167; address = "127.0.0.1"; allow_registration = false; }; }; # ============================================================================ # Gokapi (file sharing) — disabled due to CVEs in stable # ============================================================================ # services.gokapi = { # enable = true; # environment = { # GOKAPI_PORT = 53842; # }; # }; # ============================================================================ # Wireguard VPN # ============================================================================ # Generate keys on the server: # wg genkey | tee /etc/wireguard/private.key | wg pubkey > /etc/wireguard/public.key networking.wireguard.interfaces.wg0 = { ips = [ "10.100.0.1/24" ]; listenPort = 51820; privateKeyFile = "/etc/wireguard/private.key"; peers = [ { # Minisforum V3 SE (local NixOS machine) publicKey = "rEsHqzJVnv9AoOIEVTrdEF3x4G6rWxXqHLXTzAx88gc="; allowedIPs = [ "10.100.0.2/32" ]; } { # Pixel 5 publicKey = "jP+rYdc8qKdNY4l3PDFmGiOA31SnJRgcmQIVu6AJ9EM="; allowedIPs = [ "10.100.0.3/32" ]; } ]; }; # NAT for Wireguard clients to access the internet networking.nat = { enable = true; externalInterface = "enp1s0"; internalInterfaces = [ "wg0" ]; }; # ============================================================================ # Nginx reverse proxy + ACME # ============================================================================ services.nginx = { enable = true; recommendedProxySettings = true; recommendedTlsSettings = true; recommendedOptimisation = true; recommendedGzipSettings = true; # ── Public services ── virtualHosts."git.axiomania.org" = { enableACME = true; forceSSL = true; locations."/" = { proxyPass = "http://127.0.0.1:3000"; proxyWebsockets = true; }; }; virtualHosts."matrix.axiomania.org" = { enableACME = true; forceSSL = true; locations."/" = { proxyPass = "http://127.0.0.1:6167"; proxyWebsockets = true; }; }; virtualHosts."cache.axiomania.org" = { enableACME = true; forceSSL = true; locations."/" = { proxyPass = "http://[::1]:8080"; proxyWebsockets = true; extraConfig = "client_max_body_size 0;"; }; }; # ── VPN-only services (WireGuard clients only) ── virtualHosts."vault.axiomania.org" = { enableACME = true; forceSSL = true; locations."/" = { proxyPass = "http://127.0.0.1:8222"; proxyWebsockets = true; extraConfig = "allow 10.100.0.0/24; allow 127.0.0.1; deny all;"; }; }; virtualHosts."music.axiomania.org" = { enableACME = true; forceSSL = true; locations."/" = { proxyPass = "http://127.0.0.1:4533"; proxyWebsockets = true; extraConfig = "allow 10.100.0.0/24; allow 127.0.0.1; deny all;"; }; }; virtualHosts."sync.axiomania.org" = { enableACME = true; forceSSL = true; locations."/" = { proxyPass = "http://127.0.0.1:8384"; proxyWebsockets = true; extraConfig = "allow 10.100.0.0/24; allow 127.0.0.1; deny all;"; }; }; virtualHosts."books.axiomania.org" = { enableACME = true; forceSSL = true; locations."/" = { proxyPass = "http://127.0.0.1:5000"; proxyWebsockets = true; extraConfig = "allow 10.100.0.0/24; allow 127.0.0.1; deny all;"; }; }; virtualHosts."audio.axiomania.org" = { enableACME = true; forceSSL = true; locations."/" = { proxyPass = "http://127.0.0.1:8234"; proxyWebsockets = true; extraConfig = "allow 10.100.0.0/24; allow 127.0.0.1; deny all;"; }; }; virtualHosts."docs.axiomania.org" = { enableACME = true; forceSSL = true; locations."/" = { proxyPass = "http://127.0.0.1:28981"; proxyWebsockets = true; extraConfig = "allow 10.100.0.0/24; allow 127.0.0.1; deny all;"; }; }; virtualHosts."search.axiomania.org" = { enableACME = true; forceSSL = true; locations."/" = { proxyPass = "http://127.0.0.1:8888"; proxyWebsockets = true; extraConfig = "allow 10.100.0.0/24; allow 127.0.0.1; deny all;"; }; }; virtualHosts."home.axiomania.org" = { enableACME = true; forceSSL = true; locations."/" = { proxyPass = "http://127.0.0.1:8082"; proxyWebsockets = true; extraConfig = "allow 10.100.0.0/24; allow 127.0.0.1; deny all;"; }; }; # virtualHosts."share.axiomania.org" = { # enableACME = true; # forceSSL = true; # locations."/" = { # proxyPass = "http://127.0.0.1:53842"; # proxyWebsockets = true; # }; # }; }; security.acme = { acceptTerms = true; defaults.email = "gamma.kinematics@gmail.com"; }; # ============================================================================ # Packages # ============================================================================ environment.systemPackages = with pkgs; [ git vim htop wireguard-tools ]; }