|
|
il y a 1 semaine | |
|---|---|---|
| bash | il y a 1 semaine | |
| .gitignore | il y a 1 semaine | |
| LICENSE | il y a 1 semaine | |
| README.md | il y a 1 semaine | |
| manage_ipset.conf | il y a 1 semaine | |
| manage_ipset.py | il y a 1 semaine |
Keep Proxmox cluster firewall IPSets in sync with DNS.
Hostnames are resolved repeatedly (A and AAAA) until no new IP addresses show up, so that all IPs behind a round-robin or anycast DNS record are collected. Afterwards the IPSet is synchronized: IPs that are gone are deleted, new IPs are added. Only the difference is written — no flush-and-refill.
One script, one config file. Python 3 standard library only — no pip
installs needed. Requires pvesh (from pve-manager) and dig
(from dnsutils) on the host.
Copy the script and the config to a Proxmox host (or any host with
pvesh access to the cluster), e.g. to /etc/pve:
cp manage_ipset.py manage_ipset.conf /etc/pve/
chmod +x /etc/pve/manage_ipset.py
manage_ipset.conf is looked up next to the script unless -c is
given.
# sync every IPSet from the config
./manage_ipset.py
# use a different config file
./manage_ipset.py -c /path/to/manage_ipset.conf
# sync a single IPSet directly
./manage_ipset.py github github.com github.io
./manage_ipset.py docker-io registry-1.docker.io --round 30
# every hour
0 * * * * /etc/pve/manage_ipset.py
manage_ipset.conf)[defaults]
round=50
stale_after=10
# dns_server=1.1.1.1 # optional, default: system resolver
# timeout=15
golang
host=go.dev
github
host=github.com
host=github.io round=10 stale_after=3
[defaults] section sets the global defaults. Optional.host=... adds a host to the current IPSet.
An IPSet may hold several hosts; their IPs are merged into one set.round, stale_after, dns_server,
timeout.# are comments.| Option | Meaning | Default |
|---|---|---|
round |
max. DNS query rounds per host | 50 |
stale_after |
rounds without a new IP before stopping early | 10 |
dns_server |
resolver to query (dig @server) |
system |
timeout |
dig timeout in seconds |
15 |
Hosts with many rotating IPs (big CDNs, registry-1.docker.io)
benefit from a higher round; round=1 behaves like a single query.
manage_ipset.py reads manage_ipset.conf and groups hosts by
IPSet.dig +short host A / AAAA is run up to round
times. As soon as stale_after consecutive rounds return no new
IP, the loop stops.pvesh get /cluster/firewall/ipset/<name> --output-format json).pvesh create ... --cidr), stale IPs are
removed (pvesh delete .../<ip>).If a host in an IPSet does not resolve, that IPSet is left untouched — a single broken hostname cannot strip the IPs of its siblings.
bash/ directory.GPLv3 — see LICENSE.
Copyright (C) 2026 Paul Klumpp