Replaces it with why the remaining segments have no eligible hosts: two are appliance-only and three have no IPv6 enabled yet, pending the firewall-policy pass that SLAAC on a client segment would require.
7.5 KiB
ESH IPv6 naming scheme
Every ESH LAN carries an eight-hex-digit phrase as the first half of the interface identifier. Picked 2026-08-18/19. This file is the canonical record.
Why this file exists. The scheme originally lived as a single line in
persistent-memory.mdand was silently deleted by amemory: snapshotcommit (837fa36). Recovering it took a hunt through session transcripts to find the commit that had held it. A naming convention is not temporal state — it belongs in a document, so it now is one.
The names
| network | hex | reads as |
|---|---|---|
Default |
4BA5:3417 |
A BASE FOR IT |
esh-mgmt |
15DA:B055 |
IS DA BOSS |
esh-server |
4411:B105 |
FOR ALL BIOS |
esh-userland |
CAFE:4411 |
CAFE FOR ALL |
esh-iot |
4DBA:D107 |
FOR DA BAD IOT |
esh-cameras |
1533:FACE5 |
I SEE FACES |
| (reserved) DMZ | 4411:DBAD |
FOR ALL DA BAD |
The DMZ name is claimed against a network that does not exist yet — there is no DMZ on the ESH UDM. Do not reuse it.
Substitutions are the standard hexspeak set: 0→O, 1→I/L, 5→S, plus letters
that are already native hex (A–F). Anything outside 0-9a-f is not
expressible — b0ss and c00l do not work, which is why the set above uses
B055 and avoids c00l entirely.
House style, arrived at rather than designed: eight digits, and a complete
phrase rather than a single word. Words are allowed to straddle the group
boundary (4DBA:D107 is 4·D·BAD·107); the phrase reads through the colon.
Address structure
2607:73c0:402:1d02 : 4411:b105 : 50 : 45
└──── ISP /64 ────┘ └ segment ─┘ └ 10.0.50.45 ┘
- Prefix — Cityside's, not ours to name. ESH holds a
/56(2607:73c0:402:1d00::/56, 256 × /64); the subnet id is assigned by UniFi'sipv6_pd_prefixid.esh-camerasis1d00,esh-serveris1d02. - Segment word pair — 32 bits, from the table above.
- Host — the last two IPv4 octets, written as literal digits so they read
straight off the address.
10.0.50.45→:50:45.
The scheme lives entirely in the interface identifier, so it is
delegation-size independent. It works identically on a /56, a /48, or
NH3's single /64. It never competes with the subnet id, which is far too small
to hold a word (8 bits at ESH — two hex digits).
Note: 4411:b105:50:45 fills all four host groups, so there is no :: in
these addresses. Writing ...::4411:b105:50:45 is malformed and will be
rejected.
What can and cannot carry a name
| slot | nameable? |
|---|---|
/64 subnet id (ipv6_pd_prefixid) |
No — 8 bits at ESH, two hex digits, no room for a word |
| the gateway's own address | No — fixed at ::1 by UniFi, no field for it |
| a UniFi client reservation | No — UniFi has no IPv6 equivalent of use_fixedip |
| a host taking its own address | Yes — this is the one that works |
⚠ The original note concluded these names could never appear in a dig or
ip -6 output. That is wrong. The first three rows are correct, but they only
establish that UniFi cannot assign the address. A Linux host can simply take
one within its own advertised prefix, and the router gets no vote. Appliances
with no shell — cameras, most IoT — genuinely cannot, so 1533:FACE5 and
4DBA:D107 are likely to stay documentation-only.
Applying it to a host
Do not use an iface … inet6 static stanza: on Debian that sets
accept_ra=0, killing SLAAC and the IPv6 default route — a good way to strand a
headless box. Use an if-up.d hook that derives the live prefix instead.
Live example, /etc/network/if-up.d/ipv6-scheme-addr on esh-docker-vm:
#!/bin/sh
[ "$IFACE" = ens18 ] || exit 0
(
i=0
while [ $i -lt 30 ]; do
PFX=$(ip -6 -o addr show dev "$IFACE" scope global 2>/dev/null \
| awk '{print $4}' | cut -d/ -f1 | head -1 | cut -d: -f1-4)
if [ -n "$PFX" ]; then
ip -6 addr replace "${PFX}:4411:b105:50:45/64" dev "$IFACE" && exit 0
fi
sleep 2
i=$((i + 1))
done
) >/dev/null 2>&1 &
exit 0
Three deliberate properties:
- The prefix is derived, never hardcoded — self-heals if Cityside re-delegates.
- Backgrounded with a retry — SLAAC may not have landed when
if-up.druns, and a hook that blocks or fails would stall interface bring-up. - Additive —
/etc/network/interfacesalready sourcesinterfaces.d/; nothing existing is edited, and removal is onerm.
Remaining gap: a mid-life prefix change is only picked up at the next interface-up. A timer would close it; not worth building until the prefix is observed to actually move.
Deployed
All three Linux hosts on esh-server now carry the segment name, with the last
two groups reading straight off their IPv4 address:
| host | address | v4 | applied via |
|---|---|---|---|
esh-docker-vm (AdGuard) |
2607:73c0:402:1d02:4411:b105:50:45 |
10.0.50.45 | if-up.d on ens18 |
esh-pve-nas |
2607:73c0:402:1d02:4411:b105:50:55 |
10.0.50.55 | if-up.d on vmbr0 |
esh-vm-db |
2607:73c0:402:1d02:4411:b105:50:60 |
10.0.50.60 | if-up.d on ens18 |
esh-docker-vm's is load-bearing, not decorative: the ESH UDM advertises an
IPv6 resolver to clients via RDNSS, macOS prefers it over the DHCPv4-supplied
one, so whatever sits there is what resolves *.internal for every Mac on the
network. It previously pointed at AdGuard's MAC-derived SLAAC address, which
would have broken if that VM's NIC ever changed. Both esh-userland and
esh-server now advertise the scheme address instead
(dhcpdv6_dns_auto=false + dhcpdv6_dns_1=<address>), verified on the wire by
soliciting an RA and parsing option type 25.
⚠ Proxmox bridges need accept_ra=2 or SLAAC never runs
esh-pve-nas had link-local only despite accept_ra=1, autoconf=1 and
IPv6 enabled — every sysctl looked correct. The cause: vmbr0.forwarding = 1
(Proxmox sets per-interface forwarding on bridges), and the kernel ignores RAs on
a forwarding interface unless accept_ra is explicitly 2. accept_ra=1
means "accept only if not forwarding", so it silently did nothing.
Fixed in /etc/sysctl.d/60-ipv6-accept-ra.conf on that host:
net.ipv6.conf.vmbr0.accept_ra = 2
net.ipv6.conf.vmbr0.accept_ra_defrtr = 0
accept_ra_defrtr=0 is deliberate — it takes the advertised prefix (so
SLAAC configures an address) while declining the default route, so a
hypervisor gains an IPv6 identity with no change to its routing behaviour.
Verified after: SLAAC address present, v6 default routes still 0, v4 intact.
Expect the same on any other Proxmox node when its LAN gets IPv6.
Getting into a host with no direct root
esh-vm-db refuses key auth for root and infra-ops, and lkraven's sudo
wants a password. It is VMID 101 on esh-pve, and the QEMU guest agent runs
as uid 0 inside it, so the hook was installed with:
qm guest exec 101 -- /bin/sh -c 'echo <base64> | base64 -d > /etc/network/if-up.d/... '
base64 because quoting a multi-line script through two SSH layers mangles it. Worth remembering as the general path for guests whose credentials are not vaulted.
Every Linux host on esh-server now carries its name. The remaining ESH
segments have no eligible hosts: esh-cameras and esh-iot are appliances
with no shell, and esh-mgmt, esh-userland and Default are still
ipv6_interface_type: none pending the firewall-policy pass — enabling SLAAC
there gives every client a globally reachable address.