lkl / linux

Linux kernel source tree
https://lkl.github.io/
Other
820 stars 137 forks source link

Android: non-root network driver (VPN API) #379

Open thehajime opened 7 years ago

thehajime commented 7 years ago

@phhusson

from https://github.com/lkl/linux/issues/59#issuecomment-253587428

Implementing ethernet drivers using VPN API (this wouldn't require root)

I've been using raw socket for android network backend but I was wondering if we can open a device without root privilege. Do you have a clear idea on using VPN API to open a network backend without root ?

linhua55 commented 7 years ago

Can not! This method need iptables to forward IP packet, But not for non-rooted Android.

The TUN is working on OSI layer 3, so what be read and write here is the IP packet. From APP level, Android/Java do not support raw socket, so we can not directly bypass these IP packet into network interface. But we can protect socket from VPN service, so its possible to use a protected socket to send/get the packet. TCP/UDP socket is working on OSI layer 4, so we need do a layer translate here

from http://www.thegeekstuff.com/2014/06/Android-vpn-service/

refer to: http://www.thegeekstuff.com/2014/06/Android-vpn-service/ https://developer.android.com/reference/android/net/VpnService.html

thehajime commented 7 years ago

Thanks @linhua55 for the comment.

I can see your point. Maybe opening a pre-created tap(-like) device doesn't require a root but the host kernel should be configured. I was just wondering if there is any ultra-special method that we can do the job :)

phhusson commented 7 years ago

Ok, so first, for what you quoted: USB devices are accessible to applications in Andoid. So what I wanted was to export an usb/ethernet dongle to an application hosting LKL, use VPN API to host a tun/tap, and have LKL do the magic.

Then, for raw sockets, I've checked SELinux rules of AOSP, and only process have net_raw capability. Even worse, not even privileged applications have it. (though it's not never_allow-ed, so some OEMs might enable it if needed).

I see one way out, which I need to check deeper: Have Android route the tun/tap to other interface. I'll see what can be done there.

What are you trying to do with that? Depending on this, there might be some ways

thehajime commented 7 years ago

@phhusson thanks for the detail.

What are you trying to do with that? Depending on this, there might be some ways

I wanted to give network access to an LKL application (hijacked, or linked) without root privilege. Right now my choice is only a raw socket among available LKL network backends (i.e., tap, macvtap, dpdk, raw socket, vde). NET_RAW capability can be used for packet_socket: in my crafted web browser case (https://twitter.com/thehajime/status/900596946120736770), it added NET_RAW but I needed to use with Xposed (it means rooted).

phhusson commented 7 years ago

Ok, MPTCP is your target, I can see we have the same goals ;-)

I'll check if it's possible to trick Android framework to NAT us to the internet.

phhusson commented 7 years ago

So bad news. I think it's possible, without doing framwork change, if you allow /system modification or OEM permissions.

We can trigger NAT with INetworkManagementService's enableNat(in interface, out interface). This requires android.permission.CONNECTIVITY_INTERNAL, which is signature|privileged, which means either to be in /system/priv-app/ or to be signed by OEM.

Doing this through adb seems to be a no go in Android 7 (I think it might be possible on Android 6, I need to check)

thehajime commented 7 years ago

Thanks @phhusson for the useful information. So using NAT needs the same requirements as pf_packet creation, no ? (I needed to sign to assign permission.NET_RAW: /system/priv-app didn't work for me on Android6)

I will try to play/check if there would be other tricks.

phhusson commented 7 years ago

Hum, I've checked L/M/N and I can't see any NET_RAW permission. And from frameworks/base/core/java/com/android/internal/os/ZygoteInit.java, NET_RAW capability is granted only to system_server Would you have some additional informations about this?

Though I'm pretty confident putting app in priv-app should be enough for NAT. I'll try that next week.

thehajime commented 7 years ago

Would you have some additional informations about this?

Ah, I actually edited /system/etc/permission/platform.xml (to add net_raw entry) in addition to the signature, but it only works on the emulator (I'm not familiar with all internals of android so, it might be something wrong to do this).

mxi1 commented 7 years ago

@thehajime Creating tap interface requires root permission. the only VPN-interface supported by Android is tun type right now. Following the "tap" virtio-net code, I tried to create one virtio-net-tun driver, but it seems the LKL kernel cannot boot up due to the tun interface. Has anyone try the 'tun'-like interface for LKL ?

thehajime commented 7 years ago

@mxi1 it would be helpful if you can share your errors in detail when lkl kernel cannot start.

I'm not aware of any tun-like interface users so far.