You want to know which destinations a connected client is reaching, so you open a shell on the VPN server and type ss. Nothing useful appears, and the conclusion that the tunnel is broken follows a little too easily. A routed OpenVPN gateway forwards the client's packets; it does not terminate their TCP connections and does not own sockets for them. The evidence lives somewhere else, and which somewhere depends on how the traffic is handled once it leaves the tunnel.

Decide which arrangement you are looking at

Two common shapes produce completely different evidence. A routing gateway decapsulates, forwards and possibly source-NATs, so the client's connection continues to exist end to end without a local socket.

A proxy terminates traffic: it accepts the connection, then opens its own upstream connection. In that arrangement there are two connections for one request, and the association between them exists only in the proxy's own records. Knowing which of these you deployed decides whether you should be reading kernel flow state or application logs.

Most confusion comes from guessing. Confirm the shape before choosing the tool. Read the server configuration for a proxy directive first, because its presence changes every later step. Without one, the packet path is routing and the kernel's flow state is your evidence.

Tie the address to a session first

Start from the server's session state and identify the client's current inner address. Pool addresses are recycled, so an address on its own is a lease, not a person.

Record the time and the authenticated identity together, and note whether a whole LAN hides behind that client. If the remote end routes a subnet, the inner addresses you see may be original hosts or translated ones.

ip -4 addr show dev tun0
journalctl -u [email protected] --since '-10 min' | tail -n 40

That pair answers two questions at once: which prefix the tunnel interface serves, and which session was active during the interval you care about. Do this before interpreting any flow entry, because a convincing tuple attached to the wrong session is worse than no evidence at all.

Read the flow table on a routing gateway

With the address and interval established, a read-only listing of tracked connections shows what the gateway is forwarding for it. Filter on the original source so you are not reading the whole table.

sudo conntrack -L -p tcp -f ipv4 --orig-src 10.8.0.37

Each entry holds two tuples, original and reply, which are the two directions of one flow rather than two applications. On a source-NAT path the original tuple keeps the tunnel address while the reply side shows the translated gateway address, which is exactly what makes the output look wrong at first glance.

Treat the listing as live state and not a history. Short flows may already have expired, untracked traffic never appears, and a different network namespace shows a different table. The conntrack reference documents the filters and the two-direction output.

One bounded capture to confirm the reading

If the tunnel interface is visible where you are looking, a single bounded capture settles whether the packets you identified are the ones on the wire. Keep the filter narrow and the packet limit small.

sudo tcpdump -ni tun0 -nn -c 50 'host 10.8.0.37 and tcp'

Compare timestamps, protocol and ports against the flow entry and against the request you made as a test. A capture taken after NAT shows only the gateway's public address, while the tunnel side may still show the client's, and that difference is information rather than an inconsistency.

If the interface sees nothing, check the data path before concluding the client is idle: client-to-client traffic and some offload paths never traverse the point you are watching.

Proxy logs, and the limits of what you saw

When a proxy sits in the path, its upstream sockets are visible in the socket table but they do not map one-to-one onto VPN clients, especially with pooling or multiplexing. Use the proxy's configured transaction log to correlate client identity, destination, timestamp and any request identifier it records.

Check the deployed version's logging configuration rather than assuming every request is logged by default.

Finally, be precise about scope. A destination address and port is metadata, not a URL and not page content, because the inner HTTPS session keeps its own protection regardless of the tunnel. Report what you observed, from which observation point, and at what time.

Mikanda mikatakata