A Python script that automates the process of updating Proxmox firewall IPSets and aliases based on DNS entries. This ensures firewall configurations remain synchronized with DNS changes, enhancing security and network management.
- Proxmox Firewall Updater
The script identifies firewall objects (IPSets and aliases) with special comments containing domain names, then updates them with the resolved IP addresses. Configuration is done by adding comments to firewall objects:
#resolve=example.com
Feature | IPSets | Aliases |
---|---|---|
Multiple IPs | ✅ Supports all resolved IPs | ❌ Only first IP |
Multiple domains | ✅ Comma-separated list | ❌ Only first domain |
Alias references | ✅ Preserves dc/ and guest/ entries |
❌ Not applicable |
Use case | Load-balanced services, CDNs | Single-endpoint APIs, re-use (reference) in IPSets |
- Automatic DNS synchronization - Updates only when IP addresses change
- Multiple query support - Captures all IPs from DNS round-robin
- Custom DNS servers - Per-entry or global DNS configuration
- Dry-run mode - Test changes without applying them
- Comprehensive logging - Detailed operation logs via syslog
curl https://raw.githubusercontent.com/base23gmbh/proxmox-firewall-updater/main/update_firewall.py -o update_firewall.py \
&& install -g root -o root -m 750 ./update_firewall.py /usr/local/sbin/pve-firewall-dns-updater \
&& rm ./update_firewall.py
(crontab -l 2>/dev/null; echo "*/5 * * * * /usr/bin/env python3 /usr/local/sbin/pve-firewall-dns-updater 2>&1 | logger -t pve-firewall-dns-updater") | crontab -
echo "while true; do (python3 /usr/local/sbin/pve-firewall-dns-updater | logger -t pve-firewall-dns-updater); sleep 300; done" > firewall_updater_forever.sh
chmod +x firewall_updater_forever.sh
(crontab -l 2>/dev/null; echo "@reboot /bin/bash -c $(pwd)/firewall_updater_forever.sh &") | crontab -
Start immediately without reboot:
/bin/bash -c ./firewall_updater_forever.sh &
Add comments to IPSets or aliases in the Proxmox web interface:
#resolve=domain1.com,domain2.com #queries=3 #delay=5 #dns-servers=8.8.8.8
Option | Data type | Description | Default | Examples |
---|---|---|---|---|
#resolve= |
List of Strings | Domain(s) to resolve (comma-separated) | Required | example.com,backup.example.com |
#queries=N |
Integer | Number of DNS queries per domain | 1 |
#queries=3 |
#delay=N(.N) |
Float | Delay between queries (seconds) | 3 |
#delay=0.1 |
#dns-servers= |
List of Strings | Custom DNS servers (comma-separated) | System DNS | - Example 1:8.8.8.8,1.1.1.1 - Example 2: system (system is using the system DNS servers, even when other DNS servers have been passed via the cli variable --dns-servers ) |
- Navigate to Datacenter → Firewall → IPSets
- Click Create and enter a name
- Add comment:
#resolve=example.com
- Save the IPSet
- Navigate to Datacenter → Firewall → Aliases
- Click Create and enter a name
- Add comment:
#resolve=api.example.com
- Save the Alias
Scenario | Type | Configuration |
---|---|---|
Single API endpoint | Alias | #resolve=api.example.com |
Proxmox APT Mirror | IPSet | #resolve=download.proxmox.com #queries=3 #delay=0.1 #dns-servers=1.1.1.1,8.8.8.8,9.9.9.9 |
Load-balanced service | IPSet | #resolve=web.example.com #queries=3 |
Multi-region service | IPSet | #resolve=us.service.com,eu.service.com |
Internal service | IPSet | #resolve=internal.service.com #dns-servers=192.168.1.10 |
CDN with round-robin | IPSet | #resolve=cdn.example.com #queries=5 #delay=2 |
pve-firewall-dns-updater [OPTIONS]
Option | Description |
---|---|
--dry-run |
Show changes without applying them |
--verbose |
Enable detailed logging |
--ipsets |
Update only IPSets |
--aliases |
Update only aliases |
--all |
Update both (default) |
--version |
Show version information |
--dns-servers |
Global custom DNS servers |
# Test run with detailed output
pve-firewall-dns-updater --dry-run --verbose
# Update only IPSets with custom DNS
pve-firewall-dns-updater --ipsets --dns-servers 8.8.8.8 1.1.1.1
# Update aliases only
pve-firewall-dns-updater --aliases --verbose
# Real-time logs
journalctl -xef -t pve-firewall-dns-updater
# Recent logs
journalctl -t pve-firewall-dns-updater --since "1 hour ago"
For services using DNS round-robin or load balancing:
#resolve=load-balanced.example.com #queries=5 #delay=2
This performs 5 DNS queries with 2-second delays, collecting all unique IP addresses.
pve-firewall-dns-updater --dns-servers 8.8.8.8 1.1.1.1 9.9.9.9
#resolve=internal.company.com #dns-servers=192.168.1.10,192.168.1.11
- Comment DNS servers (
#dns-servers=
) - Highest priority - CLI DNS servers (
--dns-servers
) - Medium priority - System DNS servers - Fallback
#dns-servers=system
- Force system DNS, ignore CLI options
The old syntax is still supported:
# Old syntax (still works)
#resolve: example.com
# New syntax (preferred)
#resolve=example.com
-
Enable verbose logging:
pve-firewall-dns-updater --verbose --dry-run
-
Test domain resolution:
nslookup example.com dig @8.8.8.8 example.com A
-
Try custom DNS servers:
pve-firewall-dns-updater --dns-servers 8.8.8.8 1.1.1.1 --verbose
Problem | Solution |
---|---|
No IP changes detected | Domain might not use round-robin; try #queries=3 |
Custom DNS not working | dig is required, install dnsutils : e.g. apt-get install dnsutils |
Alias references lost | Ensure using version 3.4.0+ |
Script not running | Check cron job and file permissions |
# Google DNS
pve-firewall-dns-updater --dns-servers 8.8.8.8 8.8.4.4
# Cloudflare DNS
pve-firewall-dns-updater --dns-servers 1.1.1.1 1.0.0.1
# Quad9 DNS
pve-firewall-dns-updater --dns-servers 9.9.9.9 149.112.112.112
Run the automated test suite:
python3 -m unittest update_firewall_test.py
# Get IPSets
pvesh get cluster/firewall/ipset --output-format json
# Get Aliases
pvesh get cluster/firewall/aliases --output-format json
# Create IPSet
pvesh create cluster/firewall/ipset --name ipset_example --comment "#resolve=example.com"
# Add IPSet entry
pvesh create cluster/firewall/ipset/ipset_example --cidr 1.2.3.4
# Update alias
pvesh set cluster/firewall/aliases/alias_example --cidr 1.2.3.4 --comment "#resolve=example.com"
- Proxmox VE API Documentation
- Proxmox Forum Discussion
- Original script by @simonegiacomelli
Note: The script only updates entries when IP addresses change to minimize logging and system impact.