Local bridge: socat 127.0.0.1:27015 to the desktop's usbmuxd, as a systemd user unit #8

Closed
opened 2026-10-28 09:58:09 +01:00 by The_Void · 3 comments
Owner

The phone plugs into the same desktop that runs iTunes (operator, 2026-10-28; the native-install issue). #7 showed that iTunes in the prefix connects to TCP 127.0.0.1:27015 and speaks the usbmuxd protocol unchanged, and that Linux usbmuxd serves it behind a plain forward (KNOWLEDGE.md → Device service). Wine shares the host's loopback, so on the desktop the whole bridge is:

socat TCP-LISTEN:27015,bind=127.0.0.1,reuseaddr,fork UNIX-CONNECT:/var/run/usbmuxd

To build:

  • a systemd user unit that runs this, installed and enabled by the install script;
  • no SSH. That was only for the headless box, which is no longer the target.

Check whether Fedora's usbmuxd runs only while a device is plugged in (udev-started) and what permissions /var/run/usbmuxd has, so the unit works as the user. Reconnecting per client (fork) should cover usbmuxd starting after iTunes.

Done when, in the fedora:44 test container, the unit forwards iTunes to a usbmuxd stand-in on the Unix socket (wine/fakemux.py, given a Unix-socket mode), and iTunes lists the fake device. The real phone is the verification issue.

The phone plugs into the same desktop that runs iTunes (operator, 2026-10-28; the native-install issue). #7 showed that iTunes in the prefix connects to TCP 127.0.0.1:27015 and speaks the usbmuxd protocol unchanged, and that Linux usbmuxd serves it behind a plain forward (KNOWLEDGE.md → *Device service*). Wine shares the host's loopback, so on the desktop the whole bridge is: socat TCP-LISTEN:27015,bind=127.0.0.1,reuseaddr,fork UNIX-CONNECT:/var/run/usbmuxd To build: - a **systemd user unit** that runs this, installed and enabled by the install script; - **no SSH**. That was only for the headless box, which is no longer the target. Check whether Fedora's usbmuxd runs only while a device is plugged in (udev-started) and what permissions `/var/run/usbmuxd` has, so the unit works as the user. Reconnecting per client (`fork`) should cover usbmuxd starting after iTunes. Done when, in the `fedora:44` test container, the unit forwards iTunes to a usbmuxd stand-in on the Unix socket (`wine/fakemux.py`, given a Unix-socket mode), and iTunes lists the fake device. The real phone is the verification issue.
The_Void added this to the Blocked milestone 2026-10-28 09:58:16 +01:00
Author
Owner

What #7 settled for this bridge (KNOWLEDGE.md, Device service):

  • Box side: in the prefix, iTunes connects to TCP 127.0.0.1:27015 and speaks the usbmuxd protocol unchanged. Debian's usbmuxd 1.1.1 behind socat TCP-LISTEN:27015,bind=127.0.0.1,fork UNIX-CONNECT:/var/run/usbmuxd served it as a listening client. So no translator is needed; the first attempt is plain forwarding.
  • The AMDS service has to stay off (Start=4, as in resources/prefixes/mux), or it takes port 27015 itself. Its MobileDevice files are still needed. They install only from the patched MSI, because the service-permissions custom action fails under Wine.
  • Suggested path: iTunes → 127.0.0.1:27015 in the container → ssh -L (OpenSSH can forward to a Unix socket) → the desktop's /var/run/usbmuxd. Fedora starts usbmuxd only while an iPhone is plugged in. corellium's usbfluxd does the same TCP exposure, which is prior art for the network half.
  • Testable without the phone: wine/fakemux.py, run on the far end of the forward, already gets Listen, ListDevices and Connect from iTunes.
  • Pairing records: the files are named the same on both systems (SystemConfiguration.plist, <UDID>.plist). Whether iTunes asks the mux (ReadPairRecord) or reads C:\ProgramData\Apple\Lockdown directly is still unknown. The first real lockdown session shows it in the usbmuxd log, which decides whether records need syncing.
What #7 settled for this bridge (KNOWLEDGE.md, *Device service*): - **Box side:** in the prefix, iTunes connects to TCP 127.0.0.1:27015 and speaks the usbmuxd protocol unchanged. Debian's usbmuxd 1.1.1 behind `socat TCP-LISTEN:27015,bind=127.0.0.1,fork UNIX-CONNECT:/var/run/usbmuxd` served it as a listening client. So no translator is needed; the first attempt is plain forwarding. - **The AMDS service has to stay off** (`Start`=4, as in `resources/prefixes/mux`), or it takes port 27015 itself. Its MobileDevice files are still needed. They install only from the patched MSI, because the service-permissions custom action fails under Wine. - **Suggested path:** iTunes → 127.0.0.1:27015 in the container → `ssh -L` (OpenSSH can forward to a Unix socket) → the desktop's `/var/run/usbmuxd`. Fedora starts usbmuxd only while an iPhone is plugged in. corellium's usbfluxd does the same TCP exposure, which is prior art for the network half. - **Testable without the phone:** `wine/fakemux.py`, run on the far end of the forward, already gets `Listen`, `ListDevices` and `Connect` from iTunes. - **Pairing records:** the files are named the same on both systems (`SystemConfiguration.plist`, `<UDID>.plist`). Whether iTunes asks the mux (`ReadPairRecord`) or reads `C:\ProgramData\Apple\Lockdown` directly is still unknown. The first real lockdown session shows it in the usbmuxd log, which decides whether records need syncing.
The_Void modified the milestone from Blocked to Ready to work 2026-10-28 12:12:27 +01:00
The_Void changed title from Bridge iTunes to the desktop's usbmuxd over the network to Local bridge: socat 127.0.0.1:27015 to the desktop's usbmuxd, as a systemd user unit 2026-10-28 13:25:29 +01:00
The_Void modified the milestone from Ready to work to Blocked 2026-10-28 13:25:31 +01:00
The_Void modified the milestone from Blocked to Ready to work 2026-10-28 13:43:14 +01:00
Author
Owner

Built in 365f612. install.sh writes ~/.config/systemd/user/itunes-wine-usbmuxd.service (socat TCP-LISTEN:27015,bind=127.0.0.1,reuseaddr,fork UNIX-CONNECT:/var/run/usbmuxd, Restart=on-failure, WantedBy=default.target) and runs enable --now. That call is guarded, so a session with no user manager (the fedora:44 rig) gets a hint instead of an error.

The done-when changed: the container/fakemux check was not run. This desktop has no Docker, and the real iPhone was here, which is the stronger control (#9, KNOWLEDGE.md → Desktop run). The bridge was first run by hand, with -v capturing every message. The phone appeared in iTunes: Listen → Attached → Connect 32498, and all 84 mux replies were Number 0. Then the operator ran install.sh and the unit took over: is-active active, is-enabled enabled, socat on 127.0.0.1:27015.

Checked as asked: Fedora's usbmuxd is a static unit started by udev, and /var/run/usbmuxd is srw-rw-rw- root, so a user unit can reach it.

Found on the way: the AMDS MSI rolls back while the bridge holds 27015 (#11, fixed in the same commit).

Proposing the close: the decision is yours, because the done-when was swapped.

Built in 365f612. `install.sh` writes `~/.config/systemd/user/itunes-wine-usbmuxd.service` (`socat TCP-LISTEN:27015,bind=127.0.0.1,reuseaddr,fork UNIX-CONNECT:/var/run/usbmuxd`, `Restart=on-failure`, `WantedBy=default.target`) and runs `enable --now`. That call is guarded, so a session with no user manager (the `fedora:44` rig) gets a hint instead of an error. **The done-when changed:** the container/fakemux check was not run. This desktop has no Docker, and the real iPhone was here, which is the stronger control (#9, KNOWLEDGE.md → *Desktop run*). The bridge was first run by hand, with `-v` capturing every message. The phone appeared in iTunes: `Listen` → `Attached` → `Connect 32498`, and all 84 mux replies were `Number 0`. Then the operator ran `install.sh` and the unit took over: `is-active` active, `is-enabled` enabled, socat on 127.0.0.1:27015. Checked as asked: Fedora's usbmuxd is a static unit started by udev, and `/var/run/usbmuxd` is `srw-rw-rw-` root, so a user unit can reach it. Found on the way: the AMDS MSI rolls back while the bridge holds 27015 (#11, fixed in the same commit). Proposing the close: the decision is yours, because the done-when was swapped.
Author
Owner

Closed by the operator (2026-10-28): the real-iPhone run replaces the container/fakemux done-when. Evidence is in the comment above and KNOWLEDGE.md → Desktop run (365f612).

Closed by the operator (2026-10-28): the real-iPhone run replaces the container/fakemux done-when. Evidence is in the comment above and KNOWLEDGE.md → *Desktop run* (365f612).
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference
iTunes/iTunes.Wine#8
No description provided.