Nob ~/ip-rotator

01 · redes móviles

IP Rotator

Cambiar la IP de un celular Android desde el PC, por ADB

Empezó como un experimento con una pregunta concreta: ¿se puede cambiar la IP pública de un celular Android solo desde el PC, por ADB y sin root? La primera respuesta fue que no. Seis meses después resultó que sí, y que el problema siempre había sido el comando

##Verlo funcionar

##La pregunta

Mucha gente da por hecho que prender y apagar el modo avión siempre trae una IP nueva. El repo nació para comprobarlo con evidencia: medir la IP pública, cambiar el estado de la red por ADB, esperar a que vuelva, medir otra vez y guardar los logs de radio de cada intento (logcat -b radio), con un índice de corridas y exportación a JSON y CSV

##Por qué no funcionaba

Los modos A y B usaban settings put global airplane_mode_on. En los logs se veía el problema: el radio nunca se soltaba de verdad de la torre. El comando solo cambiaba un ajuste, y el operador mantenía la misma sesión de CGNAT y la misma IP. La conclusión de la v0.1.0, en diciembre de 2025, fue que ADB no podía hacerlo sin permisos de sistema

##El comando correcto

En junio de 2026, construyendo Goket (mi panel de red), Claude encontró cmd connectivity airplane-mode enable|disable. Ese comando pasa por ConnectivityService, el mismo camino que el botón del sistema, y sí apaga el radio. Funciona sin root desde Android 12; en Android 16 el aviso de AIRPLANE_MODE que se usaba antes ni siquiera se puede enviar desde ADB (da SecurityException)

##Detalles que importan

Con el comando no bastaba. El Wi-Fi del celular se apaga durante la prueba (svc wifi disable), porque si no el tethering sale por el internet de la casa y la IP medida no es la del operador. Bajo CGNAT la IP nueva no está garantizada a la primera, así que se repiten ciclos cortos (7 s apagado, 12 s de espera) hasta 5 veces. Y la IP se mide por la interfaz del tethering (curl --interface), así el PC no pierde su propio internet mientras tanto

~/ip-rotator · cómo funciona
PC (Python · menu.py)
 │ adb shell cmd connectivity airplane-mode enable
 ▼
Android 16 ─► ConnectivityService ─► radio apagado
 │ 7 s · airplane-mode disable
 ▼
el celular vuelve a pedir red al operador
 │ 12 s
 ▼
operador (CGNAT) ── ¿IP nueva?
 ├─ no ─► otro ciclo (máx. 5)
 └─ sí ─► curl --interface <tethering>
          190.130.xxx.204 → 190.130.xxx.83
Terminal con una corrida real del Modo C: la IP pasa de 190.130.xxx.204 a 190.130.xxx.83 en el primer intento
Corrida real del Modo C · 30 sep 2026 · IP rotada al primer intento, en 20 s

##Bitácora

  1. El experimentoModos A y B, menú interactivo, captura de logs de radio, índice de corridas, exportación a JSON y CSV, y un .exe para Windows que GitHub arma solo en cada release
  2. La conclusiónCon settings put global airplane_mode_on el radio nunca se apaga de verdad. El README de la v0.1.0 lo deja escrito: "ADB no puede"
  3. El descubrimientoConstruyendo Goket, Claude (la IA de Anthropic) encontró cmd connectivity airplane-mode: pasa por el sistema de conectividad y sí apaga el radio, sin root, en Android 16. El crédito es suyo
  4. De vuelta al repoModo C, Wi-Fi del celular apagado durante la prueba, ciclos cortos hasta que el CGNAT suelta una IP nueva y medición por la interfaz del tethering. Prueba real: IP rotada al primer intento, en 20 s. Sale la v0.2.0