#!/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"