# Security Configuration Comprehensive security hardening for NUC server and OpenWrt router. ## Security Architecture ``` Internet │ ▼ ┌─────────────────────────────────────┐ │ OpenWrt Router (192.168.1.1) │ │ ├─ CrowdSec Bouncer (threat intel) │ │ ├─ Firewall (WAN: REJECT default) │ │ └─ SSH: key-only authentication │ └─────────────────────────────────────┘ │ │ Only allowed: WireGuard (51820/udp) │ ▼ ┌─────────────────────────────────────┐ │ NUC Server (192.168.1.3) │ │ ├─ CrowdSec (threat intelligence) │ │ ├─ fail2ban (brute force protect) │ │ ├─ SSH: key-only + 24h ban │ │ ├─ Unattended upgrades (auto) │ │ └─ Tailscale Funnel (HTTPS only) │ └─────────────────────────────────────┘ ``` ## External Attack Surface | Port | Service | Protection | |------|---------|------------| | 51820/udp | WireGuard VPN | Cryptographic auth only | | Tailscale Funnel | HTTPS services | Tailscale auth + TLS | | Everything else | Blocked | Router firewall DROP | **Not exposed to internet:** - SSH (22) - Router admin (80/443) - Coolify (8000) - All Docker services --- ## Router Security (OpenWrt) ### SSH Configuration | Setting | Value | |---------|-------| | Password auth | Disabled | | Root password auth | Disabled | | Auth method | SSH key only | | Port | 22 (LAN only) | **Config:** `/etc/config/dropbear` ```bash # Verify settings uci get dropbear.@dropbear[0].PasswordAuth # off uci get dropbear.@dropbear[0].RootPasswordAuth # off ``` ### Firewall (fw4/nftables) **WAN Zone Policy:** - Input: REJECT - Forward: REJECT - Output: ACCEPT **Allowed WAN Input:** - DHCP (port 68) - ICMPv6 (limited) - WireGuard (51820/udp) ```bash # View WAN input rules ssh -i ~/.ssh/id_ed25519_nuc root@192.168.1.1 "nft list chain inet fw4 input_wan" ``` ### CrowdSec Firewall Bouncer Blocks malicious IPs using threat intelligence from NUC CrowdSec. | Setting | Value | |---------|-------| | API URL | http://192.168.1.3:8083/ | | Update frequency | 10s | | Action | DROP + log | | Interfaces | wan, wan6 | **Config:** `/etc/config/crowdsec` ```bash # Check bouncer status ssh -i ~/.ssh/id_ed25519_nuc root@192.168.1.1 "/etc/init.d/crowdsec-firewall-bouncer status" # View blocked IPs ssh -i ~/.ssh/id_ed25519_nuc root@192.168.1.1 "nft list set ip crowdsec crowdsec_blocklist" # Check logs ssh -i ~/.ssh/id_ed25519_nuc root@192.168.1.1 "logread | grep crowdsec" ``` --- ## NUC Security ### SSH Configuration | Setting | Value | |---------|-------| | Password auth | Disabled | | Auth method | SSH key only | | Port | 22 | **Config:** `/etc/ssh/sshd_config` ```bash # Verify grep "PasswordAuthentication" /etc/ssh/sshd_config # PasswordAuthentication no ``` ### fail2ban Protects SSH from brute force attacks. | Setting | Value | |---------|-------| | Max retries | 3 | | Ban time | 24 hours | | Find time | 10 minutes | | Ignored IPs | LAN (192.168.1.0/24), Tailscale (100.0.0.0/8) | **Config:** `/etc/fail2ban/jail.local` ```bash # Check status sudo fail2ban-client status sshd # View banned IPs sudo fail2ban-client status sshd | grep "Banned IP" # Unban an IP sudo fail2ban-client set sshd unbanip ``` ### CrowdSec (Docker) Central threat intelligence hub. | Property | Value | |----------|-------| | Container | crowdsec-mwc4ocock400goww8s4k44o8 | | API Port | 8083 | | Dashboard | http://192.168.1.3:8083 | ```bash # List registered bouncers docker exec crowdsec-mwc4ocock400goww8s4k44o8 cscli bouncers list # View decisions (blocked IPs) docker exec crowdsec-mwc4ocock400goww8s4k44o8 cscli decisions list # View alerts docker exec crowdsec-mwc4ocock400goww8s4k44o8 cscli alerts list ``` ### Unattended Upgrades Automatic security and system updates. | Setting | Value | |---------|-------| | Security updates | Enabled | | Regular updates | Enabled | | Auto-reboot | 4:00 AM if needed | | Cleanup unused | Enabled | **Config:** `/etc/apt/apt.conf.d/50unattended-upgrades-local` ```bash # Check status sudo systemctl status unattended-upgrades # View logs cat /var/log/unattended-upgrades/unattended-upgrades.log # Manual dry-run sudo unattended-upgrade --dry-run --debug ``` --- ## Access Methods ### From LAN (Home Network) | Service | Access | |---------|--------| | NUC SSH | `ssh nuc` or `ssh 192.168.1.3` | | Router SSH | `ssh -i ~/.ssh/id_ed25519_nuc root@192.168.1.1` | | Router Admin | http://192.168.1.1 | | Coolify | http://192.168.1.3:8000 | ### From Remote (Via Tailscale) | Service | Access | |---------|--------| | NUC SSH | `ssh nuc-tailscale` | | Full LAN | Via subnet router (192.168.1.0/24) | | Grafana | https://nuc-tailscale.tail58f5ad.ts.net:3002 | ### From Remote (Via WireGuard) ```bash # Connect sudo wg-quick up ~/wireguard/home-vpn.conf # Then access LAN normally ssh 192.168.1.3 ``` --- ## SSH Keys | Key | Location | Used For | |-----|----------|----------| | NUC/Router key | `~/.ssh/id_ed25519_nuc` | SSH to NUC and OpenWrt | ```bash # Test NUC key auth ssh -i ~/.ssh/id_ed25519_nuc -o BatchMode=yes alezmad@192.168.1.3 "echo OK" # Test router key auth ssh -i ~/.ssh/id_ed25519_nuc -o BatchMode=yes root@192.168.1.1 "echo OK" ``` --- ## Security Checklist ### Router - [x] SSH password auth disabled - [x] LuCI not exposed on WAN - [x] WAN input policy: REJECT - [x] CrowdSec bouncer active - [x] Only WireGuard port open (51820) - [x] UPnP disabled ### NUC - [x] SSH password auth disabled - [x] fail2ban protecting SSH - [x] CrowdSec running (Docker) - [x] Unattended upgrades enabled - [x] No services exposed to WAN directly ### Network - [x] Tailscale for remote access - [x] WireGuard as backup VPN - [x] DuckDNS for dynamic IP --- ## Incident Response ### If Brute Force Detected ```bash # Check fail2ban bans sudo fail2ban-client status sshd # Check CrowdSec alerts docker exec crowdsec-mwc4ocock400goww8s4k44o8 cscli alerts list # View auth logs sudo tail -100 /var/log/auth.log | grep -i fail ``` ### If Compromised IP Needs Blocking ```bash # Add manual ban in CrowdSec (blocks on router too) docker exec crowdsec-mwc4ocock400goww8s4k44o8 cscli decisions add --ip --duration 24h --reason "manual block" # Or block directly on router ssh -i ~/.ssh/id_ed25519_nuc root@192.168.1.1 "nft add element ip crowdsec crowdsec_blocklist { }" ``` ### If Locked Out 1. **Physical access to NUC:** Connect monitor/keyboard 2. **Router:** Reset button (hold 10s) restores defaults 3. **Tailscale:** Still works if NUC is running --- ## Monitoring | What | How | |------|-----| | SSH attempts | `sudo tail -f /var/log/auth.log` | | fail2ban activity | `sudo fail2ban-client status sshd` | | CrowdSec decisions | `docker exec crowdsec-... cscli decisions list` | | Router firewall logs | `ssh root@192.168.1.1 "logread \| grep crowdsec"` | | Blocked connections | `ssh root@192.168.1.1 "nft list set ip crowdsec crowdsec_blocklist"` | --- ## Regular Maintenance ### Weekly - Check fail2ban status: `sudo fail2ban-client status` - Review CrowdSec alerts: `docker exec crowdsec-... cscli alerts list` ### Monthly - Verify unattended-upgrades working: `cat /var/log/unattended-upgrades/*.log` - Check for OpenWrt updates: `opkg update && opkg list-upgradable` - Review SSH auth logs for anomalies ### After Security Incident 1. Check all logs (auth, CrowdSec, fail2ban) 2. Rotate SSH keys if needed 3. Update CrowdSec scenarios 4. Review firewall rules