Skip to content
overkazafPublic

About

Lightweight, rootless chroot launcher for Apple Music FairPlay DRM decrypt on Linux. No root needed. PTY output, port readiness, graceful restart.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

24 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Stars C Last Commit License

sidecar

A lightweight, rootless chroot launcher for running Apple Music FairPlay DRM decrypt binaries on Linux.

sidecar manages the lifecycle of an Android-based decrypt daemon inside a chroot environment, providing PTY-based output forwarding, port readiness detection, graceful restart, and user namespace isolation — all without requiring root privileges.

Architecture

                         ┌──────────────────────────────────────┐
                         │           sidecar (39 KB)         │
                         │                                      │
  SIGUSR1 ──────────────►│  ┌─ signal handler ────────────┐     │
  SIGTERM ──────────────►│  │  forward / grace / restart  │     │
                         │  └─────────────────────────────┘     │
                         │                                      │
                         │  ┌─ user namespace ────────────────┐ │
                         │  │  unshare(NEWUSER | NEWNS)       │ │
                         │  │  uid 1000 → 0 (inside)         │ │
                         │  │  bind-mount /dev, /proc, /sys   │ │
                         │  │                                 │ │
                         │  │  ┌─ chroot ./rootfs ──────────┐ │ │
                         │  │  │  /system/bin/main           │ │ │
                         │  │  │    ├─ TCP :47010 (decrypt)  │ │ │
                         │  │  │    └─ TCP :47020 (m3u8)     │ │ │
                         │  │  └─────────────────────────────┘ │ │
                         │  └──────────────────────────────────┘ │
                         │                                      │
                         │  ┌─ PTY ──────────────────────────┐  │
                         │  │  openpty() → line-buffered     │  │
                         │  │  child stdout → parent stdout  │  │
                         │  └────────────────────────────────┘  │
                         │                                      │
                         │  ┌─ port probe ───────────────────┐  │
                         │  │  --wait-ports 47010,47020      │  │
                         │  │  non-blocking TCP connect      │  │
                         │  │  200ms tick, interleaved w/PTY │  │
                         │  └────────────────────────────────┘  │
                         └──────────────────────────────────────┘

Acknowledgments

This project is inspired by and builds upon the pioneering work of the Apple Music decrypt community:

sidecar addresses several limitations encountered when deploying wrapper in production environments — particularly around rootless operation, observability, and process lifecycle management.

Three-Way Comparison

Metric wrapper wrapper-v2 sidecar v4
Cold startup 2338 ms ~5000-8000 ms (est.) 2163 ms
Decrypt throughput 15.0 MB/s ~15 MB/s 15.3 MB/s
Memory 53.8 MB ~150-200 MB (est.) 52.3 MB
Size 20 KB binary ~200-500 MB image 35 KB binary
Container required No Docker/podman No
Build deps none (prebuilt) Rust + NDK + CMake cc + libutil
Build time n/a ~15 min < 1 sec
Source closed Rust + C++ (open) C 935 lines (open)
Root required No No (container) No (user namespace)
PTY output No No Yes
Port readiness No Rust supervisor --wait-ports
Graceful restart No Supervisor restart SIGUSR1 (in-process)
HTTP API No Yes No (aria server provides)

wrapper-v2 data marked (est.) is based on Docker/Rust architecture overhead analysis, not direct measurement. wrapper and sidecar v4 data is from controlled benchmarks on Dell R730 (80 cores, 94 GB RAM).

Build

make
# or directly:
cc -O2 -Wall -Wextra -o sidecar sidecar.c -lutil

Requirements: Linux with unprivileged_userns_clone enabled (default on most distributions):

cat /proc/sys/kernel/unprivileged_userns_clone   # should be 1

Usage

Basic (code-from-file, headless)

./sidecar --rootfs ./rootfs --bin /system/bin/main \
  --wait-ports 47010,47020 --verbose \
  -- -M 47020 -D 47010 -F

Login mode (initial authentication)

./sidecar --rootfs ./rootfs --bin /system/bin/main \
  --wait-ports 47010,47020 --verbose \
  -- -M 47020 -D 47010 --login=user@host:pass

Multi-instance (parallel decryption)

for i in 0 1 2 3; do
  ./sidecar --rootfs ./rootfs --bin /system/bin/main \
    --wait-ports $((47010+i)),$((47020+i)) --verbose \
    -- -M $((47020+i)) -D $((47010+i)) -F &
done

Real-root mode (legacy, needs sudo)

sudo ./sidecar --no-userns --rootfs ./rootfs --bin /system/bin/main \
  --wait-ports 47010,47020 -- -M 47020 -D 47010 -F

Graceful restart (refresh auth without restarting sidecar)

kill -USR1 $(pgrep -f sidecar)

JSON events (for monitoring integration)

./sidecar --json-events --rootfs ./rootfs --bin /system/bin/main \
  -- -M 47020 -D 47010 -F

# stderr output:
# {"t":12345,"event":"chroot_ready"}
# {"t":12350,"event":"child_forked","pid":1234}
# {"t":12360,"event":"port_probe_first","port":47010}
# {"t":12361,"event":"port_probe_first","port":47020}
# {"t":12361,"event":"port_ready_all"}

CLI Reference

Flag Default Description
--rootfs PATH ./rootfs Path to the Android rootfs directory
--bin PATH /system/bin/main Executable to run inside chroot
--cwd-in-chroot PATH / Working directory after chroot
--userns (on) Use user namespace (no root needed)
--no-userns Use real chroot (needs root, legacy mode)
--wait-ports P[,P..] TCP ports to probe for readiness
--wait-timeout N 120 Seconds to wait for ports before giving up
--ready-fd N Write \1\n on this fd when ports are ready
--grace-secs N 10 Seconds between SIGTERM and SIGKILL
--pid-file PATH Write child PID to this file
--no-pty Don't allocate PTY (legacy buffered mode)
--no-dns-seed Don't copy DNS files into chroot
--json-events Emit structured JSON events on stderr
--verbose, -v Log setup steps to stderr
--help, -h Show help

Everything after -- is passed through to the child binary verbatim.

Wire Protocol

The child binary exposes two raw TCP ports:

  • Port 47010 — decrypt: pipelined stream-cipher channel for sample-by-sample FairPlay decryption
  • Port 47020 — m3u8: resolves an Apple Music adamId to an enhanced-HLS master playlist URL

Both are locally-unauthenticated, length-prefixed binary protocols. See aria's PROTOCOL.md for the full byte-level specification.

Integration

With aria service

# aria_sidecar.py manages N sidecar instances for parallel decryption
python3 aria_sidecar.py -F --instances 4

With systemd

[Unit]
Description=sidecar FairPlay decrypt

[Service]
Type=notify
NotifyAccess=all
ExecStart=/usr/local/bin/sidecar \
  --rootfs /opt/am/rootfs \
  --bin /system/bin/main \
  --wait-ports 47010,47020 \
  --ready-fd 3 \
  --json-events \
  -- -M 47020 -D 47010 -F
ExecReload=/bin/kill -USR1 $MAINPID
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

Performance Benchmarks

Tested on Dell PowerEdge R730 (80 cores, 94 GB RAM, Ubuntu 22.04).

Metric wrapper_new sidecar v4 Delta
Cold startup (median) 2338 ms 2163 ms sidecar 7.5% faster
Pipelined decrypt 3.18s (15.0 MB/s) 3.12s (15.3 MB/s) tie
Memory (main) 53.8 MB 52.3 MB sidecar 3% less
Binary size 20 KB 35 KB wrapper smaller (closed)
5-track sequential 5/5 5/5 tie
Source code closed binary 935 lines C sidecar open
PTY output no yes sidecar only
Port readiness no --wait-ports sidecar only
Graceful restart no SIGUSR1 sidecar only

Key optimizations in v4:

  • Namespace reduced to CLONE_NEWUSER | CLONE_NEWPID (removed CLONE_NEWNS)
  • Port probe tick 200ms to 50ms
  • Skip DNS seed and bind-mount in userns mode
  • Binary stripped (-s)

Full methodology: docs/BENCHMARK.md

License

MIT — see LICENSE.

About

Lightweight, rootless chroot launcher for Apple Music FairPlay DRM decrypt on Linux. No root needed. PTY output, port readiness, graceful restart.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages