celzero / rethink-app

DNS over HTTPS / DNS over Tor / DNSCrypt client, WireGuard proxifier, firewall, and connection tracker for Android.
https://rethinkfirewall.com/
Apache License 2.0
3k stars 153 forks source link

Firewall may be shouldn't block all TCP and UDP conns #26

Closed ignoramous closed 1 year ago

ignoramous commented 4 years ago

The firewall mode shouldn't block localhost TCP and UDP.

May be it also shouldn't block connections on the private IPv4 (v6 isn't supported) space? May be it should.

Interestingly, some folks want to block all LAN traffic. So, that should be an option too?

Discuss.

ignoramous commented 4 years ago

Case in point?

08-16 08:10:03.576 23934 23934 E chromium: [0816/081003.575374:ERROR:elf_dynamic_array_reader.h(61)] tag not found
08-16 08:10:03.584 15668 16890 E GoLog   : [0816/081003.575374:ERROR:elf_dynamic_array_reader.h(61)] tag not found
08-16 08:10:03.594 15668 16867 F libc    : Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x31f000001b9 in tid 16867 (Thread-24), pid 15668 (elzero.bravedns)
08-16 08:10:03.736  2152  2152 E ndroid.systemu: Invalid ID 0x00000000.
08-16 08:10:03.797 23937 23937 I crash_dump64: obtaining output fd from tombstoned, type: kDebuggerdTombstone
08-16 08:10:03.800  1259  1259 I /system/bin/tombstoned: received crash request for pid 16867
08-16 08:10:03.802 23937 23937 I crash_dump64: performing dump of process 15668 (target tid = 16867)
08-16 08:10:03.809 23937 23937 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
08-16 08:10:03.809 23937 23937 F DEBUG   : Build fingerprint: 'OnePlus/OnePlus6/OnePlus6:10/QKQ1.190716.003/2005052051:user/release-keys'
08-16 08:10:03.809 23937 23937 F DEBUG   : Revision: '0'
08-16 08:10:03.809 23937 23937 F DEBUG   : ABI: 'arm64'
08-16 08:10:03.809 23937 23937 F DEBUG   : Timestamp: 2020-08-16 08:10:03+0530
08-16 08:10:03.809 23937 23937 F DEBUG   : pid: 15668, tid: 16867, name: Thread-24  >>> com.celzero.bravedns <<<
08-16 08:10:03.809 23937 23937 F DEBUG   : uid: 10421
08-16 08:10:03.809 23937 23937 F DEBUG   : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x31f000001b9
08-16 08:10:03.809 23937 23937 F DEBUG   :     x0  0000006f1a6ea600  x1  0000000000000000  x2  00000040004bfea0  x3  0000000000000003
08-16 08:10:03.809 23937 23937 F DEBUG   :     x4  0000000000000160  x5  0000004000297e90  x6  000000700c853000  x7  0000000000f421c2
08-16 08:10:03.809 23937 23937 F DEBUG   :     x8  0000006f1a7aac14  x9  000000000000000c  x10 0000000000000002  x11 0000000000000030
08-16 08:10:03.809 23937 23937 F DEBUG   :     x12 0000000000a56b80  x13 00000003e8000000  x14 00044460ac096168  x15 0000a507849446f3
08-16 08:10:03.809 23937 23937 F DEBUG   :     x16 000000700870f8f0  x17 0000007008701070  x18 0000006ec0bea000  x19 0000006f1a6ea600
08-16 08:10:03.809 23937 23937 F DEBUG   :     x20 0000031f000001a4  x21 0000006f27239aa0  x22 0000006f27239ab0  x23 0000006f1a7aaa00
08-16 08:10:03.809 23937 23937 F DEBUG   :     x24 0000006f27239aa0  x25 0000006f26d1d394  x26 0000000000000000  x27 0000000000000010
08-16 08:10:03.809 23937 23937 F DEBUG   :     x28 0000004000182900  x29 0000006ec2837b90
08-16 08:10:03.809 23937 23937 F DEBUG   :     sp  0000006ec2837b70  lr  0000006f26d16418  pc  0000006f26d197b4
08-16 08:10:03.809 23937 23937 F DEBUG   :
08-16 08:10:03.809 23937 23937 F DEBUG   : backtrace:
08-16 08:10:03.809 23937 23937 F DEBUG   :       #00 pc 00000000005d47b4  /data/app/com.celzero.bravedns-S0OlU-rPT9myMvnoLKv6fQ==/base.apk (offset 0xb000) (tcp_process_refused_data+32)
08-16 08:10:03.837   728 23940 E ResolverController: No valid NAT64 prefix (377, <unspecified>/0)
08-16 08:10:03.837   728 23941 E ResolverController: No valid NAT64 prefix (377, <unspecified>/0)
ignoramous commented 4 years ago

65 does something as crude.

4-FLOSS-Free-Libre-Open-Source-Software commented 3 years ago

The firewall mode shouldn't block localhost TCP and UDP.

by default safely exclude [::1]/128 127.0.0.0/8

May be it also shouldn't block connections on the private IPv4 (v6 isn't supported) space? May be it should.

Discuss.

To not break things by default broadcast and multicast & mdns? 224.0.0.0/4 for DLNA/wifidisplay/airplay/chromecast/spotify/IoT devices/ wifi vacum robot/ own router webinterface / etc. and only exclude subnet of active wifi and private 169.254.0.0/16 yes, but not all /intranet ranges.

ignoramous commented 3 years ago

See: https://github.com/tailscale/tailscale/blob/c6d3f622e9b52d226232a1dbc5b56f61b2ba5bf9/ipn/ipnlocal/local.go#L998-L1015

And: https://github.com/M66B/NetGuard/blob/master/app/src/main/java/eu/faircode/netguard/ServiceSinkhole.java#L1276-L1353

Also: https://github.com/ViRb3/wgcf/issues/42#issuecomment-889015992

ItsIgnacioPortal commented 1 year ago

It would be good if apps could be individually granted LAN access, instead of it just being a global switch like NetGuard does.

ignoramous commented 1 year ago

That's an interesting suggestion.

So, a global / universal rule like Block all LAN IPs

And then, per individual app, you'd trust / allow LAN IP subnets?

ItsIgnacioPortal commented 1 year ago

And then, per individual app, you'd trust / allow LAN IP subnets?

I don't see much of a point in allowing only specific subnets. I think it should be an ON/OFF switch, per app

ignoramous commented 1 year ago

Gotcha. Shouldn't be too hard to implement it. Let's see: https://github.com/celzero/rethink-app/issues/801

Rhys-T commented 1 year ago

KDE Connect also doesn't work right now without excluding it from Rethink (or pausing/stopping Rethink completely), because of the multicast/broadcast issue - it can't find or communicate with its counterpart on the desktop machine.

Regarding mDNS specifically, there are actually several different issues that could keep it from working, only one of which seems to have anything to do with this.

mDNS notes - [Android only got support for resolving .local domains through mDNS in late 2021.][andmdns] - Even when it does support mDNS, "VPN and mobile data connections are excluded from .local resolution" - meaning that Android will treat .local like any other TLD and send it to Rethink, because it thinks it's on a VPN. ([personalDNSFilter ran into that too][pdnsfmdns] - I have more detailed notes in that issue.) - While Android's resolver won't send .local domains to mDNS with a 'VPN' running, normally an app can still send mDNS requests itself and get a response. For instance, in Termux, I can do `dig @224.0.0.251 -p5353 some-machine.local`. With Rethink running, this no longer works, probably because multicast packets aren't making it through. (That's the one that is most relevant to this issue.) - This one may not even be an issue here, but: Some of the blocklists - e.g. the [StevenBlack][] one - have an entry that says `127.0.0.1 local`. personalDNSFilter interprets that as being a block for _the entire .local TLD_. I don't know whether Rethink treats host-file entries as being wildcards like pDNSf does, but if so, that could cause issues even if the other things are fixed.
ignoramous commented 1 year ago

KDE Connect also doesn't work right now without excluding it from Rethink (or pausing/stopping Rethink completely), because of the multicast/broadcast issue - it can't find or communicate with its counterpart on the desktop machine.

In v054c, you can enable Do not route Private IPs in Configure -> Network (which also would not not route multicast IP ranges through Rethink's network namespace anymore). Can you please see if that fixes KDE Connect?

Re: mDNS: Thanks. That's a lot of information. I don't think I have quite enough expertise to make incoming multicast probes work, but we'll see.

ignoramous commented 1 year ago

Implemented. For a power-user use-case, see:

Feel free to reopen in case something's wrong.

ignoramous commented 1 year ago

https://github.com/celzero/rethink-app/blob/66f29707f1cf196b70809e13b35624586135c0a6/app/src/main/java/com/celzero/bravedns/service/BraveVPNService.kt#L1911-L1926

https://github.com/celzero/rethink-app/blob/66f29707f1cf196b70809e13b35624586135c0a6/app/src/main/java/com/celzero/bravedns/service/BraveVPNService.kt#L1948-L1957

Rhys-T commented 1 year ago

In v054c, you can enable Do not route Private IPs in Configure -> Network (which also would not not route multicast IP ranges through Rethink's network namespace anymore). Can you please see if that fixes KDE Connect?

I just tried that setting, and it does seem to let KDE Connect see my computer. (Even if the app is set to be blocked - which makes sense, given the option's description, but for now I think I'll keep using the 'exclude' workaround instead, so I can still block other apps from seeing the LAN.)

Re: mDNS: Thanks. That's a lot of information. I don't think I have quite enough expertise to make incoming multicast probes work, but we'll see.

When you say 'incoming multicast probes', are you referring to other computers asking for the IP address of some-android-device.local? I hadn't even thought of that case - I'm not sure if Android even attempts to give itself an mDNS name that way. (Although it does seem to use mDNS + DNS-SD to let adb find its Wireless Debugging server… and that still works when Rethink is on.)

What I was referring to is: Normally, when (a new enough version of) Android is trying to resolve the domain example.local - because you tried to visit it in the web browser, or ssh into it from Termux, or whatever - it tries to do so using an mDNS query on the local network, rather than[^rather] asking a normal DNS server. However, if it's using a VPN app - even if it's just a pseudo-VPN like Rethink - it disables that functionality, and uses normal DNS for everything. The only way around this that I can come up with is for Rethink to be able to intercept DNS queries for *.local, and proxy them to mDNS itself. [^rather]: Or possibly 'in addition to' - I'm not entirely sure.

Currently I just have the few *.locals I need listed as custom hosts in personalDNSFilter, and update them manually on the rare occasion that their addresses change. (I was already doing this before I switched to Rethink - pDNSf has the same issue when it's being the 'VPN'.)

ignoramous commented 1 year ago

Thanks for confirming that KDE Connect works.

For instance, in Termux, I can do dig @224.0.0.251 -p5353 some-machine.local. With Rethink running, this no longer works, probably because multicast packets aren't making it through

If all Rethink has to do is forward .local / .lan / .internal (are there more?) to 224.0.0.251:5353 over UDP (and whatever it's equivalent is for IPv6), then this is much easier to do. But: I'm confused about the multicast packets not making it through part.

Currently I just have the few *.locals I need listed as custom hosts in personalDNSFilter, and update them manually on the rare occasion that their addresses change

Neat. We intend to implement this someday... #316

Rhys-T commented 1 year ago

(Note: take everything I post with a grain of salt, and check the actual specifications. I am not an expert on this stuff by any means.)

If all Rethink has to do is forward .local / .lan / .internal (are there more?) to 224.0.0.251:5353 over UDP (and whatever it's equivalent is for IPv6), then this is much easier to do.

Not sure where that list came from. As far as I know, .lan and .internal aren't defined anywhere official; they're just currently-nonexistent TLDs that some local setups with their own internal DNS servers tend to use, because they're unlikely to conflict with anything real.[^dothome] None of the networks I've had to use do that, so I can't tell you what would need to be done for those cases. .local sometimes gets used that way as well (so there might need to be a checkbox to control whether to handle it via mDNS or treat it like .lan etc.), but its official purpose these days is mDNS.

[^dothome]: I've also heard of .home and .corp being used like that. Apparently those actually got sold to become real TLDs at one point, but the sale was reversed once ICANN found out just how many setups that would break. Still not officially reserved, though.

Besides .local, it looks like the only other domains that are supposed to go to mDNS are the reverse-DNS domains corresponding to self-assigned addresses (169.254/16[^cidr] or FE80::/10) - see here and here.

If a domain does need to use mDNS, there are basically two ways to do it:

[^cidr]: Here's what I was able to find out on how abbreviated CIDR ranges like that are supposed to work.

For IPv6, the equivalent address is [FF02::FB]:5353. (The spec actually reserves FF0X::FB where X is 1 through F, but it looks like only FF02::FB is currently used.)

But: I'm confused about the multicast packets not making it through part.

I may have misunderstood, but it sounded to me like this issue was keeping (among other things) packets that were targeted to multicast addresses from making it out of Rethink's 10.111.222. net and into the real 192.168.1. (or whatever) net. What I was describing with that Termux command was actually separate from the "can Android (or Rethink) resolve mDNS .local names correctly" thing: I was basically trying to bypass Android and Rethink entirely, and send a UDP packet (containing a legacy one-shot query) to 224.0.0.251:5353 myself using the dig command, so I could ask for the address without getting onto a desktop computer, and put it into pDNSf's custom hosts list. With pDNSf's pseudo-VPN, that works (even though the system itself can't resolve those names). With Rethink's pseudo-VPN, dig times out waiting for a response - and according to Wireshark, the computer it's asking for is never even receiving the query. That seemed to suggest that the query wasn't making it past Rethink because it was multicast. (Termux was not set to be blocked at all during that test, nor do I have any rules for that IP address.)

ignoramous commented 1 year ago

Thanks a lot for the links and references. Appreciate it.

Legacy one-shot queries

These are easy to implement. I'll take a stab at it for landing it in v055.

send a UDP packet (containing a legacy one-shot query) to 224.0.0.251:5353 myself using the dig command, so I could ask for the address without getting onto a desktop computer, and put it into pDNSf's custom hosts list. With pDNSf's pseudo-VPN, that works (even though the system itself can't resolve those names). With Rethink's pseudo-VPN, dig times out waiting for a response - and according to Wireshark, the computer it's asking for is never even receiving the query. That seemed to suggest that the query wasn't making it past Rethink because it was multicast.

Gotcha. This dig command would now probably work with Do not route Private IPs enabled.

pdnsf, btw, only traps UDP connections sent to its DNS endpoint (it leaks DNS over TCP dig +tcp ... which is okay, but I've seen multiple ad tracking SDKs use DNS over TCP and pdnsf wouldn't catch those) and lets the rest through as-is. That's one reason I can think of why dig did just fine with the one-shot mdns query.

For Rethink, I can see why connections over multicast / reserved IPs may not work. Btw, Rethink v054 onwards has Packet capture (PCAP) mode if it helps to debug this. With Packet capture enabled, you can either log packets to logcat and grep for rdnspcap, or log packets to a file stored on external storage (usually, the Downloads folder). I'd like to debug this and fix it someday, but it isn't priority (given Exclude / Do not route Private IPs are neat compromises ;)

ignoramous commented 1 year ago

Thanks for the pointers. We've implemented one-shot mdns for v055 (release due in a week) https://github.com/celzero/firestack/commit/af83b9ff4a1d1804ae367330cb6a66d805d23f0e

Hopefully, it works.