When performing server migrations or hardware upgrades, transferring UFW (Uncomplicated Firewall) rules often becomes a pain point. Unlike some other firewall solutions, UFW doesn't provide a single-command export/import feature, which leads to manual rule recreation headaches.
The most reliable approach is to copy UFW's configuration files between servers:
# On source server: sudo cp /etc/ufw/{user.rules,user6.rules,before.rules,before6.rules,after.rules,after6.rules} /tmp/ sudo chown $USER:$USER /tmp/*.rules # On destination server (after transferring files): sudo cp *.rules /etc/ufw/ sudo ufw disable sudo ufw enable
Important: Always test rules with sudo ufw --dry-run enable
before applying them to production servers.
For more controlled migrations, consider using the community-developed ufw-dump
tool:
# Install on source server: sudo apt install git -y git clone https://github.com/xyproto/ufw-dump.git cd ufw-dump make sudo ./ufw-dump > ufw_rules.backup # On destination server: while read line; do sudo ufw $line done < ufw_rules.backup
When migrating between different Linux distributions or versions:
# Convert Debian/Ubuntu rules to work on RHEL: sudo ufw show raw | grep -E '^ufw' | sed 's/^ufw //' > rules.txt # Then manually review for distro-specific syntax differences
Always validate the migration:
# Compare rule counts: sudo ufw status numbered | wc -l # Check for syntax errors: sudo ufw --dry-run enable sudo tail -f /var/log/ufw.log
For frequent migrations, create a transfer script:
#!/bin/bash # ufw-migrate.sh SOURCE_IP="192.168.1.100" TEMP_DIR="/tmp/ufw_migrate_$(date +%s)" mkdir -p $TEMP_DIR scp root@$SOURCE_IP:/etc/ufw/*.rules $TEMP_DIR/ sudo cp $TEMP_DIR/*.rules /etc/ufw/ # For atomic changes sudo ufw disable sudo ufw --force enable sudo rm -rf $TEMP_DIR
UFW (Uncomplicated Firewall) rules are stored in several locations:
/etc/ufw/user.rules
/etc/ufw/user6.rules
/etc/ufw/before.rules
/etc/ufw/before6.rules
/etc/ufw/after.rules
/etc/ufw/after6.rules
The most reliable method is to copy all configuration files:
sudo tar -cvzf ufw_rules_backup.tar.gz /etc/ufw/*.rules
For just the active rules (IPv4 only):
sudo ufw status numbered > ufw_active_rules.txt
After creating the backup, transfer it using scp:
scp ufw_rules_backup.tar.gz user@newserver:/tmp/
First, back up existing rules on the new server:
sudo mv /etc/ufw /etc/ufw.bak
sudo mkdir /etc/ufw
Then extract the backup:
sudo tar -xvzf /tmp/ufw_rules_backup.tar.gz -C /
For automated environments, use this bash script:
#!/bin/bash
# Export rules
OLD_IP="192.168.1.100"
NEW_IP="192.168.1.101"
ssh root@$OLD_IP "ufw status numbered | grep -oP '(?<=$$)\d+(?=$$)' | \
xargs -I {} sh -c 'ufw status numbered | grep \"^{}\" | \
sed \"s/^\$$.*\$$//\"'" > ufw_rules_export.txt
# Process and import
while read -r rule; do
# Replace old server IP if present
cleaned_rule=${rule//$OLD_IP/$NEW_IP}
sudo ufw $cleaned_rule
done < ufw_rules_export.txt
After importing, verify with:
sudo ufw status verbose
sudo systemctl restart ufw
sudo ufw enable
If you've defined application profiles:
sudo cp -r /etc/ufw/applications.d /etc/ufw/applications.d.bak
sudo scp -r user@oldserver:/etc/ufw/applications.d/* /etc/ufw/applications.d/
If rules don't apply correctly:
# Check for syntax errors
sudo ufw --dry-run enable
# Examine logs
sudo tail -f /var/log/ufw.log
# Reset if needed
sudo ufw reset
- Always test rules in non-production first
- Consider using configuration management tools (Ansible/Puppet)
- Document all custom rules with comments
- Maintain rule versioning using Git