Somebody reports that the VPN "blocks UDP", and the phrase hides two completely different claims. One is about the transport the access network can see, the other about an application's packets after they have been decrypted inside the tunnel. An encrypted tunnel can be filtered from outside without any key, and an inner UDP application can fail for reasons that have nothing to do with filtering. Decide which claim you are testing before you collect evidence.

Two headers, one word

In a NAT-traversal IPsec deployment, the outer packet is UDP addressed between the two VPN endpoints, typically on port 4500. Inside that, the encrypted payload carries whatever the tunnel forwards, which may itself be TCP or UDP. The word UDP therefore appears twice with different meanings and different visibility.

An intermediate network sees the outer header and nothing of the inner one. It can allow, shape or drop the outer flow, and it does not need to decrypt anything to do so. That asymmetry is the whole reason the two claims get confused: the same word describes what the network filters and what the application sends. Write the layer next to the word whenever you record a finding, and the confusion mostly disappears.

The inner header only becomes visible at the receiving endpoint, after decryption. From that point the packet is forwarded like any other, subject to routes, policy and the endpoint's own filtering. Those are separate decisions made by different boxes.

What the network can still see

Encryption hides payload and the inner transport header, not the fact that a flow exists. Endpoint addresses, ports, packet sizes and timing remain visible, and those are enough to classify traffic heuristically or to block a specific destination.

sudo tcpdump -ni eth0 'udp port 4500'
sudo tcpdump -ni tun0 'udp port 5201'

The first capture shows the outer flow on the physical interface, and the second shows the inner flow on the tunnel interface. Running both at once answers the question directly: if the outer flow exists and the inner one does not, the application never sent anything into the tunnel. If both exist and nothing comes back, the problem is beyond the tunnel, at the destination or on the return path.

RFC 3948 defines the outer UDP encapsulation, and the ESP specification defines the protected layout inside it. Neither document promises that an access network will pass the outer flow, which is why a reachability test on the outer tuple is worth running before any theory about the inner one. A blocked outer tuple produces a tunnel that never forms, not a tunnel that forms and then loses one application.

Why one UDP app fails inside a working tunnel

A tunnel that carries a web application but not a UDP application has several plausible explanations, and ISP filtering of the inner protocol is not the first. The most common is coverage: the two applications do not both enter the same tunnel, because the route for the UDP destination is missing or the client's split-tunnel rules exclude it.

The second is the endpoint. A VPN server that permits a protocol list, a destination firewall, or a service that never listens on the expected port will all produce a timeout that looks identical to a network block.

The third is packet size. UDP applications often send larger datagrams than a web request, and encapsulation reduces the usable MTU, so a working handshake can be followed by silence on the first full-size payload. That pattern is easy to misread as a block, because the small packets succeed and the large ones vanish. A quick MTU probe settles it in under a minute, and the answer is usually a smaller payload or a corrected MSS rather than a network filter.

ping -M do -s 1400 -c 2 10.60.0.20
iperf3 -u -c 10.60.0.20 -p 5201 -b 1M -t 5

The first command tests whether a large packet survives the path with fragmentation disabled, which exposes an MTU problem quickly. The second sends a small, bounded UDP stream and reports loss and jitter. A stream that starts and then stalls points at size rather than at a block.

Report the layer, not the protocol

Write the finding in one of three forms: outer delivery failed, inner forwarding failed, or the application failed. Each has a different owner, and mixing them sends the ticket to the wrong team.

Changing a local port cannot create a matching listener at the far end, so a client-side workaround that appears to help is usually evidence that the original destination was wrong. Likewise, a supplied alternative profile proves something about reachability and nothing about whether the application is configured correctly.

Keep inference separate from observation as well. Traffic analysis can suggest what a flow is without decrypting it, and that is a useful finding, but it is not the same claim as reading the inner header. State which one you actually have.

Pennadoù liammet