Hello, I'm writing this in case the developers see this and take it into account, or maybe my post will help someone.
I'm from Russia. We have neither freedom of speech nor a free internet, and then there's Putin's war.
I installed OpenVPN on my new VPS server and spent three days trying to get it to work. I even used up my entire Cloud AI token limit. Finally, I found out under what circumstances OpenVPN is blocked by DPI in Russia.
The point is that only the 2.5.0 bundle without tls-crypt worked for me.
Why 2.5.0 works without TLS-Crypt in detail
First, two facts that are important to keep in mind.
Fact 1: SSLH doesn't encrypt or hide anything. It only looks at the first packet to decide "TLS → Xray, the rest → OpenVPN," and then simply forwards bytes like a transparent TCP proxy. This means that on the wire between the phone and the server, the operator sees a raw OpenVPN-over-TCP stream on port 443. SSLH provides port sharing with Reality, but it doesn't obfuscate OpenVPN.
Fact 2: Without TLS-Crypt, the OpenVPN handshake is open and easily recognizable. OpenVPN has a very distinctive wire structure: a 2-byte length prefix, then an opcode byte (P_CONTROL_HARD_RESET, P_ACK, P_DATA_V2...) at fixed positions, followed by a TLS handshake. Using this opcode grid, DPI classifies a stream as OpenVPN based on the first packets.
What does "Modern" mode (2.6/2.7) change?
OpenVPN 2.6 added a set of new features that the parties negotiate via IV_PROTO and that are visible in PUSH_REPLY—you saw it in your log:
IV_PROTO=8094
protocol-flags cc-exit tls-ekm dyn-tls-crypt
tls-ekm — a new way to extract data channel keys (via a TLS exporter instead of the classic OpenVPN scheme).
dyn-tls-crypt — dynamic TLS-crypt: after the handshake, the server generates a new key and the control channel is re-encrypted to it (an unnecessary early exchange).
cc-exit — exit notification via the control channel.
compat-mode 2.5.0 disables all of this—the client behaves like 2.5: no EKM, no dyn-tls-crypt, no cc-exit, the old classic key exchange.
Why 2.6 mode is throttled, while 2.5 works
The key conclusion from our measurements: the operator doesn't cut OpenVPN "in general"—otherwise, classic 2.5 wouldn't work either (and it delivers 24 MB in 3 minutes without a single interruption). It cuts a specific, modern OpenVPN 2.6+ pattern.
The most honest explanation for this is that DPI signatures are almost always narrow and version-specific. Today, the vast majority of VPN applications use 2.6+ defaults, so it's advantageous for the operator to tailor the rule specifically to the modern fingerprint—the pattern of early control packets after the TLS handshake (their sizes and sequence differ in 2.6 with these flags than in 2.5). Classic 2.5 traffic doesn't fall under this rule and occurs in a "blind spot."
It's worth clarifying here: IV_PROTO, peer-info, and the protocol flags themselves are contained within the TLS control channel, meaning the DPI doesn't read them directly. This means it doesn't filter based on the "read version number," but rather on an indirect fingerprint—the size/timing/number of early packets, which is different in modern mode. We don't see the exact signature from the outside, so this part is a reasonable inference from behavior, not a fact from the operator's datasheet. But the empirical evidence is clear: modern → throttle, 2.5 → don't.
Why tls-crypt made things WORSE, not better (counterintuitive)
Logically, tls-crypt should help against DPI: it encrypts and authenticates the entire control channel, and the characteristic OpenVPN "opcode grid" turns into noise—the signature should disappear. But in practice, it caused instability on this operator. Reasons:
In modern mode, tls-crypt automatically pulls dyn-tls-crypt—that same unnecessary early re-encryption exchange. It seems that its fragile/large early pattern was what was causing the throttle (the very first tls-crypt+Modern test failed).
The results were inconsistent—sometimes it worked, sometimes it didn't. This is a sign that tls-crypt/dyn-tls-crypt was introducing a borderline state (extra roundtrips, time-based rekeying), which was sometimes throttled, sometimes not. Removed tls-crypt → removed fragility; compat-mode 2.5.0 → removed the modern signature. Together, they provide a stable, reproducible stream (proven by load testing).
There's one caveat: pure static tls-crypt (in 2.5 mode, without dynamic) could theoretically work and even hide the signature—but since bare 2.5 already works, and tls-crypt introduced instability, there's no point in using it. It's not worth the effort.
Direct answer to your question
"So, does the DPI still detect it?" — Yes, without tls-crypt, the stream is identified as OpenVPN. But the operator doesn't block OpenVPN as a class—it has a narrow rule for modern OpenVPN 2.6+ (and especially for the tls-crypt/dyn-tls-crypt variant). Classic 2.5-style traffic currently doesn't fall under this rule and passes. That is, we didn’t “hide,” but pretended to be an old OpenVPN and fell into the blind spot of a specific rule.