16:00:48 #startmeeting tor anti-censorship meeting 16:00:48 Meeting started Thu Feb 5 16:00:48 2026 UTC. The chair is Shelikhoo[mds]. Information about MeetBot at https://wiki.debian.org/MeetBot. 16:00:48 Useful Commands: #action #agreed #help #info #idea #link #topic. 16:00:48 here is our meeting pad: https://pad.riseup.net/p/r.9574e996bb9c0266213d38b91b56c469 16:00:48 editable link available on request 16:00:57 :) 16:00:59 hi 16:02:07 hi 16:03:03 I didn’t see any new discussion topics 16:03:45 o/ 16:04:33 Hi gus, do you wants to suggest a discussion point 16:04:34 Or just saying hi 16:04:47 I just added one 16:04:51 i'm planning to send call for snowlfka proxies to tor-relays today, any thoughts/ideas/suggestions? https://pad.riseup.net/p/4dOwW-5eaAkMfFFoHlEM-snowflake-call-keep 16:04:51 can we remove the old ones? 16:05:44 I think we can remove the old ones, but there is a new topic about allow listing restrictions in Russia 16:06:13 Let’s proceed with gus’s discussion point first 16:07:07 ggus: nice, it looks good to me 16:07:42 it looks great. i do think we should list the options in order of positive user experience (maybe 1. orbot, 2. webext, 3. standalone, 4. badge)? 16:08:00 I wonder if we can make the link about running a browser extension navigate to the corresponding section 16:08:11 It might be possible with a # tag 16:08:50 - Option 2: Install Snowflake browser extension: 16:08:50 https://snowflake.torproject.org/ 16:09:06 like this_ https://snowflake.torproject.org/#03-donate-bandwidth 16:09:16 Yes… 16:09:46 Thanks… that is end of my suggestion 16:10:26 thanks for doing this ggus 16:10:42 Yes! Thanks ggus! 16:10:45 i didn't realize how overloaded we were until seeing the shared user reports with rendezvous failures in the logs 16:11:16 yes, it looks like it takes many retries to connect to snowflake, and some times it doesn't work 16:11:21 our prometheus metrics show clients being denied for lack of proxies, but it's hard to tell how that impacts user experience directly 16:12:43 the thing with snowflake is that we tend to have most proxies iddle, until something happens and the network gets overloaded 16:13:15 if you open the snowflake badge page now, you will get users immediately 16:13:29 we could reconsider the webextensions allowing for more than one client, or having the broker telling the proxies how often to poll 16:14:57 i think the default is already that webextensions with less restrictive NATs allow 2 clients to connect 16:15:08 let me quickly check 16:15:24 ahh, nice, I didn't know 16:16:15 https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake-webext/-/blob/9ed59f79bdfacee7c72d0ddca8987bb52c644c38/snowflake.js#L113 16:17:00 ggus: good point about the badge, maybe it's also a good option to add more temporary churn to the pool 16:17:01 should we do this also for restricted? grafana claims that we have many unrestricted clients in Iran... 16:17:08 * ggus sending the email 16:17:55 meskio[mds]: we could, i'm not seeing any clients with unrestricted NATs denied at the broker 16:18:26 we still have a lot of idle proxies in that pool 16:18:58 mmm, true 16:19:08 maybe not worth it 16:20:11 Yeah, anything more we would like to discuss about this topic? 16:20:37 I don't think so 16:20:57 thanks ggus for making a call 16:21:09 thanks ggus 16:21:13 the next topic is about 16:21:14 whitelisting in russia 16:21:15 https://gitlab.torproject.org/tpo/anti-censorship/censorship-analysis/-/issues/40071 16:21:26 I added that one 16:22:05 I did see the part that only some messager is working when the allowlisting is enforced 16:22:09 it looks like is becoming more common that for some periods of time users in some networks in russia can only access a short list of in-country allowlist services 16:22:39 Does this means the cross border dns also get blocked 16:22:40 I was brainstorming myself a bit on this issue on how to make Tor work for those users 16:22:51 or we still don't know for sure 16:23:02 yes, it could be that dnstt/splitstream work 16:23:27 maybe something to test now that orbot is including dnstt... 16:23:53 I mean, asking users to try out 16:24:05 yes... I was thinking if the effort around dns tunnel thing can be shared 16:24:29 I was considering if we should look into PTs of proxing the traffic over messengeres, to use those services that are available 16:24:45 there are a bunch of literature on how to offuscate traffic in text 16:25:06 and some code around, but I assume is a big project 16:25:39 the other issue is that it is not hard to russian messager app to block our account 16:26:13 yes, true, we end up distributing accounts like we distribute bridges, but been probably harder to create them 16:26:20 is cdn77 one of the allowlisted providers? 16:26:37 or any of the fronts we've used for them, I guess? 16:26:40 no 16:26:41 only russian services 16:26:59 nina13[mds]: ping 16:27:03 AFAIK no full providers, no in-country traffic, just specific services 16:27:26 but it looks like is SNI based and not so much IP based... 16:27:29 I think we should try the dns tunnel thing, if the speed is insufficient, we can attempt ip level source forging 16:27:39 I think some people are just using webtunnel with the right SNI 16:28:05 and for SNI based censorship, there are many options to deal with that without too much effort like sni imitation 16:28:06 sounds good, to me, and that will also be useful for the situation in Iran 16:28:42 I think at some point we should also have some try about ip level source forging 16:28:55 ggus: I'm here 16:29:09 fyi a plaintext udp/53 DNS tunnel is an "arms race" style transport: it is easy to detect and block once the censor knows what to look for 16:29:09 it will be able to deal with ip level censorship 16:29:26 nina13: just discussing your issue about russian whitelisting 16:29:30 I think of it as a last-resort "emergency use only" transport because it's security through obscurity 16:30:27 dcf1: I agree, it looks like it was very useful during the Iranian blackout, but let's not use it more than just in extreme situations 16:31:13 BTW, champa is another tool that is often useful in Iran with nothing else works, because they tend to allowlist google first 16:31:55 we were discussing if champa will be faster than dnstt, and nicer user experience with all the Tor overhead 16:32:06 Yes, and that one is not security by obscurity because the true destination is actually encrypted, unlike a plaintext DNS tunnel 16:32:34 I think amp cache also have some kind of throttling 16:32:35 champa would be faster than dnstt, except for rate limiting at the AMP cache 16:32:49 I don't know a solution to that. It's a bummer. 16:33:04 the rate limit is per account? 16:33:16 Try it, it works at 10 KB/s for a few minutes, then stops working completely for a few hours. 16:33:29 Miserable usability. 16:33:34 wow, ok 16:33:45 a pity 16:34:07 is this a limit based on the html page loaded 16:34:15 or something else 16:34:27 I think it is keyed on the client and not the server, not 100% sure 16:34:28 let's say if we request images or other resources 16:34:47 images are problematic because the AMP cache may transcode them 16:35:32 https://developers.google.com/amp/cache/overview#cache-optimizations-and-modifications 16:35:40 "Conversion of images to smaller and mobile-friendlier image formats, such as converting GIF, PNG, and JPEG format images to WebP in browsers that support WebP." etc. 16:36:26 There may be a more efficient encoding than the current base64-in-HTML, but it's not obvious 16:37:18 I see web font can also be shipped 16:37:49 I image it is a more complex format and won't be transformed at edge as easy as images 16:38:01 feel free to experiment, I don't see how it helps against rate limiting though 16:38:06 I imagine it is a more complex format and won't be transformed at edge as easy as images 16:38:10 yes.... 16:39:06 the other option is to use ip source forging 16:39:41 I think this is something that would be hard for censor to filter even with the knowledge we are doing so 16:39:48 don't most ISPs use ingress/egress filtering to prevent that? 16:41:29 it is possible for martian packet to be filtered 16:42:30 however, when it comes to internet traffic exchange, unless an ip address is announced by a particular ISP, it will not be able to drop packet "from" it 16:43:32 to send a packet with forged source, one requires an isp that don't filter outgoing traffics 16:43:59 which is not common for most residential or big data center 16:44:14 however, it is still possible 16:45:01 so, so long as the destination address is announced, we can send a packet to it and claim the packet is from any source 16:45:21 so long as the source is not directly adjacent the the destination 16:46:16 EOF 16:46:49 we still have a paper to discuss 16:47:03 yes, I'm done with this topic, we can move to the reading group 16:47:06 I see there is an interesting link: https://gitlab.torproject.org/tpo/anti-censorship/censorship-analysis/-/issues/40068#note_3333227 16:47:27 okay let's move to the reading group 16:47:38 We will discuss "Fingerprint-resistant DTLS for usage in Snowflake" on Feb 5 16:47:38 https://www.petsymposium.org/foci/2025/foci-2025-0006.php 16:47:48 https://www.petsymposium.org/foci/2025/foci-2025-0006.php 16:48:50 The download link for the paper is available from the link above 16:50:08 the super quick summary from me is that the dtls used in webrtc stack(which we are using in snowflake) can be fingerprinted in the same way as tls 16:50:45 and this paper presented the utls equivalent for dtls 16:51:23 it is a nice paper, even though we have discussed this topic for years I learn many new things 16:51:25 this is really nice work, great job theodorsm! 16:51:35 tnx! 16:51:48 yes, thanks theodorsm 16:51:55 worth noting that both chrome and firefox uses dtls 1.3 by default now in webrtc 16:52:25 thanks for tracking down those setup:pass and setup:active attributes 16:52:29 interesting, do they use ECH? 16:52:34 yes... I think we might wants to consider maybe find a way to use dtls 1.3 as well 16:52:58 i took a look at the RFC and it makes sense from a latency perspective for the proxy to be the DTLS client: https://datatracker.ietf.org/doc/html/rfc5763 16:53:11 pion is in progress to support it: https://github.com/pion/dtls/issues/727 16:53:12 I am working on implementing dtls 1.3 for pion currently. Got funding through nlnet to do it. 16:53:28 nice 16:53:29 amazing, congrats on the funding! 16:53:50 thanks:) 16:54:18 One thing we couldn't really figure out is why a lot of handshakes fail. see Table 1. 16:54:21 nice!!! 16:54:53 even the baseline had around 12% failed handshakes. (calcualted from the traffic capture) 16:55:10 the baseline is a non-modified snowflake standalone proxy 16:55:10 that surprised me 16:56:02 Maybe it was retried later, but I have no stats on that and all the captures are deleted now 16:56:34 and the webextension was failing even more 16:56:42 it sounds like a good idea to follow up on that 16:56:47 I think this is related to the other side of the connection 16:57:04 if we are running on a public pool 16:57:43 maybe this is something to add to our list of research ideas: https://gitlab.torproject.org/tpo/anti-censorship/team/-/wikis/Research-ideas 16:57:50 Shelikhoo[mds]: that's true, we've heard from proxy operators about clients connecting and terminating the connection in what looks like an automated way 16:58:26 I saw a few weird scanners from a datacenter in the NL 16:58:28 so it could be weirdly behaving clients 16:58:48 But I filtered them out from calc the failure rate 16:59:07 Also, do we have metrics on which types of proxies are actually 16:59:10 being matched and successfully used by clients. 16:59:24 theodorsm: oh yeah that was a point i wanted to discuss 16:59:57 our broker metrics collect just poll data, and our bridge metrics collect just client data 17:00:02 yeah, I think we can try to see the client/server hello from the peer and attempt to guess why the handshake fails 17:00:10 we don't have metrics about proxies that actually connect to the bridge 17:00:24 it's tricky for us to do this but probably not impossible 17:00:56 i was thinking a little about this in the context of limiting malicious proxy polls as well 17:01:25 we could have the bridge give proxies some kind of signed receipt when they tunnel data from a client: if a client successfully connects, the bridge would send an authenticated receipt to the proxy, which would then hand that receipt to the broker 17:01:36 it's possible that a malicious proxy could serve a client honestly every once in a while to get these receipts, but maybe it would at least function as some level of network-based proof of work? 17:02:28 (the meeting time is almost over. we can keep the meeting open a little longer. feel free to leave if you have conflicting schedules) 17:02:48 it would take some engineering network that might not be worth it for metrics, but if it also has this DoS defence benefit then it could be interesting to consider 17:02:50 (I can stay for a while) 17:03:33 I think we can at least let the proxy send its own identity "token" to both server and broker 17:04:00 cohosh: would be cool to brainstorm a bit more on. Do you have an issue for it somewhere? 17:04:03 so that we can track if an instance is working correctly 17:04:25 Shelikhoo[mds]: that's another way to do it: have the bridge report extra stats about connected proxies 17:05:02 theodorsm: i'll make one after this discussion and mention you in it 17:05:04 yes, I feel the signed receipt thing would require some extra work on the proxy side 17:05:26 we'd have to extend the protocol for that bridge-proxy connection 17:05:29 which is more "expensive" for us, since we need to do it twice 17:06:00 it's also the flip side of https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/-/issues/31804 17:06:24 I think my udp transport mode already support sending extra options from proxy to server via websocket url 17:06:28 which would try to prevent proxy connections to a bridge without a verified client match from the broker 17:06:56 so if we just let the server to report the proxy stat 17:06:58 Shelikhoo[mds]: oh i see you mean, we'd have to implement it in the web code and the go library code 17:09:04 rather than let the proxy receive extra data from server 17:09:24 this is because the server can not verify the client connection is valid 17:09:40 when the websocket connection is created 17:09:50 as it has not received any data from client at that point 17:10:14 it will need to at least wait for some traffic on kcp level 17:10:50 which would pass the point when the server can send info to proxy over http protocol 17:11:00 and it will have to send some websocket message 17:11:25 yeah that would be difficult to do 17:11:43 and it's what we would want for this DoS prevention feature 17:11:44 so I think it is better for the proxy to just generate an random id 17:11:59 and send it to both broker and server 17:12:20 and let the broker and server do the check on their side 17:12:21 i guess the bridge and broker could communicate directly to compare proxy ids 17:12:58 yes.. 17:14:53 maybe we can continue the discussion in an issue 17:15:12 either way this is a pretty big project, and won't happen soon, i'll make an issue to summarize the discussion and think about whether to pursue it 17:15:13 since I think this will take a while to be done 17:15:27 thanks cohosh! 17:15:42 thanks! 17:15:57 there is another good thing about the proxy sending its instance id 17:16:33 this would allow the broker to send different "next poll at" to different proxies running on the same ip 17:17:01 to avoid sending the same "next poll at" to all the proxies running on the same ip address 17:17:13 and allow then to gracefully share the quota 17:17:26 eof from me on this topic 17:17:54 one thing interesting from the paper for me is that chrome randomizes its fingerprints, I guess this will make it hard for censors to make an allowlist of DTLS fingerprints 17:18:51 the one I was wondering if could be exploided by censors is the fact that WebRTC connections are always started by the proxy, I wonder what will be the collateral damage if censors block all WebRTC ClientHello arriving from outside the country 17:19:42 wouldn't normal clients retry and use a different client starting? I have no idea what is a normal behaviour 17:20:06 I think webrtc determine who is the "dtls client" in a "magic" way... so it is hard to say who will be the "dtls client" 17:20:19 ohh interesting attack vector. But we could also change up who is sending the SDP offer no? 17:21:08 According to RFC 5763, the SDP offer must include the\nsetup:actpass attribute, and it is recommended that the SDP answer\nuses the setup:active attribute [31]. The peer designated as active is\nresponsible for initiating the DTLS handshake by sending the CH.\nSince the Snowflake client is implemented to always send the SDP\noffer, the proxy—in responding with the SDP answer—becomes\nthe 17:21:14 active peer and thus initiates the handshake. 17:21:53 the reason we have the client do the offer in snowflake is to make it so the client only has to do 1 round trip with the broker 17:22:12 since that connection is less reliable and more costly to us than proxy connections to the broker 17:22:56 (shell withdraw the magic line above... it is just me don't understand the understand logic behind it) 17:24:07 you're not the only one, took me a while to understand too 17:24:10 I think this is unlikely to be censor's next move... but we might wants to consider this next time snowflake get blocked 17:24:28 theodorsm: yeah i appreciated that detail in the paper, thanks for noting it! 17:24:50 I agree, I don't think we need to react on this, I just wanted to point it out to keep it in mind 17:25:39 I think we covered all the points I wanted to bring on this reading group, I'm done :) 17:26:39 yeah it was a good discussion, thanks :) 17:26:42 eof from me as well 17:26:52 anything else we wants to discuss in this meeting 17:26:52 \0 EOF 17:26:55 (we are overtime) 17:27:07 #endmeeting