Update #11 - Syncthing UFW DDNS Cron Recovery & Long-Term Rule Persistence Date: May 11, 2025 Category: Security / Automation Backlink: Update #10 – Fail2Ban IP Geolocation Lookup Script with Auto-Filtering Overview This update builds upon our existing Syncthing and UFW/DDNS configuration and addresses the issue of persistent firewall rules disappearing after system events such as upgrades or restarts. It introduces mechanisms to automatically recover and persist UFW rules linked to DDNS-resolved IPs, as well as implement log rotation for our custom scripts. Problem Summary UFW rules allowing DDNS-bound access to Syncthing ports (8384, 22000, 21027) were occasionally disappearing. There was no persistent re-application of these rules on reboot or after package upgrades. A need existed to reduce log file size growth from regular UFW rule updates. Key Changes Implemented 1. Syncthing DDNS-based UFW Script Improvements Script Path: /usr/local/bin/update-syncthing-ufw.sh Now includes: Cleanup of old rules Re-application of DDNS-resolved IP IPv6 exception handling Console output when run manually Logged output when run via cron #!/bin/bash DDNS_HOST="your-ddns.example.com" PORTS=(8384/tcp 22000/tcp 21027/udp) LOG_TAG="Syncthing DDNS Access" # Resolve IP IP=$(dig +short "$DDNS_HOST" | grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' | head -n1) if [[ -z "$IP" ]]; then echo "❌ Failed to resolve IP for $DDNS_HOST" exit 1 fi # Clean up existing rules for this tag for port in "${PORTS[@]}"; do ufw status numbered | grep "$LOG_TAG" | grep "$port" | awk -F'[][]' '{print $2}' | tac | while read -r num; do ufw --force delete "$num" done done # Add new rules for port in "${PORTS[@]}"; do ufw allow from "$IP" to any port "${port%/*}" proto "${port##*/}" comment "$LOG_TAG" done echo "✅ Cleaned and updated UFW rules for Syncthing from $IP" 2. Cron Automation for Rule Recovery Location: sudo crontab -e Jobs Added: # Run daily at 3:00 AM 0 3 * * * /usr/local/bin/update-syncthing-ufw.sh # Run every 10 minutes, prevents overlapping runs */10 * * * * flock -n /tmp/ufw-ddns.lock /usr/local/bin/update-syncthing-ufw.sh >> /var/log/update-syncthing-ufw.log 2>&1 # Run on reboot @reboot /usr/local/bin/update-syncthing-ufw.sh >> /var/log/update-syncthing-ufw.log 2>&1 3. Logrotate Setup for UFW Update Logs File: /etc/logrotate.d/update-syncthing-ufw Content: /var/log/update-syncthing-ufw.log { su root root daily rotate 7 compress missingok notifempty create 644 root root } Additional Files and Paths Script Path Syncthing DDNS UFW Script /usr/local/bin/update-syncthing-ufw.sh Cron Log File /var/log/update-syncthing-ufw.log Logrotate Config /etc/logrotate.d/update-syncthing-ufw Testing Verified successful rule refresh via sudo ufw status Confirmed script logs rotation using logrotate --debug Confirmed cron execution via grep update-syncthing-ufw /var/log/syslog Script executes correctly manually and via cron. Conclusion This update ensures that DDNS-based access to Syncthing is consistently maintained with automatic recovery and no risk of bloat from excessive log growth. The solution is now reliable through reboots, daily updates, and in the event of system changes like package upgrades