Networks that allow only proxied egress are where a working profile suddenly dies. The proxy address is the least interesting variable in that failure. What decides everything is the shape of traffic the proxy will relay, because these proxies forward a byte stream and a UDP tunnel is not one. That leaves two architectures, and they break in different places.

One constraint decides the design

SOCKS5 does specify a UDP association mode. OpenVPN's client proxy support is nonetheless built around streams: socks-proxy is documented for TCP profiles, and an HTTP CONNECT proxy has no datagram path whatsoever. One line of documentation settles the architecture before you touch a configuration file.

The question is therefore not which proxy to choose. It is whether the tunnel becomes a stream, or stays a datagram and lets something else absorb the proxying.

Option A: turn the tunnel into a stream

This needs a server with a TCP listener, and a client profile that names the proxy. Both pieces are required, and the server side is the one people forget:

proto tcp-client
remote vpn.example.net 443
socks-proxy 127.0.0.1 1080

Swap the last line for http-proxy proxy.internal 8080 when the proxy speaks HTTP, and append a credentials file if it demands one. The proxy must be willing to CONNECT to your VPN port, and the server must answer on TCP; a UDP-only listener ignores the attempt. Choosing 443 is a practical move, since many restrictive networks allow it and little else.

The cost is TCP stacked on TCP. One dropped outer segment stalls every inner stream sharing that connection, so recovery that would normally be independent becomes shared. Setup also takes longer, and a flaky outer path turns into a flaky tunnel rather than a slow one.

Option B: leave the tunnel alone

When the tunnel must stay on UDP, the tunnel is not where you configure anything. Instead, outbound TCP from applications is redirected to a local SOCKS listener, and the applications never learn that a proxy exists. On Linux that is typically redsocks plus a NAT REDIRECT rule in the nat table.

TCP only, again. An HTTP-only proxy such as privoxy cannot relay arbitrary protocols, and this design adds no datagram support for the applications either.

Telling each application about the proxy directly is usually better where the software supports it. It is easier to audit, and it fails somewhere you can actually see.

Where each option fails

Option A fails when the server lacks a TCP listener, when the proxy refuses the CONNECT target, or when the outer stream is throttled below what the tunnel needs. The first two leave an entry in the proxy log; the third leaves a connection that establishes and then feels wrong. Read that log before editing the profile, because it separates a permission problem from a capacity problem. A completed CONNECT moves the investigation inside the tunnel.

Option B fails for anything needing datagrams, for protocols the proxy does not understand, and quietly on hosts where the redirect rule exists but routing sends the traffic past it.

Neither option changes the device requirement. Packets still need a TUN or TAP node before the kernel will route them, so the process still needs permission on /dev/net/tun. A wrapper changes what happens after that node is open, not whether you need one.

Proving which path you built

Look at sockets rather than the tray icon. The VPN process should hold an established connection to the proxy address, and the proxy should have logged the target it was asked to reach:

ss -tnp | grep openvpn

Then reach for a destination only the tunnel can serve, and a name only the tunnel resolver can answer. A completed proxy connection with a dead tunnel usually means the far end never offered the transport named in your profile.

Note the transport and the accepting proxy somewhere durable. When the same profile fails on another network, that note rules the proxy in or out within seconds.

Mikanda mikatakata