Reassociating an address takes a minute. The week after is where the move breaks, and rarely where the provider console suggests. A new public IP is referenced in four places: the socket the daemon listens on, the trust anchor clients verify, every rule that names the old address, and the DNS record tying them together. Two moves look identical from a control panel but behave nothing alike: reassigning the address on the machine you run, or standing up a second endpoint and moving clients onto it. The checks below put the cheap failures first, and each section names which move it applies to.

In-place swap and parallel cutover are different jobs

An in-place swap keeps the host, the keys, the routing table and the user list; only the address changes. That is what a floating IP reassociation does, and on several providers the guest never notices, because translation happens in front of the instance. A rebuild or provider reassignment is harsher: the guest sees the change, and everything that cached the old value learns it at the same moment.

A parallel endpoint is a second host doing the same job. Build it, test it with one profile, and leave the old one answering until the new one proves itself over a real path. The price is state. Without shared peer entries, revocations and logging, you have two networks that happen to share a name.

QuestionIn-place swapParallel endpoint
Rollback in one step?Only if you can get the old address backPoint DNS back; old host still up
Blast radiusEvery client at onceOnly the clients you moved
Best whenThe address is yours to reassignThe old address is gone for good

Find every place the old address is written down

Start with a text sweep, because configuration files are the easy half. Search the daemon config, firewall fragments, monitoring targets and any generated client bundle on disk. Include the IPv6 address if you publish one; a move that follows only the A record leaves dual-stack clients on the old path.

OLD=203.0.113.10
grep -RIn -- "$OLD" /etc /root
ss -lunpt | grep -F "$OLD"
nft list ruleset | grep -F "$OLD"
iptables-save | grep -F "$OLD"
wg show all endpoints

Then sweep the kernel, because a running system holds the address in places no file mentions. A static source NAT rule, an ipset entry, a bind address and a conntrack entry outlive the config edit that removed them, and some outlive a reboot because they came back from a saved ruleset. One layer up, provider security groups, load balancer targets and monitoring checks are not on your filesystem at all.

Write the inventory down before you change anything; it doubles as the rollback script.

Hostname clients recover; literal-IP clients go quiet

If clients reach the server by hostname, the cutover is mostly a DNS problem, and the TTL you set yesterday decides how bad it gets. Resolvers cache, stub resolvers cache again, and many clients only look the name up on a new connection, so an established tunnel keeps its starting address.

If the endpoint is a literal address, nothing re-resolves and nothing logs a complaint. WireGuard stores a resolved socket address: Endpoint = vpn.example.net:51820 becomes an IP the moment wg-quick up runs and stays that IP until you change it. OpenVPN is more forgiving: it resolves the remote hostname at connect time and, with resolv-retry infinite, tries DNS again on reconnect. Given a literal IP, both keep dialling a machine that no longer exists.

What misleads people is the mirror image. A client already pointed at the new address, while the old listener still answers, passes every test you run from your own desk. I have been fooled by that: the new endpoint came up on a phone in one try, and a client on a stale profile only surfaced when the old listener was shut off much later.

Trust does not move with the address

WireGuard separates identity from reachability, which makes an address move almost free. Peers are identified by public key, and the endpoint is only where packets currently go; a host updates a peer's endpoint from the source address of the most recent authenticated packet. An idle peer still needs a reason to talk to the new place, and it learns the address only when its session ages out and the handshake retries fail somewhere visible. The WireGuard quickstart covers the endpoint field.

TLS-based servers are the opposite case. The certificate is bound to a name, and a client that dials an address compares what it dialled against the subject alternative names. Connect by IP to a certificate carrying only a DNS SAN and verification fails: the name the client used is not in the certificate. Reissuing with an IP SAN fixes that one connection and makes the next move worse. Keeping a hostname in the profile and leaving verify-x509-name in place keeps the check strict while the address underneath changes.

Then check what the daemon is bound to; a socket pinned to the old address fails silently. An OpenVPN server started with local 203.0.113.10 refuses to come up once that address is gone, while a listener on 0.0.0.0 follows the change for free. NAT splits the same way: MASQUERADE follows whatever address the box now has, and a static SNAT --to-source 203.0.113.10 keeps rewriting to an address you no longer own, so return traffic vanishes. If the new address comes with a different upstream gateway, check rp_filter: reverse-path filtering drops return traffic arriving on an interface the kernel did not expect.

Cutover order and the evidence that it worked

Lower the TTL a day ahead, stand the new listener up, and prove it with a profile that only you hold. A test from inside the same network proves almost nothing, so use a phone on cellular and test something the tunnel is meant to carry rather than a ping to the endpoint.

Watch both addresses through the window. wg show all latest-handshakes on the new host, or the OpenVPN status file, tells you how many peers have actually moved. When the new endpoint has the peers you expect and the old one has only stragglers, retire the old listener, remove the stale NAT rule and drop the address from the provider firewall. Removing the old listener is the step that gets skipped, and it closes the gap where a stale profile still reaches the old network.

Set the rollback trigger in writing before you begin: if the new endpoint has no handshake from a single real client after the agreed window, restore the old address and stop distributing profiles. Re-run the sweep afterwards and confirm that no listener is still bound to a retired address. Two things carry forward into the next move, a hostname in the client profile so the following change is a DNS edit, and the inventory stored beside the server's recovery notes.

Artitgels cun il medem tema