{ config, pkgs, lib, ... }: { imports = [ ./hardware-configuration.nix ]; # Workaround for https://github.com/NixOS/nix/issues/8502 services.logrotate.checkConfig = false; boot.tmp.cleanOnBoot = true; zramSwap = { enable = true; memoryPercent = 50; algorithm = "zstd"; }; networking.hostName = "nixos"; networking.domain = ""; # === Firewall === networking.firewall = { enable = true; allowedTCPPorts = [ 22 ]; # SSH (80/443 added by nginx module) allowPing = false; }; # === SSH Hardening === services.openssh = { enable = true; settings = { PermitRootLogin = "no"; PasswordAuthentication = false; KexAlgorithms = [ "sntrup761x25519-sha512@openssh.com" "curve25519-sha256" "curve25519-sha256@libssh.org" ]; Ciphers = [ "chacha20-poly1305@openssh.com" "aes256-gcm@openssh.com" ]; Macs = [ "hmac-sha2-512-etm@openssh.com" "hmac-sha2-256-etm@openssh.com" "umac-128-etm@openssh.com" ]; }; }; # === User Account === users.users.ashie = { isNormalUser = true; extraGroups = [ "wheel" ]; openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII0OjmlFPbz/H0sv+Y7L+rHR7KCD9lL7HIevEnqy48qH ashisgreat22@github.com" ]; }; # === Sudo without password for wheel group === security.sudo.wheelNeedsPassword = false; # === SOPS (Secrets Management) === sops = { defaultSopsFile = ./secrets/secrets.yaml; defaultSopsFormat = "yaml"; age.keyFile = "/var/lib/sops-nix/key.txt"; # Generate with: nix-shell -p age --run "age-keygen -o key.txt" # Then add the public key to .sops.yaml }; # === System Maintenance & Updates === myModules.system = { mainUser = "ashie"; autoUpdate = { enable = true; allowReboot = false; # Set to true to allow automatic reboots for kernel updates }; }; system.stateVersion = "23.11"; environment.systemPackages = with pkgs; [ vim wget git nano kitty.terminfo htop tmux headscale ]; nix.settings.experimental-features = [ "nix-command" "flakes" ]; # Allow unfree packages (for open-webui) nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [ "open-webui" ]; # === SearXNG === myModules.searxng = { enable = true; port = 8888; domain = "search.ashisgreat.xyz"; # Change to your domain instanceName = "Ashie Search"; }; # === Nginx Reverse Proxy === myModules.nginx = { enable = true; email = "info@ashisgreat.xyz"; rateLimit = { enable = true; requests = 10; burst = 20; }; domains = { "search.ashisgreat.xyz" = { port = 8888; # SearXNG sets its own CSP in settings.yml — omit at Nginx level to avoid conflicts contentSecurityPolicy = null; # Search engine — slightly more permissive for bot traffic rateLimit.requests = 20; rateLimit.burst = 40; }; }; }; # === AdGuard Home (DoT) === myModules.adguard = { enable = true; domain = "dns.ashisgreat.xyz"; }; # === OpenClaw === myModules.openclaw-podman = { enable = true; superpowers.enable = true; port = 18789; domain = "openclaw.ashisgreat.xyz"; }; # OpenClaw secrets sops.secrets.openclaw_discord_token = { }; sops.secrets.openclaw_zai_api_key = { }; sops.secrets.openclaw_brave_api_key = { }; sops.secrets.github_token = { }; sops.secrets.forgejo_url = { }; sops.secrets.forgejo_token = { }; sops.secrets.forgejo_user = { }; sops.templates."openclaw.env" = { content = '' OPENCLAW_GATEWAY_TOKEN=local_bypass_token_for_openclaw_12345 DISCORD_TOKEN=${config.sops.placeholder.openclaw_discord_token} ZAI_API_KEY=${config.sops.placeholder.openclaw_zai_api_key} BRAVE_API_KEY=${config.sops.placeholder.openclaw_brave_api_key} GITHUB_TOKEN=${config.sops.placeholder.github_token} FORGEJO_URL=${config.sops.placeholder.forgejo_url} FORGEJO_TOKEN=${config.sops.placeholder.forgejo_token} FORGEJO_USER=${config.sops.placeholder.forgejo_user} ''; }; # === Vaultwarden === myModules.vaultwarden = { enable = true; domain = "vault.ashisgreat.xyz"; signupAllowed = false; }; # === Forgejo (Self-hosted Git) === myModules.forgejo = { enable = true; domain = "git.ashisgreat.xyz"; disableRegistration = true; # Admin only runner = { enable = true; tokenFile = config.sops.templates."forgejo-runner.env".path; }; }; # Forgejo runner secrets sops.secrets.forgejo_runner_token = { }; sops.templates."forgejo-runner.env" = { content = '' TOKEN=${config.sops.placeholder.forgejo_runner_token} ''; }; # === CrowdSec === myModules.crowdsec.enable = true; # === Headscale (Self-hosted Tailscale) === myModules.headscale = { enable = true; domain = "vpn.ashisgreat.xyz"; # OIDC not enabled by default — use pre-shared auth keys: # headscale apikeys create # tailscale up --login-server=https://vpn.ashisgreat.xyz --authkey= # # To enable OIDC login (Google, GitHub, etc.): # oidc.enable = true; # oidc.issuer = "https://accounts.google.com"; # oidc.clientId = "your-client-id"; # oidc.clientSecret = config.sops.placeholder.headscale_oidc_secret; # And add headscale_oidc_secret to your secrets.yaml }; # === Tailscale Client === services.tailscale.enable = true; # === OpenWeb UI === myModules.open-webui = { enable = true; domain = "ai.ashisgreat.xyz"; ollamaUrl = "http://100.64.0.1:11434"; }; # === Backups (Restic + B2) === myModules.backup = { enable = true; repository = "b2:nixos-vps-backup2"; paths = [ "/var/lib/vaultwarden" # Vaultwarden SQLite DB and attachments "/var/backup/vaultwarden" # Vaultwarden built-in backup snapshots "/var/lib/private/AdGuardHome" # AdGuard Home config, filters, query logs "/var/lib/sops-nix" # SOPS age key (critical — decrypts all secrets) "/var/lib/crowdsec" # CrowdSec state, decisions, custom parsers ]; }; }