The client shows a global IPv6 address, the handshake completed, and nothing comes back from the internet. The pool setting looks correct because it is correct; the address is valid and the tunnel carries it. What fails is delivery, and delivery depends on a decision made upstream of the VPN server that no client-side configuration can influence.

The myth: a piece of your /64 is already reachable

The story is appealing: the server has a public /64, cut it in half, hand the other half to the VPN pool, and those clients are now on the internet. Splitting the prefix does allocate addresses without collisions. It does not change how the upstream network decides where a packet for one of those addresses should go.

IPv6 has no default translation layer to fall back on, so the return path has to exist as routing or as link-level delivery. A packet addressed to a client's tunnel address arrives at the upstream router, and that router makes a forwarding decision from its own table. If the table points at the physical link, the packet goes there regardless of what your VPN server believes.

That is the entire failure: the forward direction works because your server sends it, and the reverse direction dies one hop away because the upstream never learned the client exists.

What on-link delivery really requires

When the upstream considers the whole /64 to be on the physical link, it resolves each destination address with neighbor discovery. It sends a solicitation on that link and expects the owner of the address to answer. A VPN client sitting behind a tunnel is not on that link and cannot answer, so the solicitation goes unanswered and the packet is dropped.

Carving out a /65 does not change that expectation. The upstream still treats the range as on-link, because the only thing that would change its mind is a route or a proxy that answers on the client's behalf. Neither appears because you edited a VPN configuration. That gap is why a pool can work perfectly between its own clients and still be unreachable from anywhere else.

Proxy neighbor discovery is the mechanism that can bridge the two worlds. The gateway answers solicitations for the specific client addresses it owns and forwards the traffic into the tunnel. It works, and it has to be scoped to exactly those addresses with a lifecycle that follows the pool, because answering for an address you no longer serve black-holes someone else's traffic. Some upstreams will not accept proxy answers they did not expect, so this design needs the provider's agreement as well.

What routed delivery requires

The cleaner design is an allocation the upstream actually routes to your gateway. That can be a delegated prefix or a static route for a smaller block, and the requirement is the same either way: the upstream's table must point at your server for the client range. Then return traffic arrives at the gateway and the gateway forwards it into the tunnel.

Routed delivery removes the neighbor-discovery question entirely, which is why it is worth asking the provider for it before building anything clever. Ask for the route in writing, and confirm the next hop is the address the upstream can actually reach.

Both designs still need IPv6 forwarding enabled on the gateway and firewall rules that permit the forwarded flow in both directions. Delivery is a prerequisite, not a substitute, for the rest of the path. A working route with forwarding disabled produces exactly the same silence as a missing route, so check both before redesigning anything.

Two independent routes to get right

The pool prefix and the client's own default route are separate settings, and confusing them produces partial connectivity that looks like a broken tunnel. The pool tells the server which addresses to hand out. The client's routes decide which destinations the client sends into the tunnel at all.

server-ipv6 2001:db8:42:100::/64
push "redirect-gateway ipv6 !ipv4"

The prefix above is documentation space, and the redirect applies to IPv6 only, which is exactly what a dual-stack deployment often wants while IPv6 delivery is still being fixed. An IPv4 redirect does not establish IPv6 coverage, and neither setting implies the other.

Keep the control traffic that IPv6 depends on working under whatever policy you apply. Packet Too Big messages are the classic casualty of a firewall that permits only TCP and UDP, and dropping them produces connections that establish and then stall on larger transfers.

Router advertisements are the third moving part. If the gateway starts advertising on the uplink, it may change what clients and neighbours believe about on-link prefixes, which can quietly undo the design you just documented.

Record the design so a rebuild reproduces it

Write down three objects separately: the client allocation, the client's destination route, and the upstream's delivery method for the allocation. A reader who has all three can rebuild the deployment; a reader who has only the pool setting will reproduce the original bug.

Then test the reverse direction explicitly, with a packet that has to come back from outside. The openvpn(8) manual covers the server-ipv6 and redirect options, and your provider's routing confirmation covers the half the manual cannot.

ተዛማጅ ጽሑፎች