apple bloqueó altserver dos veces en una semana. propuse el arreglo.

continuación de altstore no podía iniciar sesión. apple devolvía una página html. en octubre de 2026 altserver en macos 27 volvió a dejar de iniciar sesión, primero con -80045 y, dos días después, con una página html que altserver intentaba leer como plist. así rastreé los dos fallos, qué medí en el borde de apple sin credenciales y el arreglo que propuse. la versión larga, con diagramas, está en el informe de campo (en inglés).
resumen
- 12 de oct: todos los inicios de sesión fallaban en la primera petición de grandslam con
-80045. altserver en macos 27 generaba datos de anisette de android mientras mandaba la información de cliente de un mac. apple empezó a rechazar esa diferencia. - 14 de oct, hacia las 20:50 utc: apple empezó a responder con una página html
503a cualquier información de cliente de android. altserver lo mostraba como "los datos no están en el formato correcto" (NSCocoaErrorDomain 3840). eso también acabó con el arreglo del pixel 7, que había funcionado unas horas. - lo que pasa: datos de anisette de windows desde un servidor de anisette v3, con la información de cliente y el user agent que ese servidor informa. el arreglo inicia sesión así.
- probado en macos 27.2 con un apple id gratuito con 2fa: inicio de sesión, instalación de altstore en un ipad pro y en un iphone 15 pro max, y un refresco de altstore. no probado: refrescar otras apps instaladas por sideload, y nadie lo ha confirmado todavía; un usuario reportó después que inició sesión y reinstaló una app con la build (#1828).
- no es universal: algunas cuentas siguen recibiendo
-80045con la identidad de windows. y el 15 de oct jkcoxson publicó un servidor de anisette con identidad de mac que, según dice, funciona sin parches. no lo he probado.
la regla que explica los dos bloqueos
los datos de anisette y la cabecera X-MMe-Client-Info tienen que describir el mismo dispositivo. altserver pedía anisette local (coreadi de android) y luego se declaraba mac. esa diferencia es el primer bloqueo. el segundo es el borde de apple rechazando android por completo.
sondear el borde sin credenciales
para separar "el servidor rechaza esta identidad" de "mi inicio de sesión está mal", mandé peticiones sin credenciales a GsService2 con un cuerpo plist vacío y cambiando solo la información de cliente. muestran cómo enruta el borde una petición, no si un inicio de sesión funcionaría.
| información de cliente | respuesta | lectura |
|---|---|---|
<Pixel 7> <Android;14;…> | 503 html, 6 de 6 | bloqueado en el borde |
| variantes de pixel 5 y pixel 8 | 503 html, 6 de 6 | igual |
<MacBookPro…> <macOS;27.2;…> akd | 404 / 429 | llega al servicio (mi ip ya estaba limitada) |
<PC> <Windows;6.2(0,0);9200> itunes | 404 | llega al servicio |
la única receta confirmada después del 503 fue la que traían iloader 2.3.8 e isideload 0.4.6: anisette de windows desde un servidor de anisette v3.
un crash que no era el error
llevar el arreglo a altserver implicó compilarlo con xcode 27. la primera build que llegó a apple se cayó sola: la llamada que fallaba era alt_ccsrp_gp_rfc5054_2048, un símbolo que altsign enlaza por el espacio de nombres plano, y no estaba definido en ningún framework. el producto AltSign-Dynamic de swiftpm salía vacío con xcode 27.
$ nm -arch arm64 AltSign.framework/Versions/A/AltSign | grep rfc5054
U _alt_ccsrp_gp_rfc5054_2048
reconstruir solo ese dylib desde libcorecrypto_static.a con -force_load eliminó el crash. es un problema de compilación, así que a propósito no forma parte del pull request.
el arreglo
seis commits, tres en altstore y tres en altsign. se apoyan en el arreglo de 2fa de altsign#59 y reutilizan el cliente de anisette remota de altstore#1806.
| antes | después | |
|---|---|---|
| anisette | coreadi de android, local (anisettekit) | adi de windows, servidor de anisette v3 |
| user-agent | cadena fija de authkit con xcode 26 | el user_agent del servidor |
| errores http | error de lectura de plist 3840 | código http legible |
tu contraseña y tu código 2fa van directos a apple. el servidor de anisette solo ve la identidad de un dispositivo.
evidencia
instalar altstore desde la build descargada funcionó en un ipad pro y en un iphone 15 pro max, y refrescar altstore desde la app también: 26 peticiones durante una instalación y 6 durante un refresco, todas http 200, de vuelta a 7 días restantes, con un app id usado. el código 2fa vino de un dispositivo de confianza, porque el sms falla ahora mismo por parte de apple.

qué prueba esto y qué no
- prueba que en mi cuenta y mi red el inicio de sesión, la instalación y un refresco de altstore funcionan con anisette de windows, y que el borde de apple rechaza la identidad de android.
- no prueba que funcione para todos: algunas cuentas siguen recibiendo
-80045con la identidad de windows, al parecer según la cuenta o la red. no sé por qué. - depende de un servidor de anisette de la comunidad, y apple puede cambiar las reglas otra vez: el primer arreglo duró menos de un día.
- no es el único arreglo: un servidor con identidad de mac publicado el 15 de oct podría hacer innecesario el parche. sin probar de mi lado.
errores que cometí en el camino
- leer el primer fallo como si fuera todo el error. el arreglo de la cabecera del pixel 7 quitó el
-80045durante unas horas y hizo parecer que estaba resuelto. el 503 era un segundo bloqueo, aparte. - culpar a la compilación. el segfault parecía mi parche. era un framework vacío de xcode 27.
lo que me llevo
- sondear primero sin credenciales. una petición con cuerpo vacío y una sola cabecera cambiada te dice cómo te enruta el borde y no puede bloquear tu cuenta.
- la identidad debe coincidir de punta a punta. anisette, información de cliente y user agent tienen que venir del mismo dispositivo.
- decir lo que no probaste. el arreglo no está fusionado y no es universal, y este informe y el release lo dicen.
enlaces
- el informe de campo, con la cronología y diagramas (en inglés)
- altstore#1834 y altsign#61
- el issue de seguimiento, #1828
- build no oficial, temporal
- el informe de septiembre sobre el inicio de sesión