CloudBeaver database manager guide, Ecija intranet deployment, Gitea-Coolify auto-deploy and integration docs, monitoring setup with presentation, remote access guide, security architecture, and Turbostarter deployment procedure. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
330 lines
7.7 KiB
Markdown
330 lines
7.7 KiB
Markdown
# 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 <IP>
|
|
```
|
|
|
|
### 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 <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 { <IP> }"
|
|
```
|
|
|
|
### 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
|