Address plans that say 'this laptop gets 10.90.0.10' are really statements about identity: which authenticated device may hold that address. The current public IP of that device has almost nothing to do with it, because NAT and roaming change it without changing who the user is. Building the plan on the source address produces rules that break on the first hotel network. Building it on the authenticated identity produces a plan that survives travel.

Start from what the server can verify, then decide what the address is for.

Pick the identity key before the address

A separate client certificate per device gives the server a stable, verifiable key for each member, which is the cleanest basis for a static assignment. A deployment using per-user authentication can key on the username instead, as long as the configuration selection follows the same field. Mixing the two models produces assignments that match a certificate for one client and a username for another, and nobody can predict which one wins. Decide which key the plan uses before writing a single reservation.

With duplicate-cn, several simultaneous sessions can present the same common name, so one pinned address cannot identify them individually. That is a property of the identity model, not something a better address plan can fix.

Reserve addresses outside the dynamic range

In a subnet-topology network such as 10.90.0.0/24, keep the low addresses for named members and put the dynamic pool in a disjoint range. An assignment for a pinned member looks like ifconfig-push 10.90.0.10 255.255.255.0 in the file the server selects for that identity. The second argument means something different under net30, so the example is not topology-neutral. Read the topology before copying it.

Pool persistence records recent leases and tends to hand the same address back, which is a convenience rather than a reservation. Do not let the persistence file become the record of ownership, because it changes with connection history rather than with policy.

Assignment precedence decides who wins

The manual documents an order: an explicit assignment generated during client-connect can take effect before a client-config-dir entry, which in turn precedes ordinary pool allocation. That ordering explains most 'the pinned address did not apply' reports. It also means a dynamic allocator that writes per-session configuration can silently override a static file you thought was authoritative.

Choose one layer to own assignments and make the others read-only. Two layers that both claim to decide produce assignments that depend on timing.

A dynamic allocator needs the same model

A client-connect integration that hands out addresses per session is a small allocator with the usual allocator problems. It has to validate the requesting identity, reserve an address atomically, emit only the supported per-connection output, and release the reservation on disconnect or failure. Concurrent requests need a lock or a database constraint, not a read-then-write sequence. Without cleanup, the pool leaks addresses until a restart.

Keep the allocator's state where the next operator can read it, and log the identity-to-address decision rather than only the address.

Decide whether the address is policy or convenience

If a firewall rule or a route allows traffic from one tunnel address, then the address participates in access policy and a reassignment inherits that permission. Coordinate the identity, address and firewall lifecycle, or key the rule on something that cannot be reassigned. Stable addressing makes the configuration readable; it does not replace authentication.

Write the plan as an inventory with an owner per entry, then review it when a device is retired. The unused reservation is the one that gets reused by accident.

ဆက်စပ်ဆောင်းပါးများ