How to Migrate UFW Firewall Rules Between Linux Servers (Complete Guide)


1 views

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