doronz88 / pymobiledevice3

Pure python3 implementation for working with iDevices (iPhone, etc...).
https://discord.gg/52mZGC3JXJ
GNU General Public License v3.0
1.43k stars 198 forks source link

FEATURE REQUEST: RSD tunnel on Linux (iOS >= 17.0, < 17.4) #566

Open corrrso opened 1 year ago

corrrso commented 1 year ago

Test environment OS: Ubuntu 20.04.1 LTS Target: tvOS 17.0

I have connected my device via usbmux:

[
    {
        "BuildVersion": "21J354",
        "ConnectionType": "USB",
        "DeviceClass": "AppleTV",
        "DeviceName": "ATV 9904167065",
        "Identifier": "blablabla",
        "ProductType": "AppleTV5,3",
        "ProductVersion": "17.0"
    }
]

And the device is reachable in my network (E.G. if I ping it, I see it).

If I try to run sudo python3 -m pymobiledevice3 remote start-quic-tunnel I get __main__[2707] ERROR Device is not connected.

I'm a bit stuck over here. I tried to run python3 -m pymobiledevice3 bonjour browse to check what I'm getting returned, the output is

Exception in thread zeroconf-ServiceBrowser-_apple-mobdev2._tcp-2724:
Traceback (most recent call last):
  File "/usr/lib/python3.8/threading.py", line 932, in _bootstrap_inner
    self.run()
  File "src/zeroconf/_services/browser.py", line 583, in zeroconf._services.browser.ServiceBrowser.run
  File "src/zeroconf/_services/browser.py", line 452, in zeroconf._services.browser._ServiceBrowserBase._fire_service_state_changed_event
  File "src/zeroconf/_services/browser.py", line 462, in zeroconf._services.browser._ServiceBrowserBase._fire_service_state_changed_event
  File "/usr/local/lib/python3.8/dist-packages/zeroconf/_services/__init__.py", line 56, in fire
    h(**kwargs)
  File "src/zeroconf/_services/browser.py", line 203, in zeroconf._services.browser._service_state_changed_from_listener.on_change
  File "/usr/local/lib/python3.8/dist-packages/pymobiledevice3/bonjour.py", line 51, in add_service
    ipv4 = [socket.inet_ntop(socket.AF_INET, address) for address in info.addresses_by_version(IPVersion.V4Only)]
AttributeError: 'zeroconf._services.info.ServiceInfo' object has no attribute 'addresses_by_version'
[]

I have the feeling I'm missing something very basic over here, but still I'm stuck. How I can then make start-quic-tunnel work, if I can, on Linux? Many thanks.

doronz88 commented 1 year ago

Currently, Linux is missing driver support for the changes Apple made to the USB ethernet implementation for iOS 17. We have been cooperating with other cool kids on the community's Discord server to be able to work with Linux also.

I hope these changes can be made public soon and part of an official release for the mainline kernel - Which I will definetly tweet about when this happens.

Till then, all I can offer is to wait patiently 🙏

corrrso commented 1 year ago

Gotcha, I'll join the community then!

Thanks for the info. Please feel free to either close the issue or keep it open until this is done :)

haryshi commented 11 months ago

Currently, Linux is missing driver support for the changes Apple made to the USB ethernet implementation for iOS 17. We have been cooperating with other cool kids on the community's Discord server to be able to work with Linux also.

I hope these changes can be made public soon and part of an official release for the mainline kernel - Which I will definetly tweet about when this happens.

Till then, all I can offer is to wait patiently 🙏

What's process of ios 17 linux support ? any update? Thanks a lot!

truonggiang0710 commented 10 months ago

Is it supported on Linux @doronz88 ? Please drop me any updates!

doronz88 commented 10 months ago

Haven't seen any commit regarding it on linux kernel.

doronz88 commented 10 months ago

Since some were asking for a clear guide, I'll summarise the steps required to make the tunnel work on linux:

That's it! everything should work

daigaigai520 commented 10 months ago

How can this be used in an Ubuntu Docker container? such like https://hub.docker.com/_/ubuntu

Spidy123222 commented 9 months ago

Since some were asking for a clear guide, I'll summarise the steps required to make the tunnel work on linux:

  • Build your own kernel with the following patch:

idevice_debug_ncm.patch

That's it! everything should work

Would this be for libimobiledevice than pymobiledevice3?

eyJhb commented 9 months ago

I've tried applying the patch to my computer (kernel, as well as usbmuxd), and didn't have any issues doing that. However, I've been trying to use pymobiledevice3 INSIDE a Docker container (haven't tried outside the container), which I assume should work just fine. Ie. Docker should reuse my kernel, and therefore the kernel patch should be ok (AFAIK please do correct me!) and I'm forwarding the usbmuxd (patched) socket into the docker container.

I can see the device using usbmux list, but when I try to do remote start-tunnel, it just says device not connected. However, I'm not sure what that error ACTUALLY means. Does it mean it couldn't find a device to begin starting the tunnel, or did it fail creating the tunnel?

Can somebody give me a sanity check, because I'm not exactly sure what I'm doing wrong here.

Starting docker container

docker run --rm -it -v /var/run/usbmuxd:/var/run/usbmuxd -p 5555:5555 --entrypoint=bash python

installing pymobiledevice3

cd /tmp
git clone https://github.com/doronz88/pymobiledevice3.git
cd pymobiledevice3
python3 -m pip install -U -e .

running commands

root@7cf58f3413c6:/# pymobiledevice3 usbmux list
[
    {
        "BuildVersion": "21B101",
        "ConnectionType": "USB",
        "DeviceClass": "iPhone",
        "DeviceName": "iPhone",
        "Identifier": "XXXXXXXXXXXXXXXXXXXXXXXXX",
        "ProductType": "iPhone14,6",
        "ProductVersion": "17.1.2"
    }
]

root@7cf58f3413c6:/# pymobiledevice3 remote start-tunnel
2024-01-18 11:43:36 7cf58f3413c6 pymobiledevice3.__main__[164] ERROR Device is not connected
haryshi commented 8 months ago

I've tried applying the patch to my computer (kernel, as well as usbmuxd), and didn't have any issues doing that. However, I've been trying to use pymobiledevice3 INSIDE a Docker container (haven't tried outside the container), which I assume should work just fine. Ie. Docker should reuse my kernel, and therefore the kernel patch should be ok (AFAIK please do correct me!) and I'm forwarding the usbmuxd (patched) socket into the docker container.

I can see the device using usbmux list, but when I try to do remote start-tunnel, it just says device not connected. However, I'm not sure what that error ACTUALLY means. Does it mean it couldn't find a device to begin starting the tunnel, or did it fail creating the tunnel?

Can somebody give me a sanity check, because I'm not exactly sure what I'm doing wrong here.

Starting docker container

docker run --rm -it -v /var/run/usbmuxd:/var/run/usbmuxd -p 5555:5555 --entrypoint=bash python

installing pymobiledevice3

cd /tmp
git clone https://github.com/doronz88/pymobiledevice3.git
cd pymobiledevice3
python3 -m pip install -U -e .

running commands

root@7cf58f3413c6:/# pymobiledevice3 usbmux list
[
    {
        "BuildVersion": "21B101",
        "ConnectionType": "USB",
        "DeviceClass": "iPhone",
        "DeviceName": "iPhone",
        "Identifier": "XXXXXXXXXXXXXXXXXXXXXXXXX",
        "ProductType": "iPhone14,6",
        "ProductVersion": "17.1.2"
    }
]

root@7cf58f3413c6:/# pymobiledevice3 remote start-tunnel
2024-01-18 11:43:36 7cf58f3413c6 pymobiledevice3.__main__[164] ERROR Device is not connected

I tried outside container and met the same issue, have you resolved? @eyJhb

jordus100 commented 8 months ago

As someone who uses this wonderful repository (pymobiledevice3) for handling iOS 17 devices on Linux (Ubuntu) extensively I will share some of my knowledge.

[ethernet]

[match] driver=idevice_debug_ncm;

[ipv4] method=disabled

[ipv6] addr-gen-mode=eui64 ip6-privacy=0 method=link-local

[proxy]


This is a NetworkManager keyfile, it usually needs to be put in `/etc/NetworkManager/system-connections` with a name [something].nmconnection with root ownership and permissions 600. In any doubts, consult NetworkManager documentation.
You need to create as many such files as you want to connect iOS>17 devices. Just change the name and id.
After you reboot, the iPhone connection should be visible as active in NetworkManager connection list - `nmcli` command.

After you have all that set up, pymobiledevice3 should have no problem connecting to iOS>17 devices. 
@haryshi @eyJhb 
doronz88 commented 8 months ago

Wow @jordus100 thanks for the very detailed guide! Could you submit a PR to add this steps to the README for linux?

haryshi commented 8 months ago

@jordus100 thanks a lot for the information, I put the config file ethusb-ios.ncconnection with your quoted contents (just delete the ";" mark in [match] section) in /etc/NetworkManager/system-connections with permissions 600, and sudo reboot ubuntu, but after running command nmcli, the iphone device still displayed as is not connected:

enx9a0daf5f4670: disconnected "Apple iPhone 5/5C/5S/6/SE/7/8/X" 1 connection available ethernet (cdc_ncm), 9A:0D:AF:5F:46:70, hw, mtu 1500

my ubuntu version is 24.04, here is my steps:

  1. with kernel version 6.6.3 source file applying the idevice_debug_ncm patch( with command: sudo patch -p1 < idevice_debug_ncm.patch)
  2. build and install the kernel
  3. update GRUB file, sudo reboot and choose the new kernel
  4. build and install usbmuxd from sources
  5. put the usb-ios.ncconnection in /etc/NetworkManager/system-connections
  6. sudo reboot, launch usbmuxd with "sudo usbmuxd -s -f"
  7. run nmcli, the ios 17 device is listed as not connected and pymobiledevice3 cannot find the device.

you mentioned "to enable the idevice_debug_ncm driver in build config", and how to do that? I'm not sure how to confirm the driver is working well, expecting your reply, thanks a lot!

jordus100 commented 8 months ago

@haryshi if the driver is working properly, you should see two network devices named enx* after connecting the iPhone. One of them should be connected with the standard cdc_ncm driver (you already have that in your nmcli output) and the other via the custom idevice_debug_ncm. Also, maybe try the command nmcli dev as it gives more info about network devices. Make sure that your iPhone has no passcode set, otherwise the debug interface won't activate (this is perhaps what you have experienced).

jordus100 commented 8 months ago

@haryshi I have kind of run into a perhaps similar issue to that of yours, please check the output of modinfo idevice_debug_ncm. If it returns an error, that means the kernel doesn't have the custom driver.

Spidy123222 commented 8 months ago

idevice_debug_ncm.patch

Couldn't this patch file be made into a kernel module?

jordus100 commented 8 months ago

idevice_debug_ncm.patch

Couldn't this patch file be made into a kernel module?

It could be but as far as I'm aware no one is working actively on it right now.

update: I've started tinkering with it

jordus100 commented 8 months ago

Wow @jordus100 thanks for the very detailed guide! Could you submit a PR to add this steps to the README for linux?

Sorry for the late reply, I'm really busy this week but I'll be happy to do that when I find time. Amongst other things, I'm resolving a couple of iOS 17 Linux related issues so maybe I'll post an update if I find out something important.

haryshi commented 8 months ago

@jordus100 I succeed to connect to ios 17 device with your guide finally, thanks again, the key point is to enable the driver before build the kernel:

after reboot of correct setting of /etc/NetworkManager/system-connections, the 'nmcli' command should display iPhone 17 device sth. like this: enx42144ccaba4c: connected to ethusb-ios "Apple iPhone 5/5C/5S/6/SE/7/8/X" ethernet (idevice_debug_ncm), 42:14:4C:CA:BA:4B, hw, mtu 1500 inet6 fe80::4014:4cff:feca:bb4c/64 route6 fe80::/64 metric 1024

@jordus100 I have another question, have you tried pymobiledevice3 in a docker? how to make the device workable in a docker container? It seems to need additional settings.

jordus100 commented 8 months ago

@haryshi I'm glad you found success! Thanks for writing down the part about the kernel config, I also set it before building but was a bit confused and I didn't know what exactly it was that made it work and I also forgot what I edited. Regarding pymobiledevice3 in a Docker container, no, I haven't tried that. I'm pretty sure that if you connect the iphone debug interface (enx42144ccaba4c in your case) to the Docker container's network interface with a virtual bridge, pymobiledevice3 would see it and connect. That being said, I'm not sure if it would all work if the host OS didn't have the idevice_debug_ncm driver and only the Docker container did. An interesting thing to test for sure.

MPBogdan commented 7 months ago

Hello,

I followed @jordus100 instruction and now I got the following entry in nmcli :

enx76b58788813a: connected to ethusb-ios
        "Apple iPhone 5/5C/5S/6/SE/7/8/X/XR"
        ethernet (idevice_debug_ncm), 76:B5:87:88:81:3A, hw, mtu 1500
        inet6 fe80::74b5:87ff:fe88:813a/64
        route6 fe80::/64 metric 1024

enxf64711ccb19a: disconnected
        "Apple iPhone 5/5C/5S/6/SE/7/8/X/XR"
        2 connections available
        ethernet (idevice_debug_ncm), F6:47:11:CC:B1:9A, hw, mtu 1500

but I see that both of them are using idevice_debug_ncm driver.

My issue is the fact that when connected to the first one the tunnel is still not working:

sudo -E python3 -m pymobiledevice3 remote tunneld
INFO:     Started server process [4232]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:5555 (Press CTRL+C to quit)
sudo -E python3 -m pymobiledevice3 remote rsd-info --tunnel ''
2024-02-23 10:41:43 debian __main__[4159] ERROR Device is not connected

If I'm connecting to second connection (enxf64711ccb19a) I get the following error:

sudo -E python3 -m pymobiledevice3 remote tunneld
INFO:     Started server process [4406]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:5555 (Press CTRL+C to quit)
*** stack smashing detected ***: terminated

Any idea what I did wrong?

daigaigai520 commented 7 months ago

@haryshi I'm glad you found success! Thanks for writing down the part about the kernel config, I also set it before building but was a bit confused and I didn't know what exactly it was that made it work and I also forgot what I edited. Regarding pymobiledevice3 in a Docker container, no, I haven't tried that. I'm pretty sure that if you connect the iphone debug interface (enx42144ccaba4c in your case) to the Docker container's network interface with a virtual bridge, pymobiledevice3 would see it and connect. That being said, I'm not sure if it would all work if the host OS didn't have the idevice_debug_ncm driver and only the Docker container did. An interesting thing to test for sure.

@jordus100 After I use --privileged and --network=host, I execute: pymobiledevice3 remote start-tunnel inside the container can connect suc.

but , our further goal is to mount multiple ios devices and map them to different docker containers through --device. It cannot use the --network=host but --network=bridge mode. Is there any command to map it into?


<Thank you very much!>

 \
  \
  /  \~~~/  \
 (    ..     )----,
  \__     __/      \
    )|  /)         |\
     | /\  /___\   / ^
      "-|__|   |__|
jordus100 commented 7 months ago

@jordus100 After I use --privileged and --network=host, I execute: pymobiledevice3 remote start-tunnel inside the container can connect suc.

but , our further goal is to mount multiple ios devices and map them to different docker containers through --device. It cannot use the --network=host but --network=bridge mode. Is there any command to map it into?

That's great news about the Docker container working, thanks for sharing! As for mapping individual devices, I haven't looked into it at all.

hsorbo commented 7 months ago

Haven't seen any commit regarding it on linux kernel.

https://marc.info/?l=linux-usb&m=170138175510294&w=4

nanoscopic commented 5 months ago

FYI authors of go-ios have written a Go program that will create interfaces directly from USB devices without a kernel module.

See https://github.com/danielpaulus/go-ios/tree/89f480768e8c3311da72c3ef50a2d19547bf2761/ncm Also see the Makefile at the root of the project. It builds the tool. Just run the tool as root and it does it's thing.

lnguyen234 commented 5 months ago

@nanoscopic I tried go-ncm on linux docker but could not create the network interface. Not sure what I was missing

doronz88 commented 5 months ago

I'm not familiar enough with the project or a Linux user myself. If any of you manages to get this to work well, feel free to submit a PR 😃 This can be either implemented proabably in pure Python (preferred way), or we'll bundle it as a resource for Linux installations. Prefereably this should be a shared library and wrap it using ctypes as we do with wintun

nanoscopic commented 5 months ago

@nanoscopic I tried go-ncm on linux docker but could not create the network interface. Not sure what I was missing

Unless you are giving the container full system access, I'm pretty sure it won't work from a container. It needs to be able to create a utun and have USB access to the device(s)

You don't need to run it as root. On Linux you can just give it permissions to make make/manage utuns and that should be sufficient.

felixruan commented 1 month ago

@nanoscopic I tried go-ncm on linux docker but could not create the network interface. Not sure what I was missing

@lnguyen234 I use the debian image(FROM debian:bullseye-slim), it works fine. You just need to download the usbmuxd from git and build the binary. The container needs to set privileged: true and network_mode: "host". Finally, remember to install ifconfig.