Implement modular nftables architecture and Gitea SSH firewall management

- Restructure security playbook with modular nftables loader
- Base rules loaded first, service rules second, drop rule last
- Add Gitea self-contained firewall management (port 2222)
- Add fail2ban protection for Gitea SSH brute force attacks
- Update documentation with new firewall architecture
- Create comprehensive Gitea deployment and testing guide

This enables self-contained service roles to manage their own firewall
rules without modifying the central security playbook. Each service
deploys rules to /etc/nftables.d/ which are loaded before the final
drop rule, maintaining the defense-in-depth security model.
This commit is contained in:
2025-12-16 21:45:22 +01:00
parent 9b12225ec8
commit 2fe194ba82
12 changed files with 933 additions and 43 deletions

View File

@@ -88,31 +88,42 @@ ssh root@your-vps "journalctl -u sshd | grep -i 'failed\|invalid'"
### Firewall Configuration
#### nftables Firewall Rules
#### Modular nftables Architecture
Rick-infra uses a **modular firewall architecture** that enables self-contained service roles:
**Structure:**
```
/etc/nftables.conf Base infrastructure rules (SSH, HTTP, HTTPS)
/etc/nftables-load.conf Orchestration script (loads rules in order)
/etc/nftables.d/
├── 50-gitea.nft Service-specific rules (Gitea SSH port 2222)
└── 99-drop.nft Final drop rule (loaded last)
```
**Load Order:**
1. Base infrastructure rules (always allowed)
2. Service-specific rules (00-98 prefix)
3. Final drop rule (99-drop.nft)
**Example: Current Ruleset**
```bash
# Deployed firewall configuration
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
# Allow loopback traffic
iifname "lo" accept
# Allow established connections
# Base infrastructure rules
iif "lo" accept
ct state established,related accept
# Allow SSH (rate limited)
tcp dport 22 ct state new limit rate 5/minute accept
# Allow HTTP/HTTPS
tcp dport {80, 443} accept
# Allow ICMP (rate limited)
tcp dport 22 ct state new accept
tcp dport {80, 443} ct state new accept
icmp type echo-request limit rate 1/second accept
# Log dropped packets
log prefix "DROPPED: " drop
# Service-specific rules (loaded from /etc/nftables.d/)
tcp dport 2222 ct state new accept comment "Gitea SSH (Port 2222)"
# Final drop rule (99-drop.nft)
counter drop comment "Drop all other traffic"
}
chain forward {
@@ -129,15 +140,38 @@ table inet filter {
```bash
# Check firewall status
ssh root@your-vps "nft list ruleset"
nft list ruleset
# Monitor dropped connections
ssh root@your-vps "journalctl -k | grep DROPPED"
# View service-specific rules
ls -la /etc/nftables.d/
cat /etc/nftables.d/50-gitea.nft
# Temporary rule addition (emergency access)
ssh root@your-vps "nft add rule inet filter input tcp dport 8080 accept"
# Reload firewall (after manual changes)
systemctl restart nftables
# Test configuration syntax
nft -c -f /etc/nftables-load.conf
# Add service rule (example for future services)
# Create /etc/nftables.d/60-newservice.nft with your rules
echo 'add rule inet filter input tcp dport 8080 accept comment "New Service"' > /etc/nftables.d/60-newservice.nft
systemctl restart nftables
```
#### Adding New Service Ports
When deploying new services that need firewall access:
1. Create rule file: `/etc/nftables.d/XX-servicename.nft` (XX = 00-98)
2. Add rule: `add rule inet filter input tcp dport PORT accept comment "Service Name"`
3. Restart nftables: `systemctl restart nftables`
**Naming Convention:**
- `00-19`: Infrastructure services
- `20-79`: Application services
- `80-98`: Custom/temporary rules
- `99`: Drop rule (reserved)
### Intrusion Detection (fail2ban)
#### fail2ban Configuration