Closed tladesignz closed 2 years ago
Ah, hey, @bitmold, you might have to say something about this, too!
We do have similar issues on Android, but they have generally been manageable by users and other apps. Tor-over-Tor does work, and not as poorly as you might think, but ideally it could be avoided.
Part of the reason we built NetCipher and the Intenet APIs in Orbot is for this very kind of thing, so that apps interested in Tor, whether they embed it or not, can query if Orbot is installed, if Tor is running, and if so, on what ports. It would be great if we could provide some similar API / lightweight SDK for this. Since Tor already essentially runs a number of localhost server ports, adding another one at a known static port for querying public info would be useful.
Question: can an app override another app's network extension? If Orbot is running as a VPN/network extension, but another app has its own network extension, who wins?
As for knowing if you are running over Tor, that is what https://check.torproject.org is for. I believe there is an actual json or other parseable file there beyond just the HTML page. We should figure that out. Ability to resolve .onion addresses is another indicator of course.
There's no compartmentalisation of apps on the localhost network. Meaning, Orbot will block ports for other apps and other >apps might just connect to Orbot's Tor SOCKS5 port.
That is fine, and matches what we do on Android, and what Tor does on desktop OSes with Tor browser. I am not sure if Tor supports adding authentication into its SOCSK5 port.
mode and gets around 3 minutes to do so), the other app's Tor (or anything else for that matter) might block the ports Orbot >defines for Tor to use.
Having all ports, including PT ports, be fully dynamic here seems like a good solution.
Other apps won't be able to access Orbot Tor's control port, as they would need the cookie for that. However, there's no >globally shared disk space. Other apps can't read the cookie.
I don't think we want other apps to be able to access the control port, unless somehow the user approves them, but even so, seems risky and potentially to cause conflict with multiple apps managing.
With Orbot, we've allowed other apps to request Onion Services to be setup, through Intent API calls, so there is some potential we could create some kind of service request like that, using URIs or other inter-app communication that iOS supports.
information, if currently not. Or can Tor provide a "canary" on the localhost network? Should we provide anything? Like, an >HTTP server on a fixed port, which just answers with 201 OK if Tor is running?
Yes, on the localhost and see my comment about check.torproject.org
copy. So Onion Browser should definitely just use Orbot's Tor VPN, if it's available.
yes, seems like a good app to prototype all of this inter-app collaboration with, and also OnionShare.
There's other apps like OnionShare, which might need their own Tor, because it's going to serve stuff. Other apps won't be >able to access the filesystem of Orbot, so they won't be able to set up the server.
I think OnionShare may be a case where we don't use a network extension, and it should run its own Tor instance. Tor-over-Tor may be fine.
Additionally, it seems highly unlikely, that Apple lets us run a VPN which also integrates a server. Needs to be tested through >submission of a burner project.
Tor already has multiple server ports, but maybe since it isn't in Swift it won't be seen as "a server"?
If they let us, however, Orbot might need a REST API for other apps, so they'll be able to set the configuration.
Yes, this is what we do on Android.
If not, how to allow other Tor apps? With leaf, we might be able to offer a SOCKS5 port where other apps could connect, >which traffic we then could let bypass Orbot's Tor. However, that could lead to a security problem. So that needs to be explicitly >configured by the user.
Not sure I like the SOCKS bypass option, but open to talking about it. It could be one way for OnionShare to have its own Tor which proxys out through SOCKS in Orbot.
Should we show the Tor control port cookie to the user, who could then copy-paste it into another app, which wants to make >use of it?
This doesn't feel like something we should do, but happy to explore potential user stories where it is necessary.
How should other apps interact with the user? Should they show an alert to them like "There seems to be Orbot running, >should we just use that? If no, we'll replace it with our own VPN. / If no, we're going to run Tor in Tor. yes/no"
YES, this should be at least what we offer.
How can we protect Orbot's Tor SOCKS5 port?
Need to check torrc options if possible, or just leave it open as we do on Android and desktop OS.
@ahf told me, that on desktop that is not so much of an issue, because the Tor Browser's Tor communicates via file socket. DNS and SOCKS is only used by folks who torify their complete machine. I guess, these are people who know what they're doing and can debug issues for themselves with the power of a shell.
I guess I have to read through Orbot Android's code a little more deeply on what you're already providing there. App interaction is very limited on iOS, though. There's no IPC like Intents. Custom-scheme-URIs seem like a really uncanny way of doing IPC. A REST server would probably the easiest.
Question: can an app override another app's network extension? If Orbot is running as a VPN/network extension, but another app has its own network extension, who wins?
There's no override
in any inheritance sense or in the sense of overriding control or something.
There's a list of "VPNs". The user can see and also control it (to some extent) in the Settings app. The Settings app can create a few on its own, like classic IPSec. Apps can have Network Extensions and install config profiles for that as one or more VPN entries.
The app can see all the entries, which belong to it (resp. its Network Extension), but not the others. It can enable one and start one of its own, that stops all others. That's it. Since an app can really only run, when it's in the foreground, the user actually decided to change the VPN, more or less explicitly by at least starting that app and hopefully pressing a button in it.
I'm going to dig around in that API again, but AFAIR, there's nothing which tells you if another VPN is currently active, and which one it is.
I don't think we want other apps to be able to access the control port, unless somehow the user approves them, but even so, seems risky and potentially to cause conflict with multiple apps managing.
True. Unfortunately, a lot of features require access, e.g. circuit display.
Tor already has multiple server ports, but maybe since it isn't in Swift it won't be seen as "a server"?
Nothing to do with the language. To be more precise: I doubt heavily, that Apple approves apps which contain a network extension which runs a server on the Internet. Which we would, if Orbot would start onion services and forward them to any other app.
How should other apps interact with the user? Should they show an alert to them like "There seems to be Orbot running, should we just use that? If no, we'll replace it with our own VPN. / If no, we're going to run Tor in Tor. yes/no" YES, this should be at least what we offer.
That's not for us to offer, merely to recommend. Well, in a library, maybe, but I'd rather not provide any UI there. That opens up a can of worms, like localization.
Ability to resolve .onion addresses is another indicator of course.
Hmmmm. Since it turned out, that iOS is blocking these by default to not accidentally leak these requests, that's actually a viable option to test without a leak happening.
So, what domain would be a good one to test? torproject.org's one? 2gzyxa5ihm7nsggfxnu52rck2vv4rvmdlkiu3zzui5du4xyclen53wid.onion
?
How can we protect Orbot's Tor SOCKS5 port? Need to check torrc options if possible, or just leave it open as we do on Android and desktop OS.
Hm. Actually we don't need to take care of that at all. Because, what are we afraid of? If Orbot's Tor VPN is running, the app traffic ends up there, anyway. If an app wants to circumvent leaf, that's not really a problem for us.
Custom-scheme-URIs seem like a really uncanny way of doing IPC
Android Intent's are essential custom URIs, ala keanu://invite?id=foo where "keanu" is the package id, "invite" is the action, and the arguments are the various "extras".
Apple has provided this as a way for inter-app communication, whether we call it IPC formally or not, and we should take advantage of it.
Apple has provided this as a way for inter-app communication, whether we call it IPC formally or not, and we should take advantage of it.
Unfortunately, it's not so easy. Custom URLs have several drawbacks:
A network extension can't handle custom URLs. Only the companion app can. On Android, that would be the equivalent of services not being able to receive intents, only activities.
There's no response mechanism. On Android, Intents can have answers (e.g. a list of selected images). That's not possible with custom URLs. We could work around that, by letting the senders provide a callback URL. But that is really ugly, too:
Apps wanting a response would need to implement custom URLs, too.
Custom URLs always change the active app. Not sure, if an app will be fully rendered, before it could call the provided callback URL which would jump back to the requesting app, but I'm betting hard on that there's going to be a lot of flicker due to the back-and-forth. Additionally, the requesting app would need to take care to jump back to the right position in the UI from every state. It could have been completely killed in the mean time. That's quite a hassle.
Part of the reason we built NetCipher and the Intenet APIs in Orbot is for this very kind of thing, so that apps interested in Tor, whether they embed it or not, can query if Orbot is installed, if Tor is running, and if so, on what ports.
Can you point me to that? Because, when reading through Orbot Android, I could only find these three intent handlers which allow some control:
Interestingly enough, they seem all to be without any response. While for Onion Browser, the most important things I need to do, all have responses:
Possible solutions:
Use a custom URL scheme to send the user to Orbot's bridge settings instead of showing them inside Onion Browser.
As a first solution, which doesn't create the need of running an additional server: Set Tor's control port to a fixed port. Either 9051, as suggested by the docs, because we're going to be the most official Tor VPN for the foreseeable future on iOS but might run into potential clashes with that, or a far-out one, which is highly unlikely to clash so gives high confidence, that it's Orbot. (However, an imitating app could just use that, too.) Even without authentication, we could still test the response. Need to check, if it behaves distinguishable and deterministic in that case.
That's only possible with authenticated access to Tor's control port. These are the options:
HashedControlPassword
: We could either set a fixed one, which eventually will get loose, or let the user create them (even multiple for different apps) and hand them out to trustworthy apps. (Minus: Susceptible to social engineering attacks from attacking apps., Plus: Easy solution for other apps to make use of Orbot's Tor, too.)For Onion Browser for now, we should just test if Orbot is installed, and use it if so. It can also not display circuit info if needed when in Orbot mode.
Or explore the shared folder solution for Onion Browser only.
also explore having Orbot provide pass through SOCKS proxy on-demand to apps that request it.
Have a fully "auto" control port and read the port from the shared file
registered "app site association" with https://orbot.app domain
Ok, so after a call we came to the following conclusion:
ControlPort
is listening, which is not fixed, so other apps cannot easily impersonate it. (Actually, do we need to randomize it ourselves, if Tor is too predictable?)4 - I'm not sure we should care about "other apps that bring their own VPN" (other than OB, which I think we have to change). The only use case I can imagine at the moment is that, assuming Orbot gets a "you need to stop" signal when the new VPN wants to start, the Orbot pops a message that says "Orbot Quitting".
Actually, iOS is completely handling the lifecycle of Network Extensions. The Orbot companion app receives notifications about state changes, so that is taken care of already.
So, a first implementation of remote-controlling Orbot is released with version 1.3.0.
If it happens, that we need to improve the design, we'll follow up in a new issue.
So, when this app hits the app store, we'll finally have a fully-torified iOS[1].
But that brings us to a new problem, we didn't have to think about before:
As far as I understand, the situation is the following: (And please correct me, if I'm wrong, which might well be!)
201 OK
if Tor is running?Foot notes:
@n8fr8, what problems does Orbot Android already solve? How? Which ones not? Why? @ahf, how does Tor on desktop solve these issues? Which ones doesn't it care about? Why? What suggestion do you have? @mtigas, @DavidMOliver, @m4mb01t4l14n0, any additional insights?