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
2.83k stars 144 forks source link

LAN access in VPN Lockdown mode #1618

Closed mvevitsis closed 1 month ago

mvevitsis commented 1 month ago

Continuing the discussion from reddit:

System firewall (lockdown mode): Outgoing to LAN -> blocked Incoming from LAN -> allowed

RethinkDNS + system firewall (lockdown mode) Outgoing to LAN -> allowed, unless you exclude the app in which case it will be blocked by the system firewall as above (can also be blocked directly by rethink firewall rules, e.g. block 192.168.1.*:5353) Incoming from LAN -> not working (routing issue?)

So basically: To send, you need rethink on. To receive, you need rethink stopped (not paused!)

Strangely, netguard has the opposite issue. With netguard on and in lockdown mode you can receive, but not send.

I haven't looked at netguard's source code yet (or rethink's) to compare them.

mvevitsis commented 1 month ago

Update:

Invizible handles both outgoing and incoming LAN connections properly, even with lockdown mode enabled.

https://github.com/Gedsh/InviZible

I haven't looked at the source yet but this proves it is possible to fix for both directions.

ignoramous commented 1 month ago

A user writes (mirror),

To reproduce, enable rethink, enable lockdown mode (always on VPN + block connections without VPN) then make sure you do not enable do not route LAN thru rethink.

Open local send on the computer and phone.

Confirm you can send a file from the phone to the computer.

Now try sending from the computer to the phone, confirm the computer cannot find the phone.

Next enable 'do not route... ' in rethink and repeat the steps (only possible on older versions of rethink, now if you enable lockdown this option gets greyed out).

You will notice this time the phone cannot send to the computer, but the computer can send to the phone (this is expected because block connections without VPN only blocks incoming connections).

ignoramous commented 1 month ago

Incoming from LAN -> not working (routing issue?)

I think Rethink wouldn't let Incoming from LAN with or without VPN Lockdown (ie, Block connections without VPN) turned ON (and Do not Private IPs turned OFF). Can you confirm? If so, this problem won't be solved unless we overhaul how we treat incoming packets (which is not a trivial undertaking and as such I don't see us investing effort in to it anytime soon given the already existing open feature requests / issues).

The current workaround is to turn OFF Block connections without VPN (VPN Lockdown) mode, then:

mvevitsis commented 1 month ago

That's correct. Even with block connections without VPN off, as long as they are being routed thru rethink incoming LAN connections do not work.

ignoramous commented 1 month ago

This issue then is a dup of #577 (closing, but feel free to re-open)

ignoramous commented 1 month ago

Track impl at: https://github.com/celzero/firestack/issues/77

mvevitsis commented 1 month ago

Track impl at: https://github.com/celzero/firestack/issues/77

Bookmarked, looking forward to possible fix.

Lanius-collaris commented 1 month ago

Endpoint-Independent Mapping is for UDP punching, can't fix accepting connections initiated by other devices in a LAN. https://tailscale.com/blog/how-nat-traversal-works


Incoming from LAN -> not working (routing issue?)

I think this is expected behavior if your subnet is routed via the TUN controlled by rethink. You can check with adb shell ip route get <IP>

reverse proxy / port forward may be a solution. @ignoramous

mvevitsis commented 1 month ago

@Lanius-collaris

InviZible Pro is able to route incoming LAN requests.

Checking its routing behavior via adbshell, I used the command in your post above to check 10.0.0.1

The result is that it is routed over tun1 which is indeed the interface currently in use by inviZible. It has to be this way, or the system firewall in lockdown mode will block requests to 10.0.0.1

Of course invizible doesn't have a built in wireguard client. I was able to get it to work, but I don't consider this doable for most people. Please note both profiles are in lockdown mode.

Messenger_creation_f1113f24-9752-4288-bb1e-3ef7d5605dba.jpeg

If someone is a networking beginner and they just want to use wireguard in lockdown mode with KDE connect they are not going to figure this out.

ignoramous commented 1 month ago

Endpoint-Independent Mapping is for UDP punching, can't fix accepting connections initiated by other devices in a LAN. https://tailscale.com/blog/how-nat-traversal-works

If Rethink allows UDP hole-punching, wouldn't those P2P apps be able to connect through to the endpoints on this side of (a full-cone NAT?) Rethink?


@mvevitsis

InviZible Pro

Unsure what it does to make it work... but it excludes a range of IPs (ie, asks Android to route those outside its tunnel):

        List<IPUtil.CIDR> listExclude = new ArrayList<>();
        if (!firewallEnabled || compatibilityMode || fixTTL) {
            listExclude.add(new IPUtil.CIDR("127.0.0.0", 8)); // localhost
        }

        if (!torIsRunning && (apIsOn || modemIsOn) && !fixTTL) {
            // USB tethering 192.168.42.x
            // Wi-Fi tethering 192.168.43.x
            listExclude.add(new IPUtil.CIDR("192.168.42.0", 23));
            // Bluetooth tethering 192.168.44.x
            listExclude.add(new IPUtil.CIDR("192.168.44.0", 24));
            // Wi-Fi direct 192.168.49.x
            listExclude.add(new IPUtil.CIDR("192.168.49.0", 24));
        }

...

        if (lan && (!(blockIPv6DnsCrypt && modulesStatus.getDnsCryptState() != STOPPED)
                || useIPv6Tor && modulesStatus.getDnsCryptState() == STOPPED
                && modulesStatus.getTorState() != STOPPED)) {

            builder.addRoute("::", 0);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                excludeIPv6Multicast(builder);
            }

If you're familiar with the app, its settings and modes of working, it might be worth asking the InviZible Pro developers what makes incoming connections work on your Android.

Lanius-collaris commented 1 month ago

Interesting, Intra allows incoming TCP as well as InviZible Pro.

mvevitsis commented 1 month ago

Tethering is allowed by the system even with lockdown mode on; I don't think these are related.

I could ask him but he probably doesn't like me because I argued with him about letting me set the bootstrap resolvers for dnscrypt to 127.0.0.1 or null (I use a stamp, so I don't need them).

ignoramous commented 1 month ago

Interesting, Intra allows incoming TCP as well as InviZible Pro.

Intra allows apps to bind to underlying interfaces. I sent a PR to fix this, but they didn't bother (and so, Intra should not even work when VPN is in Lockdown mode aka Block connections without VPN is turned ON): https://github.com/Jigsaw-Code/Intra/pull/420

Intra tun2socks over LwIP (and supports endpoint-independent mapping), but Rethink has switched to gvisor's netstack.

ignoramous commented 1 month ago

I could ask him

Thanks. Feel free to loop me in.

Lanius-collaris commented 1 month ago

Intra allows apps to bind to underlying interfaces.

Seems Invizible has the same bug. Tested with busybox nc -l -p 10000 -s ::%30 (30 is my wlan0) @ignoramous

mvevitsis commented 1 month ago

Intra allows apps to bind to underlying interfaces.

Seems Invizible has the same bug. Tested with busybox nc -l -p 10000 -s ::%30 (30 is my wlan0) @ignoramous

I am not rooted, so I can't use BusyBox, but I haven't seen any apps fail to connect after enabling lockdown mode with invizible. Theoretically if they bind to an interface other than tun* the system firewall should block them, though.

However, much like rethink's 'use all available connections' option, using invizible seems to ignore Android's active network (both WWAN and WLAN icons are showing in the status bar). I am not sure why it is doing that.

ignoramous commented 1 month ago

Seems Invizible has the same bug.

It isn't a bug? From what I know, the VPN app has to opt-in to allow sockets from other installed apps to bind to interfaces other than the VPN's tun device. From its code, InviZible does not opt-in to allow for this. The bind may be working for you because InviZible excludes certain IP ranges by default (as discussed above).


much like rethink's 'use all available connections' option, using invizible seems to ignore Android's active network (both WWAN and WLAN icons are showing in the status bar). I am not sure why it is doing that.

Why is this concerning? If "use all available networks" is turned ON, then the VPN app, if it supports it, must be able to connect via any of the active networks (wifi, mobile, ethernet, usb etc)

mvevitsis commented 1 month ago

Not concerning, just thought it was interesting. It doesn't seem to be looping any traffic back through itself like rethink can (it doesn't have any features that would require this afaik).

I wasn't able to get the second, wireguard VPN in my diagram to use invizible's dnscrypt-proxy as its default dns (this would only apply to apps installed inside the work profile that didn't already pass through rethink's local VPN). I guess it doesn't listen on its interface IP (10.1.10.1) or the work profile tun1 cannot access tun0.

Lanius-collaris commented 1 month ago

It isn't a bug?

Sorry. Doesn't appear when tor is enabled (Some very old versions do?), so it's not a bug. @ignoramous

Lanius-collaris commented 1 month ago

@mvevitsis

I am not rooted, so I can't use BusyBox

Running Busybox doesn't require a /system/bin/busybox, you can install a terminal emulator (e.g. Termux) or place a statically linked BusyBox in /data/local/tmp/.

mvevitsis commented 1 month ago

@mvevitsis

I am not rooted, so I can't use BusyBox

Running Busybox doesn't require a /system/bin/busybox, you can install a terminal emulator (e.g. Termux) or place a statically linked BusyBox in /data/local/tmp/.

I got it working in termux, thanks

ignoramous commented 1 month ago

InviZible Pro

Apparently, InviZible working for inbound LAN is due to broken Block connections without VPN (VPN Lockdown) implementation in Android: https://issuetracker.google.com/issues/280462382 / via: https://github.com/mullvad/mullvadvpn-app/issues/4643#issuecomment-1531523100

mvevitsis commented 1 month ago

InviZible Pro

Apparently, InviZible working for inbound LAN is due to broken Block connections without VPN (VPN Lockdown) implementation in Android: https://issuetracker.google.com/issues/280462382 / via: https://github.com/mullvad/mullvadvpn-app/issues/4643#issuecomment-1531523100

I'm not sure it's actually broken or if it's by design. Incoming connections have never been filtered by that setting, only outgoing. So if anything that is the expected behavior.

Whether that's a security risk is debatable but by default Android has nothing listening and all ports are closed.

I posted in there to suggest that they just add a toggle to allow/disallow LAN connections in lockdown mode (both incoming and outgoing) which would solve this issue for both camps (the people that want it blocked, and those who don't).