413 lines
		
	
	
	
		
			9.9 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
			
		
		
	
	
			413 lines
		
	
	
	
		
			9.9 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
# server nas
 | 
						|
{
 | 
						|
  inputs,
 | 
						|
  config,
 | 
						|
  ...
 | 
						|
}: {
 | 
						|
  sops.secrets = {
 | 
						|
    "vpn-keys/tailscale-authkey/defiant" = {
 | 
						|
      sopsFile = "${inputs.secrets}/vpn-keys.yaml";
 | 
						|
    };
 | 
						|
    "vpn-keys/proton-wireguard/defiant-p2p" = {
 | 
						|
      sopsFile = "${inputs.secrets}/vpn-keys.yaml";
 | 
						|
      mode = "0640";
 | 
						|
      owner = "root";
 | 
						|
      group = "systemd-network";
 | 
						|
    };
 | 
						|
    "services/zfs_smtp_token" = {
 | 
						|
      sopsFile = "${inputs.secrets}/defiant-services.yaml";
 | 
						|
    };
 | 
						|
    "services/paperless_password" = {
 | 
						|
      sopsFile = "${inputs.secrets}/defiant-services.yaml";
 | 
						|
      mode = "0700";
 | 
						|
      owner = "paperless";
 | 
						|
      group = "paperless";
 | 
						|
    };
 | 
						|
  };
 | 
						|
 | 
						|
  host = {
 | 
						|
    users = {
 | 
						|
      leyla = {
 | 
						|
        isDesktopUser = true;
 | 
						|
        isTerminalUser = true;
 | 
						|
        isPrincipleUser = true;
 | 
						|
      };
 | 
						|
    };
 | 
						|
    impermanence.enable = true;
 | 
						|
    storage = {
 | 
						|
      enable = true;
 | 
						|
      encryption = true;
 | 
						|
      notifications = {
 | 
						|
        enable = true;
 | 
						|
        host = "smtp.protonmail.ch";
 | 
						|
        port = 587;
 | 
						|
        to = "leyla@jan-leila.com";
 | 
						|
        user = "noreply@jan-leila.com";
 | 
						|
        tokenFile = config.sops.secrets."services/zfs_smtp_token".path;
 | 
						|
      };
 | 
						|
      pool = {
 | 
						|
        # We are having to boot off of the nvm cache drive because I cant figure out how to boot via the HBA
 | 
						|
        bootDrives = ["nvme-Samsung_SSD_990_PRO_4TB_S7KGNU0X907881F"];
 | 
						|
        vdevs = [
 | 
						|
          [
 | 
						|
            "ata-ST18000NE000-3G6101_ZVTCXVEB"
 | 
						|
            "ata-ST18000NE000-3G6101_ZVTCXWSC"
 | 
						|
            "ata-ST18000NE000-3G6101_ZVTD10EH"
 | 
						|
            "ata-ST18000NT001-3NF101_ZVTE0S3Q"
 | 
						|
            "ata-ST18000NT001-3NF101_ZVTEF27J"
 | 
						|
            "ata-ST18000NE000-3G6101_ZVTJ7359"
 | 
						|
          ]
 | 
						|
          [
 | 
						|
            "ata-ST4000NE001-2MA101_WS2275P3"
 | 
						|
            "ata-ST4000NE001-2MA101_WS227B9F"
 | 
						|
            "ata-ST4000NE001-2MA101_WS227CEW"
 | 
						|
            "ata-ST4000NE001-2MA101_WS227CYN"
 | 
						|
            "ata-ST4000NE001-2MA101_WS23TBWV"
 | 
						|
            "ata-ST4000NE001-2MA101_WS23TC5F"
 | 
						|
          ]
 | 
						|
        ];
 | 
						|
        cache = [
 | 
						|
          "nvme-Samsung_SSD_990_PRO_4TB_S7KGNU0X907881F"
 | 
						|
        ];
 | 
						|
      };
 | 
						|
    };
 | 
						|
    network_storage = {
 | 
						|
      enable = true;
 | 
						|
      directories = [
 | 
						|
        {
 | 
						|
          folder = "leyla_documents";
 | 
						|
          user = "leyla";
 | 
						|
          group = "leyla";
 | 
						|
          bind = "/home/leyla/documents";
 | 
						|
        }
 | 
						|
        {
 | 
						|
          folder = "eve_documents";
 | 
						|
          user = "eve";
 | 
						|
          group = "eve";
 | 
						|
        }
 | 
						|
        {
 | 
						|
          folder = "users_documents";
 | 
						|
          user = "root";
 | 
						|
          group = "users";
 | 
						|
        }
 | 
						|
        {
 | 
						|
          folder = "media";
 | 
						|
          user = "jellyfin";
 | 
						|
          group = "jellyfin_media";
 | 
						|
          bind = config.services.jellyfin.media_directory;
 | 
						|
        }
 | 
						|
      ];
 | 
						|
      nfs = {
 | 
						|
        enable = true;
 | 
						|
        directories = ["leyla_documents" "eve_documents" "users_documents" "media"];
 | 
						|
      };
 | 
						|
    };
 | 
						|
  };
 | 
						|
 | 
						|
  systemd.network = {
 | 
						|
    enable = true;
 | 
						|
 | 
						|
    netdevs = {
 | 
						|
      "10-bond0" = {
 | 
						|
        netdevConfig = {
 | 
						|
          Kind = "bond";
 | 
						|
          Name = "bond0";
 | 
						|
        };
 | 
						|
        bondConfig = {
 | 
						|
          Mode = "802.3ad";
 | 
						|
          TransmitHashPolicy = "layer3+4";
 | 
						|
        };
 | 
						|
      };
 | 
						|
 | 
						|
      "20-wg0" = {
 | 
						|
        netdevConfig = {
 | 
						|
          Kind = "wireguard";
 | 
						|
          Name = "wg0";
 | 
						|
        };
 | 
						|
        wireguardConfig = {
 | 
						|
          PrivateKeyFile = config.sops.secrets."vpn-keys/proton-wireguard/defiant-p2p".path;
 | 
						|
          ListenPort = 51820;
 | 
						|
        };
 | 
						|
        wireguardPeers = [
 | 
						|
          {
 | 
						|
            PublicKey = "rRO6yJim++Ezz6scCLMaizI+taDjU1pzR2nfW6qKbW0=";
 | 
						|
            Endpoint = "185.230.126.146:51820";
 | 
						|
            # Allow all traffic but use policy routing to prevent system-wide VPN
 | 
						|
            AllowedIPs = ["0.0.0.0/0"];
 | 
						|
          }
 | 
						|
        ];
 | 
						|
      };
 | 
						|
    };
 | 
						|
    networks = {
 | 
						|
      "40-bond0" = {
 | 
						|
        matchConfig.Name = "bond0";
 | 
						|
        linkConfig = {
 | 
						|
          RequiredForOnline = "degraded-carrier";
 | 
						|
          RequiredFamilyForOnline = "any";
 | 
						|
        };
 | 
						|
        networkConfig.DHCP = "yes";
 | 
						|
 | 
						|
        address = [
 | 
						|
          "192.168.1.10/32"
 | 
						|
        ];
 | 
						|
 | 
						|
        # Set lower priority for default gateway to allow WireGuard interface binding
 | 
						|
        routes = [
 | 
						|
          {
 | 
						|
            Destination = "0.0.0.0/0";
 | 
						|
            Gateway = "192.168.1.1";
 | 
						|
            Metric = 100;
 | 
						|
          }
 | 
						|
        ];
 | 
						|
        dns = ["192.168.1.1"];
 | 
						|
      };
 | 
						|
 | 
						|
      "50-wg0" = {
 | 
						|
        matchConfig.Name = "wg0";
 | 
						|
        networkConfig = {
 | 
						|
          DHCP = "no";
 | 
						|
        };
 | 
						|
        address = [
 | 
						|
          "10.2.0.2/32"
 | 
						|
        ];
 | 
						|
        # Configure routing for application binding
 | 
						|
        routingPolicyRules = [
 | 
						|
          {
 | 
						|
            # Route traffic from VPN interface through VPN table
 | 
						|
            From = "10.2.0.2/32";
 | 
						|
            Table = 200;
 | 
						|
            Priority = 100;
 | 
						|
          }
 | 
						|
        ];
 | 
						|
        routes = [
 | 
						|
          {
 | 
						|
            # Direct route to VPN gateway
 | 
						|
            Destination = "10.2.0.1/32";
 | 
						|
            Scope = "link";
 | 
						|
          }
 | 
						|
          {
 | 
						|
            # Route VPN subnet through VPN gateway in custom table
 | 
						|
            Destination = "10.2.0.0/16";
 | 
						|
            Gateway = "10.2.0.1";
 | 
						|
            Table = 200;
 | 
						|
          }
 | 
						|
          {
 | 
						|
            # Route all traffic through VPN gateway in custom table
 | 
						|
            Destination = "0.0.0.0/0";
 | 
						|
            Gateway = "10.2.0.1";
 | 
						|
            Table = 200;
 | 
						|
          }
 | 
						|
        ];
 | 
						|
      };
 | 
						|
    };
 | 
						|
  };
 | 
						|
 | 
						|
  # limit arc usage to 50gb because ollama doesn't play nice with zfs using up all of the memory
 | 
						|
  boot.kernelParams = ["zfs.zfs_arc_max=53687091200"];
 | 
						|
 | 
						|
  # Enable policy routing and source routing for application-specific VPN binding
 | 
						|
  boot.kernel.sysctl = {
 | 
						|
    "net.ipv4.conf.all.rp_filter" = 2;
 | 
						|
    "net.ipv4.conf.default.rp_filter" = 2;
 | 
						|
    "net.ipv4.conf.wg0.rp_filter" = 2;
 | 
						|
  };
 | 
						|
 | 
						|
  services = {
 | 
						|
    # PostgreSQL database server
 | 
						|
    postgresql = {
 | 
						|
      enable = true;
 | 
						|
      adminUsers = ["leyla"];
 | 
						|
    };
 | 
						|
 | 
						|
    # temp enable desktop environment for setup
 | 
						|
    # Enable the X11 windowing system.
 | 
						|
    xserver.enable = true;
 | 
						|
 | 
						|
    # Enable the GNOME Desktop Environment.
 | 
						|
    displayManager = {
 | 
						|
      gdm.enable = true;
 | 
						|
    };
 | 
						|
    desktopManager = {
 | 
						|
      gnome.enable = true;
 | 
						|
    };
 | 
						|
 | 
						|
    # Enable new reverse proxy system
 | 
						|
    reverseProxy = {
 | 
						|
      enable = true;
 | 
						|
      openFirewall = true;
 | 
						|
      acme = {
 | 
						|
        enable = true;
 | 
						|
        email = "jan-leila@protonmail.com";
 | 
						|
      };
 | 
						|
    };
 | 
						|
 | 
						|
    ollama = {
 | 
						|
      enable = true;
 | 
						|
      exposePort = true;
 | 
						|
 | 
						|
      acceleration = false;
 | 
						|
 | 
						|
      environmentVariables = {
 | 
						|
        OLLAMA_KEEP_ALIVE = "24h";
 | 
						|
      };
 | 
						|
 | 
						|
      loadModels = [
 | 
						|
        # conversation models
 | 
						|
        "llama3.1:8b"
 | 
						|
        "deepseek-r1:8b"
 | 
						|
        "deepseek-r1:32b"
 | 
						|
        "deepseek-r1:70b"
 | 
						|
 | 
						|
        # auto complete models
 | 
						|
        "qwen2.5-coder:1.5b-base"
 | 
						|
        "qwen2.5-coder:7b"
 | 
						|
        "deepseek-coder:6.7b"
 | 
						|
        "deepseek-coder:33b"
 | 
						|
 | 
						|
        # agent models
 | 
						|
        "qwen3:8b"
 | 
						|
        "qwen3:32b"
 | 
						|
        "qwen3:235b-a22b"
 | 
						|
 | 
						|
        "qwen3-coder:30b"
 | 
						|
        "qwen3-coder:30b-a3b-fp16"
 | 
						|
 | 
						|
        # embedding models
 | 
						|
        "nomic-embed-text:latest"
 | 
						|
      ];
 | 
						|
    };
 | 
						|
    tailscale = {
 | 
						|
      enable = true;
 | 
						|
      authKeyFile = config.sops.secrets."vpn-keys/tailscale-authkey/defiant".path;
 | 
						|
      useRoutingFeatures = "server";
 | 
						|
      extraUpFlags = [
 | 
						|
        "--advertise-exit-node"
 | 
						|
        "--advertise-routes=192.168.0.0/24"
 | 
						|
        "--accept-dns=false"
 | 
						|
      ];
 | 
						|
      extraSetFlags = [
 | 
						|
        "--advertise-exit-node"
 | 
						|
        "--advertise-routes=192.168.0.0/24"
 | 
						|
        "--accept-dns=false"
 | 
						|
      ];
 | 
						|
    };
 | 
						|
 | 
						|
    syncthing.enable = true;
 | 
						|
 | 
						|
    fail2ban.enable = true;
 | 
						|
 | 
						|
    jellyfin = {
 | 
						|
      enable = true;
 | 
						|
      domain = "media.jan-leila.com";
 | 
						|
      extraDomains = ["jellyfin.jan-leila.com"];
 | 
						|
    };
 | 
						|
 | 
						|
    immich = {
 | 
						|
      enable = true;
 | 
						|
      domain = "photos.jan-leila.com";
 | 
						|
    };
 | 
						|
 | 
						|
    forgejo = {
 | 
						|
      enable = true;
 | 
						|
      reverseProxy.domain = "git.jan-leila.com";
 | 
						|
    };
 | 
						|
 | 
						|
    searx = {
 | 
						|
      enable = true;
 | 
						|
      domain = "search.jan-leila.com";
 | 
						|
    };
 | 
						|
 | 
						|
    actual = {
 | 
						|
      enable = true;
 | 
						|
      domain = "budget.jan-leila.com";
 | 
						|
    };
 | 
						|
 | 
						|
    home-assistant = {
 | 
						|
      enable = true;
 | 
						|
      domain = "home.jan-leila.com";
 | 
						|
      openFirewall = true;
 | 
						|
      postgres.enable = true;
 | 
						|
 | 
						|
      extensions = {
 | 
						|
        sonos.enable = true;
 | 
						|
        jellyfin.enable = true;
 | 
						|
        wyoming.enable = false; # Temporarily disabled due to dependency conflict in wyoming-piper
 | 
						|
      };
 | 
						|
    };
 | 
						|
 | 
						|
    paperless = {
 | 
						|
      enable = true;
 | 
						|
      domain = "documents.jan-leila.com";
 | 
						|
      passwordFile = config.sops.secrets."services/paperless_password".path;
 | 
						|
    };
 | 
						|
 | 
						|
    panoramax = {
 | 
						|
      enable = false;
 | 
						|
      openFirewall = true;
 | 
						|
    };
 | 
						|
 | 
						|
    crab-hole = {
 | 
						|
      enable = true;
 | 
						|
      port = 8085;
 | 
						|
      openFirewall = true;
 | 
						|
      show_doc = true;
 | 
						|
      downstreams = {
 | 
						|
        host = {
 | 
						|
          enable = true;
 | 
						|
          openFirewall = true;
 | 
						|
        };
 | 
						|
      };
 | 
						|
      upstreams.cloudFlare.enable = true;
 | 
						|
      blocklists.ad_malware.enable = true;
 | 
						|
    };
 | 
						|
 | 
						|
    qbittorrent = {
 | 
						|
      enable = true;
 | 
						|
      mediaDir = "/srv/qbittorent";
 | 
						|
      openFirewall = true;
 | 
						|
      webuiPort = 8084;
 | 
						|
    };
 | 
						|
 | 
						|
    sonarr = {
 | 
						|
      enable = true;
 | 
						|
      openFirewall = true;
 | 
						|
    };
 | 
						|
    radarr = {
 | 
						|
      enable = true;
 | 
						|
      openFirewall = true;
 | 
						|
    };
 | 
						|
    bazarr = {
 | 
						|
      enable = true;
 | 
						|
      openFirewall = true;
 | 
						|
    };
 | 
						|
    lidarr = {
 | 
						|
      enable = true;
 | 
						|
      openFirewall = true;
 | 
						|
    };
 | 
						|
    jackett = {
 | 
						|
      enable = true;
 | 
						|
      openFirewall = true;
 | 
						|
    };
 | 
						|
    flaresolverr = {
 | 
						|
      enable = true;
 | 
						|
      openFirewall = true;
 | 
						|
    };
 | 
						|
  };
 | 
						|
 | 
						|
  # disable computer sleeping
 | 
						|
  systemd.targets = {
 | 
						|
    sleep.enable = false;
 | 
						|
    suspend.enable = false;
 | 
						|
    hibernate.enable = false;
 | 
						|
    hybrid-sleep.enable = false;
 | 
						|
  };
 | 
						|
  services.displayManager.gdm.autoSuspend = false;
 | 
						|
 | 
						|
  # This value determines the NixOS release from which the default
 | 
						|
  # settings for stateful data, like file locations and database versions
 | 
						|
  # on your system were taken. It's perfectly fine and recommended to leave
 | 
						|
  # this value at the release version of the first install of this system.
 | 
						|
  # Before changing this value read the documentation for this option
 | 
						|
  # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
 | 
						|
  system.stateVersion = "23.05"; # Did you read the comment?
 | 
						|
}
 |