Files
football/config/firewall-persistence.sh
2026-01-21 08:33:09 -05:00

524 lines
16 KiB
Bash

#!/bin/bash
# Football System Firewall Persistence Configuration
# Ensures firewall rules persist across reboots with nftables
set -e
echo "Configuring firewall persistence..."
# Install required packages if not already installed
apt-get update -qq
apt-get install -y -qq \
nftables \
iptables-persistent \
netfilter-persistent
# Create nftables configuration directory
mkdir -p /etc/nftables.conf.d
# Main nftables configuration
cat > /etc/nftables.conf << 'EOF'
# Football System - nftables Configuration
# Restrictive firewall rules for secure access
# Clear existing rules
flush ruleset
# Table definitions
table inet filter {
# Chain definitions
chain input {
type filter hook input priority 0; policy drop;
# Allow loopback traffic
iifname "lo" accept comment "Allow loopback"
# Allow established and related connections
ct state established,related accept comment "Allow established/related"
# Drop invalid packets
ct state invalid drop comment "Drop invalid packets"
# Allow ICMP (limited)
ip protocol icmp icmp type { echo-request, echo-reply } limit rate 10/second burst 5 packets accept comment "Allow ping (rate limited)"
ip6 nexthdr icmpv6 icmpv6 type { echo-request, echo-reply } limit rate 10/second burst 5 packets accept comment "Allow IPv6 ping (rate limited)"
# Allow required ICMP types
ip protocol icmp icmp type { destination-unreachable, time-exceeded, parameter-problem } accept comment "Allow required ICMP"
ip6 nexthdr icmpv6 icmpv6 type { destination-unreachable, time-exceeded, parameter-problem, packet-too-big, nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept comment "Allow required ICMPv6"
# SSH access (restricted to management network if configured)
tcp dport 22 accept comment "Allow SSH (consider restricting)"
# Remmina/VNC access (only if needed)
tcp dport { 5900, 5901 } accept comment "Allow VNC access"
# WireGuard VPN
udp dport 51820 accept comment "Allow WireGuard VPN"
# DHCP client (if needed)
udp sport { 67,68 } udp dport { 67,68 } accept comment "Allow DHCP"
# DNS client
udp dport 53 ct state established,related accept comment "Allow DNS responses"
# NTP client
udp dport 123 ct state established,related accept comment "Allow NTP responses"
# HTTP/HTTPS client traffic (outbound responses)
tcp sport { 80,443 } ct state established,related accept comment "Allow web responses"
# Drop and log other traffic
log prefix "NFT-INPUT-DROP: " drop comment "Log and drop other input"
}
chain forward {
type filter hook forward priority 0; policy drop;
# Allow forwarding for VPN traffic
iifname "wg0" oifname != "wg0" accept comment "Allow VPN forwarding"
iifname != "wg0" oifname "wg0" accept comment "Allow traffic to VPN"
# Drop and log other forwarded traffic
log prefix "NFT-FORWARD-DROP: " drop comment "Log and drop other forward"
}
chain output {
type filter hook output priority 0; policy accept;
# Allow all outbound traffic by default (restrict as needed)
# Log blocked traffic for troubleshooting
log prefix "NFT-OUTPUT-DROP: " drop comment "Log dropped output"
}
}
# NAT table for VPN (if needed)
table ip nat {
chain postrouting {
type nat hook postrouting priority 100; policy accept;
# NAT for VPN traffic (if internet access via VPN)
# oifname "eth0" ip saddr 10.8.0.0/24 masquerade comment "NAT for VPN"
}
}
EOF
# Create custom rules directory for modular configuration
mkdir -p /etc/nftables.conf.d
# Create separate rule file for allowed management networks
cat > /etc/nftables.conf.d/management.nft << 'EOF'
# Management Network Access Rules
# Uncomment and modify for your management network(s)
# Allow SSH from management network only
# add rule inet filter input ip saddr 192.168.1.0/24 tcp dport 22 accept comment "SSH from management network"
# Allow monitoring from management network
# add rule inet filter input ip saddr 192.168.1.0/24 udp dport { 161,162 } accept comment "SNMP from management network"
EOF
# Create rate limiting rules
cat > /etc/nftables.conf.d/rate-limits.nft << 'EOF'
# Rate Limiting Rules
# Prevent brute force attacks and flooding
# Rate limit new SSH connections
add rule inet filter input tcp dport 22 ct state new limit rate 3/minute burst 5 accept comment "Rate limit SSH"
# Rate limit ping requests
add rule inet filter input ip protocol icmp icmp type echo-request limit rate 10/second burst 5 packets accept comment "Rate limit ping"
# Rate limit VNC connections
add rule inet filter input tcp dport { 5900,5901 } ct state new limit rate 2/minute burst 3 accept comment "Rate limit VNC"
EOF
# Create logging rules
cat > /etc/nftables.conf.d/logging.nft << 'EOF'
# Enhanced Logging Rules
# Log suspicious activity for security monitoring
# Log connection attempts to blocked ports
add rule inet filter input tcp dport { 23,3389,1433,3306,5432 } ct state new log prefix "NFT-SCANNED-PORT: " drop comment "Log blocked port scans"
# Log fragmented packets
add rule inet filter input ip frag-off drop log prefix "NFT-FRAGMENTED: " comment "Drop fragmented packets"
# Log suspicious flags
add rule inet filter input tcp flags & (syn|ack) == (syn|ack) log prefix "NFT-SYN-ACK: " drop comment "Log suspicious SYN-ACK"
EOF
# Create firewall persistence script
cat > /usr/local/bin/firewall-persistence.sh << 'EOF'
#!/bin/bash
# Football System - Firewall Persistence Script
# Ensures firewall rules are saved and restored properly
FIREWALL_CONFIG="/etc/nftables.conf"
RULES_DIR="/etc/nftables.conf.d"
LOCK_FILE="/var/lock/firewall-persistence"
LOG_FILE="/var/log/security/firewall-persistence.log"
# Function to log messages
log_message() {
local level=$1
local message=$2
echo "$(date '+%Y-%m-%d %H:%M:%S') [$level] $message" | tee -a "$LOG_FILE"
}
# Function to check if process is running
is_running() {
pgrep -f "$1" >/dev/null 2>&1
}
# Prevent concurrent execution
exec 200>"$LOCK_FILE"
if flock -n 200; then
log_message "INFO" "Starting firewall persistence check"
else
log_message "WARNING" "Firewall persistence script already running"
exit 1
fi
# Check if nftables service is running
if ! systemctl is-active --quiet nftables; then
log_message "ERROR" "nftables service is not running"
log_message "INFO" "Starting nftables service..."
systemctl start nftables
if systemctl is-active --quiet nftables; then
log_message "INFO" "nftables service started successfully"
else
log_message "CRITICAL" "Failed to start nftables service"
exit 1
fi
fi
# Verify firewall rules are loaded
if ! nft list ruleset >/dev/null 2>&1; then
log_message "ERROR" "No firewall rules are loaded"
log_message "INFO" "Loading firewall rules..."
if nft -f "$FIREWALL_CONFIG"; then
log_message "INFO" "Main firewall rules loaded successfully"
# Load additional rule files
for rule_file in "$RULES_DIR"/*.nft; do
if [ -f "$rule_file" ]; then
log_message "INFO" "Loading rules from $(basename "$rule_file")"
nft -f "$rule_file"
fi
done
else
log_message "CRITICAL" "Failed to load firewall rules"
exit 1
fi
fi
# Verify critical rules are in place
CRITICAL_RULES=(
"iifname \"lo\" accept"
"ct state established,related accept"
"tcp dport 22 accept"
"udp dport 51820 accept"
)
for rule in "${CRITICAL_RULES[@]}"; do
if nft list ruleset | grep -q "$rule"; then
log_message "DEBUG" "Critical rule verified: $rule"
else
log_message "WARNING" "Critical rule missing: $rule"
fi
done
# Check for potential firewall bypasses
log_message "INFO" "Checking for potential firewall bypasses"
# Check for raw socket usage
if netstat -anp 2>/dev/null | grep -q "raw"; then
log_message "WARNING" "Raw sockets detected - potential firewall bypass"
fi
# Check for iptables conflicts
if iptables -L >/dev/null 2>&1 && [ "$(iptables -L | wc -l)" -gt 6 ]; then
log_message "WARNING" "iptables rules detected - potential conflict with nftables"
fi
# Test basic connectivity through firewall
log_message "INFO" "Testing basic firewall functionality"
# Test loopback
if ping -c 1 -W 1 127.0.0.1 >/dev/null 2>&1; then
log_message "DEBUG" "Loopback connectivity test passed"
else
log_message "WARNING" "Loopback connectivity test failed"
fi
# Test that basic blocking works (if we can determine an unreachable port)
# This is a simple test - adjust as needed for your environment
if timeout 2 bash -c "echo >/dev/tcp/192.0.2.1/80" 2>/dev/null; then
log_message "WARNING" "Unexpected connectivity to test destination - check firewall rules"
else
log_message "DEBUG" "Basic blocking test passed (expected failure)"
fi
# Save current rules for persistence
if systemctl is-active --quiet nftables; then
log_message "INFO" "Saving firewall rules for persistence"
# Create backup of current rules
mkdir -p /var/backups/firewall
nft list ruleset > "/var/backups/firewall/ruleset_$(date +%Y%m%d_%H%M%S).nft"
log_message "INFO" "Firewall rules backed up successfully"
else
log_message "ERROR" "Cannot save rules - nftables service not running"
fi
# Report status
if systemctl is-active --quiet nftables && nft list ruleset >/dev/null 2>&1; then
log_message "INFO" "Firewall persistence check completed successfully"
exit 0
else
log_message "CRITICAL" "Firewall persistence check failed"
exit 1
fi
EOF
# Make persistence script executable
chmod 750 /usr/local/bin/firewall-persistence.sh
chown root:root /usr/local/bin/firewall-persistence.sh
# Create systemd service for firewall persistence
cat > /etc/systemd/system/firewall-persistence.service << 'EOF'
[Unit]
Description=Firewall Persistence Check
Documentation=man:nftables(8)
After=network.target nftables.service
Wants=nftables.service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/firewall-persistence.sh
StandardOutput=journal
StandardError=journal
# Security settings
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/var/log/security /var/lock
PrivateTmp=yes
[Install]
WantedBy=multi-user.target
EOF
# Create systemd timer for periodic checks
cat > /etc/systemd/system/firewall-persistence.timer << 'EOF'
[Unit]
Description=Run firewall persistence checks every 15 minutes
Requires=firewall-persistence.service
[Timer]
OnCalendar=*:0/15
Persistent=true
[Install]
WantedBy=timers.target
EOF
# Configure nftables service
cat > /etc/default/nftables << 'EOF'
# Configuration for nftables
# Set to "yes" to load firewall rules on boot
STANDARD_SETUP="yes"
# Set to "yes" to save firewall rules on shutdown/reboot
STANDARD_CLEANUP="no"
# Additional options to pass to nft during startup
NFT_OPTIONS=""
EOF
# Create iptables to nftables compatibility (if needed)
cat > /usr/local/bin/iptables-legacy-save.sh << 'EOF'
#!/bin/bash
# Legacy iptables save script for compatibility
# Saves current iptables rules for backup purposes
mkdir -p /var/backups/iptables
iptables-save > "/var/backups/iptables/legacy_$(date +%Y%m%d_%H%M%S).rules"
echo "Legacy iptables rules saved"
EOF
chmod 750 /usr/local/bin/iptables-legacy-save.sh
chown root:root /usr/local/bin/iptables-legacy-save.sh
# Create firewall status script
cat > /usr/local/bin/firewall-status.sh << 'EOF'
#!/bin/bash
# Football System - Firewall Status Check
# Comprehensive firewall status reporting
echo "=== Football System Firewall Status ==="
echo "Time: $(date)"
echo ""
# Check nftables service status
echo "=== Service Status ==="
if systemctl is-active --quiet nftables; then
echo "✅ nftables service: Active"
else
echo "❌ nftables service: Inactive"
fi
if systemctl is-enabled --quiet nftables; then
echo "✅ nftables service: Enabled on boot"
else
echo "❌ nftables service: Disabled on boot"
fi
echo ""
# Check ruleset status
echo "=== Ruleset Status ==="
if nft list ruleset >/dev/null 2>&1; then
echo "✅ Ruleset: Loaded"
TOTAL_RULES=$(nft list ruleset | grep -c "accept\|drop")
echo "Total rules: $TOTAL_RULES"
else
echo "❌ Ruleset: Not loaded"
fi
echo ""
# Show key rules
echo "=== Key Security Rules ==="
nft list ruleset | grep -E "(lo|ssh|wireguard|established)" | head -10
echo ""
# Check for recent firewall log entries
echo "=== Recent Firewall Log Entries ==="
if journalctl -u nftables --since "1 hour ago" | grep -q "NFT"; then
journalctl -u nftables --since "1 hour ago" | grep "NFT" | tail -5
else
echo "No recent firewall log entries"
fi
echo ""
# Check persistence timer status
echo "=== Persistence Monitoring ==="
if systemctl is-active --quiet firewall-persistence.timer; then
echo "✅ Persistence timer: Active"
NEXT_RUN=$(systemctl list-timers firewall-persistence.timer --no-pager | grep "n/a" -A 1 | tail -1 | awk '{print $1,$2,$3,$4}')
echo "Next run: $NEXT_RUN"
else
echo "❌ Persistence timer: Inactive"
fi
echo ""
# Network interface status
echo "=== Network Interface Status ==="
ip addr show | grep -E "(state|inet)" | grep -v "127.0.0.1"
echo ""
# Show active connections
echo "=== Recent Active Connections ==="
ss -tuln | head -10
echo "=== End Firewall Status ==="
EOF
chmod 750 /usr/local/bin/firewall-status.sh
chown root:root /usr/local/bin/firewall-status.sh
# Enable and start services
systemctl daemon-reload
systemctl enable nftables
systemctl start nftables
systemctl enable firewall-persistence.timer
systemctl start firewall-persistence.timer
# Load firewall rules
echo "Loading firewall rules..."
if nft -f /etc/nftables.conf; then
echo "✅ Main firewall rules loaded successfully"
else
echo "❌ Failed to load main firewall rules"
exit 1
fi
# Load additional rule files
for rule_file in /etc/nftables.conf.d/*.nft; do
if [ -f "$rule_file" ]; then
echo "Loading rules from $(basename "$rule_file")"
if nft -f "$rule_file"; then
echo "✅ Rules from $(basename "$rule_file") loaded successfully"
else
echo "❌ Failed to load rules from $(basename "$rule_file")"
fi
fi
done
# Run initial persistence check
if /usr/local/bin/firewall-persistence.sh; then
echo "✅ Firewall persistence check completed successfully"
else
echo "⚠️ Firewall persistence check completed with warnings"
fi
# Create firewall log rotation
cat > /etc/logrotate.d/firewall << 'EOF'
# Football System - Firewall Log Rotation
/var/log/security/firewall-persistence.log {
weekly
rotate 52
compress
delaycompress
missingok
notifempty
create 0640 root adm
sharedscripts
postrotate
systemctl reload rsyslog >/dev/null 2>&1 || true
endscript
}
/var/backups/firewall/*.nft {
monthly
rotate 12
compress
delaycompress
missingok
notifempty
}
EOF
chmod 644 /etc/logrotate.d/firewall
chown root:root /etc/logrotate.d/firewall
# Display firewall status
echo ""
echo "=== Firewall Configuration Summary ==="
echo "✅ nftables service enabled and started"
echo "✅ Firewall rules loaded from /etc/nftables.conf"
echo "✅ Additional rules loaded from /etc/nftables.conf.d/"
echo "✅ Persistence monitoring enabled (runs every 15 minutes)"
echo "✅ Status script available: /usr/local/bin/firewall-status.sh"
echo "✅ Log rotation configured"
echo ""
echo "Key firewall ports allowed:"
echo "- SSH (22): Remote management"
echo "- WireGuard (51820): VPN access"
echo "- VNC (5900-5901): Remote desktop"
echo "- ICMP (limited): Network diagnostics"
echo ""
echo "Run 'firewall-status.sh' for detailed status"
echo "✅ Firewall persistence configuration completed"