Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blocking of HTTP/3 (QUIC) in Russia #108

Open
wkrp opened this issue Mar 4, 2022 · 7 comments
Open

Blocking of HTTP/3 (QUIC) in Russia #108

wkrp opened this issue Mar 4, 2022 · 7 comments
Labels

Comments

@wkrp
Copy link
Member

wkrp commented Mar 4, 2022

A thread on NTC says that HTTP/3 connections (QUIC; UDP to port 443) to foreign sites are blocked in several ISPs in Russia. I don't know a precise time of onset. It has been tested on the ISPs Yota, Megafon, MTS, Rnet, and Beeline. HTTP/3 to sites located in Russia, for example vk.com, still works. The technical symptom of the blocking is that there is no reply to the Initial Packet.

https://ntc.party/t/http-3-quic/1823

There are web pages where you can test for yourself whether HTTP/3 is accessible. (You may have to refresh the page a few times.) Technical users can use the browser console to check HTTP/3 on other sites.

@bol-van offers a recipe for circumventing the block using zapret (English docs):

iptables -t mangle -I POSTROUTING -p udp --dport 443 -m mark ! --mark 0x40000000/0x40000000 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:3 -j NFQUEUE --queue-num 205 --queue-bypass
nfqws --qnum=205 ---dpi-desync=fake --dpi-desync-any-protocol --dpi-desync-fooling=badsum --dpi-desync-cutoff=d4

@bol-van cautions that the --dpi-desync-ttl option does not work well when using Chrome, but it works with Firefox. Chrome looks for ICMP "TTL exceeded in transit" messages and will tear down the connection if it sees them, while Firefox ignores such packets.

The QUIC Initial Packet typically contains the TLS ClientHello, including the SNI. It might seem that the censor would do selective blocking of QUIC, only for specific hostnames, as with HTTP/1 and HTTP/2 over TLS. But this block appears to be of all HTTP/3, regardless of destination. The reason may be that Initial Packets are obfuscated, encrypted using a key that is sent in plaintext. The censor would have to do extra decryption work to recover the SNI, or maybe their hardware does not support it.

@wkrp wkrp added the Russia label Mar 4, 2022
@wkrp
Copy link
Member Author

wkrp commented Mar 4, 2022

Kathrin Elmenhorst et al., in cooperation with OONI, wrote a paper and a blog post about using ooni-probe to measure HTTP/3 censorship:

But I don't know if such measurements are still being run regularly, or how to access them. I've sent an email to the authors to ask.

@wkrp
Copy link
Member Author

wkrp commented Mar 4, 2022

But I don't know if such measurements are still being run regularly, or how to access them. I've sent an email to the authors to ask.

I got a reply from Kathrin with instructions. To find HTTP/3 measurements in OONI Explorer, you have to choose the URL Getter network test, and uncheck the "Hide failed measurements" box. Like so:

https://explorer.ooni.org/search?since=2022-02-02&until=2022-03-05&test_name=urlgetter

You have to dig into the https measurements to see which ones are HTTP/3. In the JSON, look for "HTTP3Enabled=true" in the .options array, and QUIC-related events (like "operation": "quic_handshake_start") in .test_keys.network_events.

However, the URL Getter test is experimental and is not being run regularly. I did not find any recent test results from Russia.

@bol-van
Copy link

bol-van commented Mar 5, 2022

@bol-van cautions that the --dpi-desync-ttl option does not work well when using Chrome, but it works with Firefox. Chrome looks for ICMP "TTL exceeded in transit" messages and will tear down the connection if it sees them, while Firefox ignores such packets.

The best option seem to omit desync fooling. When an UDP packet with zero or trash payload arrives to QUIC server it simply ignores it. No any harm occurs.
Incoming badsums are often dropped on home routers with stock linux based firmware and by mediatek ethernet hardware

@ValdikSS
Copy link

ValdikSS commented Mar 9, 2022

The filter applies only on packets with UDP-payload larger than 1001 byte (including)
Filter seeks for "00 00 00 01" (hex, QUIC version) in the UDP payload starting from the second byte.
It is applied only for UDP packets with destination port == 443. Source port doesn't matter (the filter is not applies for source port == 443).

Pseudo YARA rule:

rule QUIC_block_Russia_TSPU_04_mar_2022
{
    condition:
        filesize > 1000 and dport == 443 and int32be(1) == 0x00000001
}

Minimalistic payload for which the filter is applied:
quic_tspu_filtered.bin.zip

nping --udp -p 443 -c 1 --data "$(xxd -ps -c 999999 quic_tspu_filtered.bin)"

@wkrp
Copy link
Member Author

wkrp commented May 2, 2022

@kelmenhorst has a thread with some interesting observations from OONI HTTP/3 measurements in Russia.

kelmenhorst/quic-censorship#4

On the ISP Yota (AS 31213), there appears to be a two-layer filter. One layer blocks all QUIC version 1, except to specific servers; and a second layer blocks QUIC version 1 with with specific SNI values, no matter the server. This is interesting because the second layer means they must be decrypting the initial packet protection on the packet containing the Client Hello.

The evidence for this comes from observing what happens when accessing different servers using different SNI values.

condition result
Access foreign server with correct SNI blocked
Access foreign server with vk.com SNI blocked
Access vk.com server with vk.com SNI works
Access vk.com server with www.facebook.com SNI blocked

@fortuna
Copy link

fortuna commented Jun 30, 2022

The new HTTPS DNS resource record has a way to specify the port number for a service.

Publishers could leverage that to run HTTP/3 on a port other than 443 and bypass the filtering.

Kudos to @daniellacosse for the idea.

@ValdikSS
Copy link

Alt-svc HTTP header could point to another port as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants