# Proxmox Firewall Migration Checklist

Use this checklist when copying firewall rules between two Proxmox servers that are not in the same cluster.

## 1. Prepare

- [ ] Confirm both servers run compatible Proxmox versions.
- [ ] Record the source node name and the target node name.
- [ ] Identify whether you need to migrate datacenter, node, VM, or container firewall rules.
- [ ] Schedule a maintenance window if the target is in production.
- [ ] Back up existing firewall configs on the target.

## 2. Inventory Source Rules

- [ ] Review datacenter rules in `/etc/pve/firewall/cluster.fw`.
- [ ] Review node rules in `/etc/pve/nodes/<source-node>/host.fw`.
- [ ] Review guest rules in `/etc/pve/firewall/<VMID>.fw`.
- [ ] Note any aliases, IP sets, security groups, macros, or logging rules in use.
- [ ] Note any interface names, bridges, VLAN tags, subnets, or management IPs referenced by rules.

## 3. Validate Target Compatibility

- [ ] Confirm the target uses the same or equivalent bridge/interface names.
- [ ] Confirm referenced VLANs and subnets exist on the target.
- [ ] Confirm required VMIDs and CTIDs exist on the target.
- [ ] Map any changed guest IDs so copied `<VMID>.fw` files can be renamed correctly.
- [ ] Check whether node-specific rules need updates for the new hostname or IP layout.

## 4. Back Up the Target

- [ ] Back up `/etc/pve/firewall/cluster.fw` if it exists.
- [ ] Back up `/etc/pve/nodes/<target-node>/host.fw` if it exists.
- [ ] Back up any existing `/etc/pve/firewall/<VMID>.fw` files that will be replaced.
- [ ] Save backups outside `/etc/pve` as well if you want easy rollback.

## 5. Copy the Files

- [ ] Copy `cluster.fw` only if you want datacenter-wide rules, aliases, IP sets, and security groups.
- [ ] Copy `host.fw` from the source node and rename it as needed for the target node.
- [ ] Copy only the guest `.fw` files that correspond to guests on the target.
- [ ] Rename guest firewall files if the target uses different VMIDs or CTIDs.

Example source paths:

```text
/etc/pve/firewall/cluster.fw
/etc/pve/nodes/<source-node>/host.fw
/etc/pve/firewall/<VMID>.fw
```

Example target paths:

```text
/etc/pve/firewall/cluster.fw
/etc/pve/nodes/<target-node>/host.fw
/etc/pve/firewall/<VMID>.fw
```

### Example Commands

Replace the placeholder values before running these commands.

Set variables on the source server:

```bash
SOURCE_NODE="pve-source"
TARGET_HOST="root@target-proxmox"
TARGET_NODE="pve-target"
BACKUP_DIR="/root/proxmox-fw-backup-$(date +%F-%H%M%S)"
```

Back up the target before copying anything:

```bash
ssh "$TARGET_HOST" "mkdir -p $BACKUP_DIR && cp -a /etc/pve/firewall $BACKUP_DIR/ && cp -a /etc/pve/nodes/$TARGET_NODE $BACKUP_DIR/"
```

Copy datacenter rules:

```bash
scp /etc/pve/firewall/cluster.fw "$TARGET_HOST:/root/cluster.fw"
```

Copy node rules from the source node:

```bash
scp "/etc/pve/nodes/$SOURCE_NODE/host.fw" "$TARGET_HOST:/root/host.fw"
```

Copy all guest firewall files:

```bash
scp /etc/pve/firewall/*.fw "$TARGET_HOST:/root/"
```

If you only want specific guest firewall files, copy them individually:

```bash
scp /etc/pve/firewall/100.fw "$TARGET_HOST:/root/"
scp /etc/pve/firewall/101.fw "$TARGET_HOST:/root/"
```

Place the files on the target server:

```bash
ssh "$TARGET_HOST" "cp /root/cluster.fw /etc/pve/firewall/cluster.fw"
ssh "$TARGET_HOST" "cp /root/host.fw /etc/pve/nodes/$TARGET_NODE/host.fw"
ssh "$TARGET_HOST" "cp /root/100.fw /etc/pve/firewall/100.fw"
```

If guest IDs changed, rename during the copy on the target:

```bash
ssh "$TARGET_HOST" "cp /root/100.fw /etc/pve/firewall/200.fw"
```

Validate and reload on the target:

```bash
ssh "$TARGET_HOST" "pve-firewall compile && systemctl restart pve-firewall && systemctl status pve-firewall --no-pager"
```

Rollback example:

```bash
ssh "$TARGET_HOST" "cp -a $BACKUP_DIR/firewall/* /etc/pve/firewall/ && cp -a $BACKUP_DIR/$TARGET_NODE/* /etc/pve/nodes/$TARGET_NODE/ && systemctl restart pve-firewall"
```

### Safer Staged Workflow

This approach copies files into `/root` on the target first, lets you compare them, and only then installs them into `/etc/pve`.

Create a staging directory on the target:

```bash
STAGE_DIR="/root/proxmox-fw-stage-$(date +%F-%H%M%S)"
ssh "$TARGET_HOST" "mkdir -p $STAGE_DIR"
```

Copy files into the staging directory instead of directly into place:

```bash
scp /etc/pve/firewall/cluster.fw "$TARGET_HOST:$STAGE_DIR/cluster.fw"
scp "/etc/pve/nodes/$SOURCE_NODE/host.fw" "$TARGET_HOST:$STAGE_DIR/host.fw"
scp /etc/pve/firewall/100.fw "$TARGET_HOST:$STAGE_DIR/100.fw"
```

Compare staged files against the current target config:

```bash
ssh "$TARGET_HOST" "diff -u /etc/pve/firewall/cluster.fw $STAGE_DIR/cluster.fw || true"
ssh "$TARGET_HOST" "diff -u /etc/pve/nodes/$TARGET_NODE/host.fw $STAGE_DIR/host.fw || true"
ssh "$TARGET_HOST" "diff -u /etc/pve/firewall/100.fw $STAGE_DIR/100.fw || true"
```

If needed, edit the staged files before installing them:

```bash
ssh "$TARGET_HOST" "nano $STAGE_DIR/host.fw"
ssh "$TARGET_HOST" "nano $STAGE_DIR/100.fw"
```

Install the reviewed staged files into `/etc/pve`:

```bash
ssh "$TARGET_HOST" "cp $STAGE_DIR/cluster.fw /etc/pve/firewall/cluster.fw"
ssh "$TARGET_HOST" "cp $STAGE_DIR/host.fw /etc/pve/nodes/$TARGET_NODE/host.fw"
ssh "$TARGET_HOST" "cp $STAGE_DIR/100.fw /etc/pve/firewall/100.fw"
```

Then compile and reload:

```bash
ssh "$TARGET_HOST" "pve-firewall compile && systemctl restart pve-firewall && systemctl status pve-firewall --no-pager"
```

Optional cleanup after validation:

```bash
ssh "$TARGET_HOST" "rm -rf $STAGE_DIR"
```

## 6. Review Before Enabling

- [ ] Compare source and target configs before overwriting files.
- [ ] Remove or update rules that reference old node names.
- [ ] Remove or update rules that reference missing interfaces, bridges, or VLANs.
- [ ] Remove or update rules that reference the wrong management subnet.
- [ ] Confirm any allow rules needed for SSH, web UI, cluster traffic, backup, and monitoring remain valid.

## 7. Apply and Reload

- [ ] Place the reviewed files into the correct `/etc/pve` locations.
- [ ] Run `pve-firewall compile` to catch syntax issues.
- [ ] Restart the firewall service with `systemctl restart pve-firewall`.
- [ ] Verify the firewall service starts cleanly without errors.

## 8. Post-Migration Validation

- [ ] Confirm access to the Proxmox web UI still works.
- [ ] Confirm SSH access still works.
- [ ] Confirm guest traffic behaves as expected.
- [ ] Confirm required inbound and outbound ports are open.
- [ ] Check firewall logs for unexpected drops.
- [ ] Test one VM and one container if both are in scope.

## 9. Rollback Plan

- [ ] Keep console or out-of-band access available before applying changes.
- [ ] Restore the target backup files if connectivity breaks.
- [ ] Restart `pve-firewall` after restoring backups.
- [ ] Re-test management access and guest connectivity.

## Notes

- `cluster.fw` can contain datacenter rules, aliases, IP sets, and security groups.
- `host.fw` is node-specific and usually needs the most review.
- Guest firewall files only apply if the corresponding guest exists and firewall is enabled for it.
- Copying configs between non-clustered hosts is supported as a file-based migration, but it is not topology-aware, so review carefully.
