Pings to the server's tunnel address succeed, the client's own route table looks right, and the LAN behind that client is still unreachable. The client's own routing table looks correct, the server has a route pointing at the tunnel, and packets still vanish. This is the classic symptom of a layer-3 tunnel that has no idea one of its clients is also a gateway.

A tun interface has no per-client next hop. The kernel sees a single interface with many peers, so the decision about which client should receive a packet for a remote LAN has to be made inside the OpenVPN process. That decision is configured with iroute, and without it the packet has nowhere to go.

The server routes by client, not by interface

When the server needs to send a packet to a client's tunnel address, the answer is unambiguous: the address belongs to that client's session. When the destination is a whole subnet behind that client, the address belongs to nobody the server knows, and the kernel's route to the tunnel only says "out this interface" without saying which peer.

OpenVPN solves this with an internal routing table that maps a destination prefix to a specific client. That table is built from iroute entries, which is why a plain route on the server host is not enough. The kernel route gets the packet to the tunnel interface; the internal mapping decides which session receives it. That is also why the repair never shows up in the kernel's route output.

If the mapping is missing, the packet arrives at the server, matches the tunnel route, and is dropped because no client claims the destination. Nothing logs a clean error, which is why the failure looks like a silent black hole rather than a routing loop.

Writing the iroute entry that names the client

iroute lives in a client-specific configuration file, not in the main server configuration. Point the server at a directory with the client-config-dir option, then create a file whose name is the client's certificate common name and put the prefix inside it.

For a branch whose LAN is 10.20.0.0/24 and whose certificate common name is branch-router, the file at that path contains a line such as iroute 10.20.0.0 255.255.255.0. The main configuration only needs the directory option; the prefix lives with the client.

The common name is the fragile part. A certificate issued with a different subject, or a deployment that authenticates users by username while the file is named for the certificate, produces a file that is never read. Check the name the server actually reports for the session, and consider the option that makes an unmatched client fail instead of silently connecting without its routes. Renaming the file to match the certificate is a five-minute fix that prevents a very long evening.

One client can own several prefixes. Add one iroute line per network, and keep the list next to the rest of that client's settings so the mapping stays auditable.

Building the return path in both directions

Getting packets to the remote LAN is half the job. The client must also send that LAN's traffic into the tunnel, which is normally done by pushing a route to the client: a line like push "route 10.8.0.0 255.255.255.0" tells every client how to reach the server-side network. For the branch, the equivalent route points at the tunnel for whatever it should reach on the server side.

The return direction needs an owner on the far side. On that side, someone must know the way back: a static route on the LAN router that points the VPN pool at the server, or address translation on the server before traffic enters the LAN. The static route keeps original addresses visible in logs and access rules but requires the LAN owner's cooperation; translation is self-contained but hides who actually connected.

Forwarding must be enabled on the server host. Without it the kernel accepts the packet from the tunnel and declines to pass it to the LAN interface, which looks identical to a missing iroute from the client's point of view.

Checking reachability with the right probes

Test in layers instead of pinging the far end and guessing. From the server, check that the internal mapping exists for the prefix and that the kernel route points at the tunnel. From the client, confirm the pushed route is installed and that its default path for the LAN address is the tunnel.

Then watch packets. A capture on the tunnel interface shows whether the server is transmitting toward the client, and a capture on the LAN interface shows whether it is forwarding. If the first shows packets and the second does not, forwarding or a filter is the problem; if neither shows anything, the lookup failed earlier.

Two servers joined by a tunnel repeat the same rule on both sides: each needs an iroute for the other's pool, and each needs the route and forwarding that make the path symmetric. Routing and policy are separate concerns here. Routing decides where a packet can go, while a FORWARD rule decides whether it may, so a client with two iroute lines can reach both prefixes unless a filter says otherwise.

Akụkọ ndị metụtara ya