guardianproject / orbot-apple

Orbot VPN app for iOS
MIT License
208 stars 35 forks source link

Obfs4 optimization #71

Closed keyboardcat1 closed 1 year ago

keyboardcat1 commented 1 year ago

I am currently in China and have to use obfs4 bridges to connect to tor. However, I rarely can manage, sometimes having to wait a day or even two of repeatedly waiting 5-10 minutes, clearing cache and switching (previously proved functional) bridges. The progress stays stuck mostly on 50% and tor logs get flooded with "general SOCKS server failure". I believe there is a lot of room for improvement since the app "Tor Browser" manages to connect to the same bridges in under a minute.

tladesignz commented 1 year ago

Uuuuh. Hello! Good to talk to you!

This is very interesting information, however it would be more helpful, if you could provide some more detail.

since the app "Tor Browser" manages to connect to the same bridges in under a minute.

Can you point me to the location of where you got the "Tor Browser" app? Are you talking about the desktop computer app provided by Tor Project for Mac, Windows and Linux? Or is this an iOS app officially available on the Apple App Store for iOS?

The official recommendation for mainland China is to use Snowflake instead of Obfs4 proxies. It is well known, that the "great firewall" blocks most Obfs4 proxies pretty quickly.

Can you cross-check with your "Tor Browser" app, that you're actually using Obfs4 proxies, and not Snowflake?

Can you use Orbot iOS with Snowflake and tell me, what's the performance with this? Please try both options (traditional and AMP)!

Thank you!

keyboardcat1 commented 1 year ago

Hello,

I am using both Orbot and Tor Browser on iOS, the latter available in the App Store.

Snowflake being the recommended option for mainland China is news to me. Sources I've read and Orbot itself that Snowflake can't get around heavy censorship and 3rd party obfs4 bridges should be used. I quote the "Choose how to connect" menu:

Thanks

n8fr8 commented 1 year ago

Do you mean Onion Browser on iOS? There is no app we support called "Tor Browser" on iOS.

keyboardcat1 commented 1 year ago

No, Tor Browser is an app unrelated to Orbot. I am bringing i up because of how faster it somehow is.

n8fr8 commented 1 year ago

My point is that it may not be Tor at all. There are many fakes, imposters, and closed source scam apps out there claiming to be Tor. Can you provide a link for us to look at so we can investigate?

keyboardcat1 commented 1 year ago

https://apps.apple.com/gb/app/tor-browser-ornet-onion-vpn/id1177964608

It can connect to hidden services in China.

n8fr8 commented 1 year ago

What this app may be doing is a traditional VPN to their servers, and THEN routing that traffic over Tor. That would make it faster, but obviously not true Tor to the client on your device.

The really is no way to know since it is closed source, their website is down, and their contact info likely doesn't work.

keyboardcat1 commented 1 year ago

Bridges are required here in China to connect through the app. They could be faking that need for bridges through geolocation, but I highly doubt that is the case since they have both tor and tor + vpn options.

In either case, couldn't you just intercept the traffic via a global proxy to see what the app is actually contacting?

Shouldn't VPN be slower than pluggable transports? It's an extra hop after all

tladesignz commented 1 year ago

Ok, so I had a look at that "ORNet browser". It seems to be a clone of the 2.x version of our Onion Browser app. I recognize a lot of elements from my Onion Browser code and from the IPtProxyUI lib.

I'm not sure, though, if they didn't somehow manage to use WKWebView instead of UIWebView. Anyhow, it still leaks your IP address through WebRTC. (Check https://browserleaks.com/ for proof.)

They bundle it up with an optional VPN subscription.

I know, I get reports from around the world which seem to point to memory issues in Orbot. Unfortunately, we're limited with 50 MByte RAM, due to artificial constraints from Apple, which doesn't want Network Extensions which continuously run in the background to use more than that.

Currently, we cannot do much about it, unfortunately.

Our hopes lie on the Arti project (Tor reimplemented in Rust). It has mobile in its mind from the beginning and I hope it will achieve a smaller memory footprint.

We're actively contributing to that work, but it still is a while to there.

In the meantime, we can only hope, that Apple will continue to increase that limit with OS updates.

Thanks for all the information you provided, @keyboardcat1!

tladesignz commented 1 year ago

BTW: Regarding the wording around Snowflake: It's hard to come up with words which manage user expectations of a global audience in the right way.

Tor Project's recommendation for China is to use Snowflake. Obfs4 proxy support is spotty. (But happy for you, if you find working ones!) If you press the "Ask Tor" button in Orbot, the server run by Tor Project will answer with "snowflake", if it recognises your IP address coming from China.

keyboardcat1 commented 1 year ago

Thanks a lot for the explanations! I'm excited for Tor in Rust, on mobile on top of that.

I'm a still bit confused though, how does it manage to connect faster to bridges than Orbot? What corners does it cut? Is it because it isn't a network extension (doesn't apply globally) and hence isn't restricted in terms of memory?

tladesignz commented 1 year ago

I'm a still bit confused though, how does it manage to connect faster to bridges than Orbot? What corners does it cut? Is it because it isn't a network extension (doesn't apply globally) and hence isn't restricted in terms of memory?

Yeah. We need to throttle Tor's memory usage. There's unfortunately not a lot of ways we can do that. In fact, there's only one option: MaxMemInQueues

I have a feeling from the reports I get, that this poses a problem in censored areas. Maybe, the constraint environment makes Tor run out of memory there, because it needs to work more for getting a connection.

Maybe we need to make this configurable. 🤔

tladesignz commented 1 year ago

Maybe we need to make this configurable.

72

keyboardcat1 commented 1 year ago

Also, is it normal behavior that there is a ton of general SOCKS errors when using obsf4? As I understand it, it is the bridge failing to connect to relays, as opposed to the client being unable to connect to the bridge, which would imply that the client is attempting to connect to invalid tor relays. I retried original snowflake, and for some reason it connects very reliably and quickly now (I think I forgot to clear cache last time). However, the connection is comparably slower to obfs4 despite the massive number of messages. Also, the WebSocket connection gets cut every 20s or so but successfully reconnects to the same bridge.

tladesignz commented 1 year ago

Also, is it normal behavior that there is a ton of general SOCKS errors when using obsf4?

No, that's not normal, but I hear reports from others describing this. So probably due to the censorship.

As I understand it, it is the bridge failing to connect to relays, as opposed to the client being unable to connect to the bridge, which would imply that the client is attempting to connect to invalid tor relays.

That doesn't sound right. Bridges run their own entry node and they're typically placed in a location which is connected well. Anyhow, I'm really no expert there, sorry.

I retried original snowflake, and for some reason it connects very reliably and quickly now (I think I forgot to clear cache last time). However, the connection is comparably slower to obfs4 despite the massive number of messages. Also, the WebSocket connection gets cut every 20s or so but successfully reconnects to the same bridge.

This is very interesting info, thanks!

keyboardcat1 commented 1 year ago

GitHub apparently is unblocked now (or was never blocked but I assumed it was) so I'll post this while I can. (My obfs4 bridge died, and snowflake stopped connecting reliably)

Unless the GUI or the rest of Tor is very memory intensive, it looks like MaxMemInQueues has been misconfigured. With a restriction of 50 MB, one would expect MaxMemInQueues to be in that order of magnitude. However, it seems like it has been set to around 5.2 MB (or 5 MiB). Here's what I'm talking about:

{GENERAL} We're low on memory (cell queues total alloc: 528 buffer total alloc: 5251072, tor compress total alloc: 0 (zlib: 0, zstd: 0, lzma: 0), rendezvous cache total alloc: 0). Killing circuits withover-long queues. (This behavior is controlled by MaxMemInQueues.)
Jul 31 05:07:52.000 [notice] {GENERAL} Removed 5218832 bytes by killing 1 circuits; 0 circuits remain alive. Also killed 0 non-linked directory connections. Killed 0 edge connections

Circuits get killed as soon as the sum of their allocated memory exceeds around 5 MB. This would explain the pattern I observe whenever I use bridges: Tor builds up microdescriptors, exceeds MaxMemInQueues, gets reset and so on, so that microdescriptors rarely exceed a count of 200, and progress stays stuck at 50%.

The real question should be how can it even connect in the first place? It must get extremely lucky to get the correct microdescriptors to build a circuit before it gets killed.

tladesignz commented 1 year ago

Ah, thank you for digging that up. Yeah, as I expected, it's the memory limitation.

The memory accounting is not that easy, though.

I played around with #72 again, and it remembered me, why I set it to 5 MB in the first place:

As soon as I set it higher, memory usage explodes during startup and exceeds 50 Mbyte, which makes it getting shot off by Apple's Jetsam memory accounting daemon immediately again.

I will, however, push changes which will let this setting be overridable by advanced users anyway, so users in difficult environments (like you) will be able to play with it and maybe discover settings which works for them. In the hope they'll report their findings.

I'll talk to Tor engineers, too. Maybe they can find a way to throttle memory consumption during startup, so we can improve the situation until Arti (A Rust Tor Implementation) arrives.

tladesignz commented 1 year ago

You can now override MaxMemInQueues. Fixes to the startup memory consumption are on their way to getting published, too.