One private service loads through the tunnel and the next one times out, and the temptation is to rebuild the whole client profile. The working service is more useful as a control than as a reason to start over. It proves that one destination, one port and one authorization path were satisfied, and nothing beyond that.

Two services on the same gateway can be reached by different address families, different subnets and different policy.

Separate the Working Flow From the Failing One

Treat each service as its own flow rather than as a symptom of "the VPN". An illustrative client can open portal.corp.example at 172.20.4.15:443 and still fail to reach a database at 172.20.9.40:5432, because those are two destinations with two rulesets. Write both rows down before changing anything, including the port and the protocol, since a rule that permits TCP 443 on a host says nothing about TCP 5432 on the same host.

The failing row is the one to investigate. The working row only tells you where the baseline sits, and it will be the comparison point after every change you make.

Compare Addresses Before You Compare Names

Resolve each full name through the policy the application actually uses, then record the address family it picked. One name can return an IPv6 address while another returns IPv4, and an old cached answer can send a request to a public address that has nothing to do with the private service.

ip route get 172.20.4.15
ip route get 172.20.9.40
ip -6 route get 2001:db8:60::20

The lookup answers a narrow question: which route would this host select for that destination, given the current tables and policy rules. A route for 172.20.4.0/24 does not cover 172.20.9.0/24, and a second network manager or a local route with better specificity can quietly override the tunnel. Repeat the lookup inside the namespace or with the mark the application uses when those differ from your shell. Record the interface the packet leaves by as well, because the route table can name one interface while policy routing sends the flow out of another.

A route that matches is a necessary condition, not a permission. It tells you the packet has somewhere to go and nothing about whether a firewall, an authorization service or the host itself will accept it.

Protocol and Response Stage Tell You Where It Stops

A ping reply does not prove that a database port is open, and a successful HTTPS page does not authorize a file share on the same machine. Record what actually came back rather than flattening every failure into one category. A timeout, a reset, a TLS identity error and an application-level rejection each point at a different layer.

The distinction matters because the corrections diverge. Silence usually means a route, a firewall or a translation problem on the path. An immediate reset suggests something reached the host and refused the port. A certificate error means the connection arrived and the name did not match, which is a configuration problem rather than a reachability problem. An application denial means the network did its job and the identity was rejected afterwards.

When a resource is published through a gateway, compare the source address the destination observes with the source your client believes it uses. A request originated by the gateway itself can succeed while the same request from a client fails, because the two arrive from different addresses and meet different rules.

Change One Variable and Re-run Both Requests

Identity is the last place people look and the first place a correct denial appears. The VPN login, the directory group and the application account are three separate identities that can diverge. Access to a portal never implies access to the database behind it, and a name in one directory does not create a row in another. If the service sits outside the user's intended scope, the denial is the system working.

Ask the resource owner to confirm the intended entitlement instead of adding a broad route or opening a group as a test. Broadening the network to prove a point is how a temporary diagnostic becomes a permanent exposure, and it destroys the control you started with. One demonstrated mismatch per iteration is enough: a missing route, a wrong address family, a blocked port or a missing group membership.

After each change, repeat both requests and keep the outputs side by side. The investigation ends when the failing service works under its own policy while the working service and the denials you still expect behave exactly as before.

Pennadoù liammet