# Home Server XMPP Deployment Guide Complete guide to deploying XMPP on your home server (the laptop downstairs) with Cloudflare DDNS and `chat.tonybtw.com`. --- ## Overview **What you're building:** - XMPP server (Prosody) on your home laptop - Domain: `chat.tonybtw.com` - Cloudflare DDNS (auto-updates your home IP) - SSL via Let's Encrypt (DNS challenge) - Port forwarding on router - Foundation for future homelab (Jellyfin, Nextcloud, etc.) **Time estimate:** 1-2 hours --- ## Prerequisites - [ ] You own `tonybtw.com` - [ ] Your laptop is running NixOS - [ ] Your laptop is always on (or nearly always) - [ ] You have access to your router admin panel - [ ] Your ISP doesn't block ports 80, 443, 5222, 5269, 5281 --- ## Step 1: Cloudflare Setup Follow the **`cloudflare-setup.md`** guide completely. **Summary:** 1. Point `tonybtw.com` nameservers to Cloudflare 2. Add DNS A records for `chat.tonybtw.com` 3. Create API token for DDNS 4. Create `/root/secrets/cloudflare-token` file 5. Create `/root/secrets/cloudflare-acme-credentials` file **Stop here and do that first.** Come back when Cloudflare is configured. --- ## Step 2: Router Port Forwarding Follow the **`router-portforward-guide.md`** guide completely. **Summary:** 1. Find your server's local IP (e.g., `192.168.1.100`) 2. Set static IP (DHCP reservation) 3. Forward ports: 22, 80, 443, 5222, 5269, 5281 4. Test ports are open from outside network **Stop here and do that.** Come back when port forwarding works. --- ## Step 3: Prepare NixOS Configuration On your home server (laptop): ```bash cd /etc/nixos ``` ### **A. Copy Config Files** If you have them in `~/nixos-dotfiles`: ```bash sudo cp ~/nixos-dotfiles/home-server-base.nix /etc/nixos/ sudo cp ~/nixos-dotfiles/xmpp-home.nix /etc/nixos/ ``` Or clone from your git repo if you pushed them. ### **B. Edit Configuration Files** #### **Edit `home-server-base.nix`:** ```bash sudo vim /etc/nixos/home-server-base.nix ``` **Change line 20:** ```nix domains = [ "chat.tonybtw.com" # Verify this is YOUR domain ]; ``` **Change line 44:** ```nix email = "tony@tonybtw.com"; # YOUR email for Let's Encrypt ``` #### **Edit `xmpp-home.nix`:** ```bash sudo vim /etc/nixos/xmpp-home.nix ``` **Change line 23:** ```nix admins = [ "tony@chat.tonybtw.com" ]; # YOUR username ``` --- ## Step 4: Update Main Configuration Edit your main configuration: ```bash sudo vim /etc/nixos/configuration.nix ``` **Add these imports** at the top (in the `imports` section): ```nix { config, pkgs, ... }: { imports = [ ./hardware-configuration.nix ./home-server-base.nix ./xmpp-home.nix # ... any other imports you have ]; # Rest of your config... } ``` Save and exit. --- ## Step 5: Verify Secrets Files Exist ```bash # Check Cloudflare token sudo cat /root/secrets/cloudflare-token # Should show your API token # Check ACME credentials sudo cat /root/secrets/cloudflare-acme-credentials # Should show: CF_DNS_API_TOKEN=your_token # If missing, go back to cloudflare-setup.md Step 5-6 ``` --- ## Step 6: Deploy Configuration ```bash # Build and activate new configuration sudo nixos-rebuild switch ``` **This will:** 1. Install Prosody 2. Configure firewall 3. Set up Cloudflare DDNS service 4. Request Let's Encrypt SSL certificates (takes ~60 seconds) 5. Start XMPP server **Watch for errors.** Common issues: - Cloudflare API token wrong → Check `/root/secrets/cloudflare-token` - ACME certificate fails → Check DNS is pointing to your home IP - Prosody fails to start → Check logs: `sudo journalctl -u prosody` **If successful, you'll see:** ``` building the system configuration... activating the configuration... setting up /etc... reloading the following units: dbus.service starting the following units: prosody.service, cloudflare-dyndns.service ``` --- ## Step 7: Verify Services Are Running ```bash # Check Prosody sudo systemctl status prosody # Should show: active (running) # Check Cloudflare DDNS sudo systemctl status cloudflare-dyndns # Should show: active (running) # Check ACME certificate sudo systemctl status acme-chat.tonybtw.com # Should show: finished successfully # View Prosody logs sudo journalctl -u prosody -n 50 # Should show: "Prosody is using the epoll backend for connection handling" ``` **If any service failed:** ```bash # See detailed logs sudo journalctl -u prosody -n 100 sudo journalctl -u acme-chat.tonybtw.com -n 100 ``` --- ## Step 8: Create XMPP Admin Account ```bash # Create your admin account sudo prosodyctl adduser tony@chat.tonybtw.com # Enter a strong password when prompted ``` **Test it worked:** ```bash sudo prosodyctl list:users # Should show: tony@chat.tonybtw.com ``` --- ## Step 9: Test XMPP Connection (Local) Install an XMPP client on your laptop: ```bash nix-shell -p dino ``` Open Dino: 1. Click **"Add Account"** 2. **Jabber ID:** `tony@chat.tonybtw.com` 3. **Password:** (the one you just set) 4. Click **"Connect"** **Expected result:** Green indicator, "Connected" **If connection fails:** - Check Prosody is running: `sudo systemctl status prosody` - Check firewall allows 5222: `sudo iptables -L -v | grep 5222` - Check logs: `sudo journalctl -u prosody -f` --- ## Step 10: Test XMPP Connection (External) **From another network** (phone on mobile data, or friend's computer): 1. Install XMPP client: - Android: Conversations - iOS: Monal - Desktop: Gajim or Dino 2. Add account: - **Jabber ID:** `tony@chat.tonybtw.com` - **Password:** (your password) 3. Connect **Expected result:** Connection successful **If connection fails:** - Check ports are forwarded: Use https://www.yougetsignal.com/tools/open-ports/ to test port 5222 - Check DNS resolves: `dig chat.tonybtw.com` should show your home IP - Check Cloudflare proxy is DISABLED (gray cloud, not orange) --- ## Step 11: Test SSL Certificate ```bash # Test SSL certificate openssl s_client -connect chat.tonybtw.com:5222 -starttls xmpp # Should show certificate details and: # Verify return code: 0 (ok) ``` **If certificate is invalid:** ```bash # Check ACME logs sudo journalctl -u acme-chat.tonybtw.com # Manually renew if needed sudo systemctl start acme-chat.tonybtw.com ``` --- ## Step 12: Create User Accounts for Friends ```bash # Create accounts sudo prosodyctl adduser alice@chat.tonybtw.com sudo prosodyctl adduser bob@chat.tonybtw.com sudo prosodyctl adduser charlie@chat.tonybtw.com # List all users sudo prosodyctl list:users ``` --- ## Step 13: Create Group Rooms In Dino (or any XMPP client), logged in as your admin account: 1. **Join/Create Room:** - Address: `#general@conference.chat.tonybtw.com` - Click "Join" - Room will be auto-created 2. **Make Room Persistent:** - In Dino: Right-click room → "Configure Room" - Enable "Persistent" and "Public" - Save 3. **Create more rooms:** - `#random@conference.chat.tonybtw.com` - `#tech@conference.chat.tonybtw.com` - `#gaming@conference.chat.tonybtw.com` --- ## Step 14: Invite Friends Send each friend: 1. **Their credentials:** ``` Username: yourname@chat.tonybtw.com Password: [their_password] ``` 2. **The setup guide:** Share `xmpp-setup.md` (edit it first to replace `yourdomain.com` with `chat.tonybtw.com`) 3. **Room to join:** ``` #general@conference.chat.tonybtw.com ``` --- ## Maintenance ### **View Logs** ```bash # Prosody logs sudo journalctl -u prosody -f # DDNS logs sudo journalctl -u cloudflare-dyndns -f # System logs sudo journalctl -f ``` ### **Restart Services** ```bash sudo systemctl restart prosody sudo systemctl restart cloudflare-dyndns ``` ### **Manage Users** ```bash # Add user sudo prosodyctl adduser newuser@chat.tonybtw.com # Change password sudo prosodyctl passwd username@chat.tonybtw.com # Delete user sudo prosodyctl deluser olduser@chat.tonybtw.com # List users sudo prosodyctl list:users ``` ### **Check Server Status** ```bash # Prosody status and stats sudo prosodyctl about # Connected users sudo prosodyctl mod_admin_telnet # Then type: c2s:show() # Exit with: quit ``` ### **Renew SSL Certificates** Automatic renewal happens via systemd timer. Check status: ```bash # Check ACME timer sudo systemctl list-timers | grep acme # Manually renew sudo systemctl start acme-chat.tonybtw.com ``` --- ## Troubleshooting ### **Prosody Won't Start** ```bash # Check config syntax sudo prosodyctl check config # Check certificate permissions sudo ls -la /var/lib/acme/chat.tonybtw.com/ # Should be readable by prosody user sudo chown -R prosody:prosody /var/lib/acme/chat.tonybtw.com/ ``` ### **Can't Connect from External Network** ```bash # Check if ports are actually open (from another network): nc -zv YOUR_HOME_IP 5222 # Check DNS resolution: dig chat.tonybtw.com # Should show your home IP # Check Cloudflare DDNS is updating: sudo journalctl -u cloudflare-dyndns | tail -20 # Check your current home IP: curl ifconfig.me ``` ### **SSL Certificate Failed** ```bash # View ACME logs sudo journalctl -u acme-chat.tonybtw.com -n 100 # Common issues: # 1. DNS not pointing to your IP yet (wait 10 minutes) # 2. Cloudflare API token wrong (check /root/secrets/cloudflare-acme-credentials) # 3. Rate limit (Let's Encrypt allows 5 certs/week) # Retry manually: sudo systemctl start acme-chat.tonybtw.com ``` ### **Home IP Changed But DNS Not Updating** ```bash # Check DDNS service sudo systemctl status cloudflare-dyndns # Manually trigger update sudo systemctl restart cloudflare-dyndns # Check Cloudflare dashboard # Go to Cloudflare → DNS → Records # Verify "chat" A record shows current IP ``` --- ## Backup Strategy **What to backup:** - User accounts and messages: `/var/lib/prosody/` - SSL certificates: `/var/lib/acme/` - Configuration: `/etc/nixos/` ### **Simple Backup Script:** ```bash #!/usr/bin/env bash # /root/backup-homelab.sh BACKUP_DIR="/home/tony/backups" DATE=$(date +%Y%m%d-%H%M) mkdir -p $BACKUP_DIR # Backup Prosody data sudo tar czf $BACKUP_DIR/prosody-$DATE.tar.gz /var/lib/prosody/ # Backup configs sudo tar czf $BACKUP_DIR/nixos-$DATE.tar.gz /etc/nixos/ # Keep last 30 days find $BACKUP_DIR -name "*.tar.gz" -mtime +30 -delete echo "Backup complete: $BACKUP_DIR" ``` Make it executable: ```bash sudo chmod +x /root/backup-homelab.sh ``` **Automate with systemd timer:** ```nix # Add to configuration.nix systemd.timers.homelab-backup = { wantedBy = [ "timers.target" ]; timerConfig = { OnCalendar = "daily"; Persistent = true; }; }; systemd.services.homelab-backup = { serviceConfig.ExecStart = "/root/backup-homelab.sh"; }; ``` Then: `sudo nixos-rebuild switch` --- ## Next Steps (Homelab Expansion) Once XMPP is running, you can add more services: ### **Jellyfin (Media Server):** ```nix services.jellyfin = { enable = true; openFirewall = true; }; # Access at: http://your-server-ip:8096 # Later: Set up jellyfin.tonybtw.com with Nginx reverse proxy ``` ### **Nextcloud (File Sync/Share):** ```nix services.nextcloud = { enable = true; hostName = "cloud.tonybtw.com"; config.adminpassFile = "/root/secrets/nextcloud-admin-pass"; }; ``` ### **Vaultwarden (Password Manager):** ```nix services.vaultwarden = { enable = true; config = { domain = "https://vault.tonybtw.com"; signupsAllowed = false; }; }; ``` **All of these will use:** - Same Cloudflare DDNS setup - Same router port forwarding (or Nginx reverse proxy) - Same Let's Encrypt SSL certificates Your XMPP setup is the foundation. Everything else builds on top. --- ## Monitoring ### **Check Disk Space:** ```bash df -h ncdu / # Interactive disk usage ``` ### **Check Memory:** ```bash free -h htop ``` ### **Check Uptime:** ```bash uptime ``` ### **Check Network:** ```bash # Current connections sudo ss -tunap | grep prosody # Bandwidth usage (install iftop) sudo nix-shell -p iftop sudo iftop ``` --- ## Security Checklist - [ ] Fail2ban is running: `sudo systemctl status fail2ban` - [ ] Firewall is enabled: `sudo iptables -L -v` - [ ] SSH has strong password or key-only auth - [ ] Root login is disabled - [ ] Prosody admin account has strong password - [ ] SSL certificates are valid - [ ] Router admin password is changed from default - [ ] Only necessary ports are forwarded --- ## You're Done! Your home XMPP server is now running at `chat.tonybtw.com`. **Share with friends:** Give them `xmpp-setup.md` (updated with your domain) **Future additions:** - Jellyfin for media streaming - Nextcloud for file sync - Nginx reverse proxy for web services - Monitoring (Grafana + Prometheus) Welcome to self-hosting. You now control your communication infrastructure. 🎉 --- ## Quick Reference Commands ```bash # Restart XMPP sudo systemctl restart prosody # View XMPP logs sudo journalctl -u prosody -f # Add user sudo prosodyctl adduser user@chat.tonybtw.com # List users sudo prosodyctl list:users # Check server status sudo prosodyctl about # Update system sudo nixos-rebuild switch --upgrade # Check open ports sudo ss -tulpn ```