# home-server-base.nix - Base configuration for home server # # This provides the foundation for your homelab: # - Cloudflare DDNS (updates chat.tonybtw.com to your home IP) # - Nginx reverse proxy (handles SSL for all services) # - Fail2ban (basic protection) # - SSH hardening (less strict than VPS since it's on your LAN) # # Import this in your configuration.nix along with service-specific configs # { config, pkgs, lib, ... }: { # ============================================================================ # Cloudflare Dynamic DNS - Keeps your domain pointing to home IP # ============================================================================ services.cloudflare-dyndns = { enable = true; apiTokenFile = "/root/secrets/cloudflare-token"; domains = [ "chat.tonybtw.com" # Add more as you expand: # "jellyfin.tonybtw.com" # "cloud.tonybtw.com" ]; ipv4 = true; ipv6 = false; # Enable if you have IPv6 }; # ============================================================================ # Nginx Reverse Proxy - Handle SSL and route to services # ============================================================================ services.nginx = { enable = true; recommendedProxySettings = true; recommendedTlsSettings = true; recommendedOptimisation = true; recommendedGzipSettings = true; # Shared SSL configuration (Let's Encrypt) # Individual vhosts will reference this }; # ============================================================================ # Let's Encrypt SSL Certificates # ============================================================================ security.acme = { acceptTerms = true; defaults = { email = "tony@tonybtw.com"; # CHANGE THIS to your email dnsProvider = "cloudflare"; # Use Cloudflare DNS challenge (works behind NAT) credentialsFile = "/root/secrets/cloudflare-acme-credentials"; }; certs."chat.tonybtw.com" = { domain = "chat.tonybtw.com"; extraDomainNames = [ "conference.chat.tonybtw.com" "upload.chat.tonybtw.com" ]; group = "prosody"; postRun = "systemctl reload prosody.service"; }; # Add more certs as you expand: # certs."jellyfin.tonybtw.com" = { # domain = "jellyfin.tonybtw.com"; # group = "jellyfin"; # }; }; # ============================================================================ # Firewall - Allow necessary ports # ============================================================================ networking.firewall = { enable = true; # Open ports for services allowedTCPPorts = [ 22 # SSH (consider changing to non-standard port) 80 # HTTP (ACME challenges + redirect to HTTPS) 443 # HTTPS (Nginx reverse proxy) 5222 # XMPP client-to-server (C2S) 5269 # XMPP server-to-server (S2S) - optional, for federation 5281 # XMPP HTTPS (file uploads) # Add more as needed: # 8096 # Jellyfin (or proxy via Nginx) ]; # Basic rate limiting extraCommands = '' # Rate-limit SSH (4 attempts per minute) iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 --name SSH -j DROP # Rate-limit XMPP connections iptables -A INPUT -p tcp --dport 5222 -m state --state NEW -m recent --set --name XMPP iptables -A INPUT -p tcp --dport 5222 -m state --state NEW -m recent --update --seconds 60 --hitcount 10 --name XMPP -j DROP ''; extraStopCommands = '' iptables -D INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH 2>/dev/null || true iptables -D INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 --name SSH -j DROP 2>/dev/null || true iptables -D INPUT -p tcp --dport 5222 -m state --state NEW -m recent --set --name XMPP 2>/dev/null || true iptables -D INPUT -p tcp --dport 5222 -m state --state NEW -m recent --update --seconds 60 --hitcount 10 --name XMPP -j DROP 2>/dev/null || true ''; }; # ============================================================================ # Fail2ban - Basic Protection # ============================================================================ services.fail2ban = { enable = true; maxretry = 5; # Less strict than VPS (you might fat-finger your password) bantime = "10m"; findtime = "10m"; jails = { sshd = '' enabled = true filter = sshd action = iptables[name=SSH, port=22, protocol=tcp] maxretry = 5 ''; }; }; # ============================================================================ # SSH Configuration - Moderate Security (it's on your LAN) # ============================================================================ services.openssh = { enable = true; settings = { PasswordAuthentication = true; # Allow passwords on LAN (change to false if paranoid) PermitRootLogin = "no"; PubkeyAuthentication = true; }; }; # ============================================================================ # Automatic Garbage Collection # ============================================================================ nix.gc = { automatic = true; dates = "weekly"; options = "--delete-older-than 30d"; }; # ============================================================================ # System Packages # ============================================================================ environment.systemPackages = with pkgs; [ vim wget curl htop tmux git btop ncdu # Disk usage analyzer ]; # ============================================================================ # Secrets Management # ============================================================================ # You'll need to create these files manually (see deployment guide) system.activationScripts.secrets = '' mkdir -p /root/secrets chmod 700 /root/secrets ''; }