Custom roms, certificados, problemas de todo tipo en mi I9100
hola gente de Linux Chad, no sé si decir que ésta será mi publicación más importante, pero desde luego es lo más jodido que he hecho en mucho tiempo.
como algunos sabrán, me compré un Samsung Galaxy S2 (GT-I9100) para instalar Replicant. la distribución no me terminó de convencer, sobre todo por temas de conectividad —aunque al final creo que fui algo injusto con ella—. aquí les cuento qué me pasó, cómo lo solucioné y todo el papeleo técnico por si a alguien le sirve.
1) ¿qué pasó después de instalar Replicant?
Al instalar Replicant se borraron varias partes del firmware original sin darme cuenta. eso provocó que no pudiera instalar un recovery “privativo” correctamente. la solución fue recuperar el firmware original.
en mi caso conseguí el firmware aquí:
https://samfw.com/firmware/GT-I9100
comandos que usé con heimdall
Primero, para flashear partes del firmware (siempre con el móvil en modo descarga —volumen abajo + home + encendido—):
heimdall flash --SBL1 Sbl.bin --BOOT boot.bin --KERNEL zImage --PARAM param.lfs
y para recuperar también la caché del sistema:
heimdall flash --CACHE cache.img
con eso quitas Replicant y vuelves al firmware original (más privativo), pero te permite instalar una custom ROM después.
2) custom ROMs y recovery
Descargué varias custom ROMs (lineageos, cyanogenmod, etc.). dentro de los ZIP suele haber un boot.img. yo al final no llegué a instalar lineageos estable; lo que mejor me funcionó fue CyanogenMod 13 (lo encontré en un vídeo de YouTube y por eso hice un torrent para que no se pierda).
el recovery que sí me funcionó fue:
recovery-the.gangster-IsoRec-TWRP-3.0.2-1-i9100
(enlace: recovery-the.gangster-IsoRec-TWRP-3.0.2-1-i9100.zip | by the.gangster for Galaxy S2 )
flashear recovery + boot
Con el teléfono en modo descarga:
heimdall flash --RECOVERY recovery.img --BOOT boot.img
el boot.img que usé venía de una build de lineageos (la versión concreta no importa tanto si está hecha para el i9100).
3) instalación desde el recovery (TWRP) — pasos rápidos
Dentro del recovery configuré idioma español y procedí así:
-
Wipe→Advanced Wipe→ seleccionar todo excepto las dos últimas opciones → deslizar y limpiar. -
Volver al menú principal →
Advanced→Install→ marcar las dos opciones necesarias para adb sideload → deslizar para instalar conadb.
sideload desde el ordenador:
adb -d sideload cm-13.0-20161218-NIGHTLY-i9100.zip
funciona aunque no tenga las animaciones típicas de lineageos y la barra se quede quieta; esperar y dejar que termine.
4) problema gordo: no puedes descargar NADA (certificados SSL)
cuando arrancas la ROM custom te puedes mover por el sistema, pero no puedes descargar nada: el navegador por defecto no permite descargas o fallan las conexiones HTTPS. el problema son los certificados SSL.
estuve 2 días peleando con Claude y ChatGPT, y al final elaboré varios scripts que sí me funcionaron para generar e instalar un CA sobre el sistema (mitmproxy para generar la CA y luego instalarla en /system/etc/security/cacerts/).
pasos generales que hice
-
generar certificado CA con
mitmproxy(o generarlo manual conopensslsi hace falta). -
convertir/copiar el PEM a un fichero con nombre
HASH.0(hash =openssl x509 -inform PEM -subject_hash_old -in cert.pem | head -1). -
subirlo al dispositivo y colocarlo en
/system/etc/security/cacerts/con permisos correctos y contexto SELinux si es posible. -
reiniciar el dispositivo para que Android lo reconozca como certificado de confianza.
5) scripts (los que me funcionaron)
abajo dejo dos scripts que usé: uno para generar el certificado con mitmproxy y preparar la instalación, y otro para forzar la instalación usando su -c y/o Magisk si /system no se puede montar como RW.
nota: los scripts contienen bastante verborrea y comprobaciones —si ves redundancias es porque me funcionó así y no me importa—. úsalos con cuidado y lee lo que hacen antes de ejecutarlos.
Script 1 — Generar CA e instalar (resumen)
#!/bin/bash
echo "🛠️ SETUP COMPLETO CON MITMPROXY"
echo "================================"
echo "mitmproxy es una alternativa gratuita y open source a Charles Proxy"
echo ""
# Función para instalar mitmproxy
install_mitmproxy() {
echo "1. Instalando mitmproxy..."
echo "========================="
if command -v mitmproxy >/dev/null 2>&1; then
echo "✅ mitmproxy ya está instalado"
mitmproxy --version
return 0
fi
echo "Instalando mitmproxy..."
# Detectar sistema operativo
if command -v apt >/dev/null 2>&1; then
echo "Sistema: Ubuntu/Debian"
sudo apt update && sudo apt install -y mitmproxy
elif command -v dnf >/dev/null 2>&1; then
echo "Sistema: Fedora"
sudo dnf install -y mitmproxy
elif command -v pacman >/dev/null 2>&1; then
echo "Sistema: Arch Linux"
sudo pacman -S mitmproxy
elif command -v pip3 >/dev/null 2>&1; then
echo "Sistema: Usando pip3"
pip3 install --user mitmproxy
echo "⚠️ Asegúrate de que ~/.local/bin esté en tu PATH"
else
echo "❌ No se pudo instalar automáticamente"
echo "Instala manualmente desde: https://mitmproxy.org/"
return 1
fi
# Verificar instalación
if command -v mitmproxy >/dev/null 2>&1; then
echo "✅ mitmproxy instalado correctamente"
return 0
else
echo "❌ Error en la instalación"
return 1
fi
}
# Función para generar certificado con mitmproxy
generate_certificate() {
echo ""
echo "2. Generando certificado con mitmproxy..."
echo "========================================"
# Crear directorio de configuración
MITM_DIR="$HOME/.mitmproxy"
mkdir -p "$MITM_DIR"
echo "Directorio de configuración: $MITM_DIR"
# Ejecutar mitmproxy brevemente para generar certificados
echo "Iniciando mitmproxy para generar certificados..."
echo "Se cerrará automáticamente en 5 segundos..."
# Usar timeout para cerrar automáticamente
timeout 5s mitmproxy --set confdir="$MITM_DIR" --quiet >/dev/null 2>&1 || true
# Verificar que se generó el certificado
CERT_FILE="$MITM_DIR/mitmproxy-ca-cert.pem"
if [ -f "$CERT_FILE" ]; then
echo "✅ Certificado generado: $CERT_FILE"
# Copiar al directorio actual con nombre estándar
cp "$CERT_FILE" "./charles-ssl-proxying-certificate.pem"
echo "✅ Copiado como: charles-ssl-proxying-certificate.pem"
# Mostrar información del certificado
echo ""
echo "Información del certificado:"
subject=$(openssl x509 -inform PEM -subject -noout -in "$CERT_FILE" | cut -d'=' -f2-)
hash=$(openssl x509 -inform PEM -subject_hash_old -in "$CERT_FILE" | head -1)
echo "Subject: $subject"
echo "Hash: $hash"
return 0
else
echo "❌ No se pudo generar el certificado"
echo "Intentando método manual..."
# Método alternativo: generar solo los certificados
echo "Generando certificados manualmente..."
cd "$MITM_DIR"
# Generar CA key y cert
openssl genrsa -out mitmproxy-ca.pem 2048 2>/dev/null
openssl req -new -x509 -key mitmproxy-ca.pem -out mitmproxy-ca-cert.pem -days 3650 -subj "/CN=mitmproxy" 2>/dev/null
cd - > /dev/null
if [ -f "$CERT_FILE" ]; then
echo "✅ Certificado generado manualmente: $CERT_FILE"
cp "$CERT_FILE" "./charles-ssl-proxying-certificate.pem"
return 0
else
return 1
fi
fi
}
# Función para instalar certificado en Android
install_to_android() {
echo ""
echo "3. Instalando certificado en Android..."
echo "======================================"
CERT_FILE="charles-ssl-proxying-certificate.pem"
if [ ! -f "$CERT_FILE" ]; then
echo "❌ No se encuentra el archivo de certificado"
return 1
fi
# Verificar ADB
if ! command -v adb >/dev/null 2>&1; then
echo "❌ ADB no está instalado"
echo "Instala con: sudo apt install adb"
return 1
fi
# Verificar dispositivo conectado
if ! adb devices | grep -q "device$"; then
echo "❌ No hay dispositivos Android conectados"
echo "Conecta tu dispositivo y habilita USB Debugging"
return 1
fi
echo "✅ Dispositivo Android detectado"
# Verificar root
if ! adb shell "su -c 'whoami'" 2>/dev/null | grep -q "root"; then
echo "❌ El dispositivo necesita acceso root"
return 1
fi
echo "✅ Acceso root verificado"
# Procesar certificado
hash=$(openssl x509 -inform PEM -subject_hash_old -in "$CERT_FILE" | head -1)
OUT_FILE="${hash}.0"
# Crear archivo con formato Android
cp "$CERT_FILE" "$OUT_FILE"
openssl x509 -inform PEM -text -in "$CERT_FILE" >> "$OUT_FILE"
echo "Archivo preparado: $OUT_FILE"
# Instalar
echo "Montando /system..."
adb shell "su -c 'mount -o remount,rw /system'" 2>/dev/null
echo "Subiendo certificado..."
adb shell "su -c 'mkdir -p /system/etc/security/cacerts/'"
adb push "$OUT_FILE" /system/etc/security/cacerts/
echo "Configurando permisos..."
adb shell "su -c 'chmod 644 /system/etc/security/cacerts/$OUT_FILE'"
adb shell "su -c 'chown root:root /system/etc/security/cacerts/$OUT_FILE'" 2>/dev/null
# Verificar
if adb shell "su -c 'test -f /system/etc/security/cacerts/$OUT_FILE'"; then
echo "✅ Certificado instalado correctamente"
# Remontar como solo lectura
adb shell "su -c 'mount -o ro,remount /system'" 2>/dev/null
# Limpiar
rm -f "$OUT_FILE"
return 0
else
echo "❌ Error en la instalación"
rm -f "$OUT_FILE"
return 1
fi
}
# Función para mostrar instrucciones de uso
show_usage_instructions() {
echo ""
echo "4. Instrucciones de uso..."
echo "========================="
echo ""
echo "🎯 CONFIGURAR PROXY EN ANDROID:"
echo "1. Ve a: Configuración → WiFi"
echo "2. Mantén presionada tu red WiFi → Modificar"
echo "3. Opciones avanzadas → Proxy manual"
echo "4. Servidor: $(ip route get 1.1.1.1 | grep -oP 'src \K\S+' | head -1 || echo 'TU_IP_LOCAL')"
echo "5. Puerto: 8080"
echo ""
echo "🚀 EJECUTAR MITMPROXY:"
echo "mitmproxy --listen-port 8080"
echo ""
echo "O en modo web (interfaz navegador):"
echo "mitmweb --listen-port 8080"
echo "# Luego ve a http://127.0.0.1:8081"
echo ""
echo "📱 VERIFICAR CERTIFICADO:"
echo "1. Reinicia tu dispositivo Android"
echo "2. Ve a: Configuración → Seguridad → Certificados de confianza"
echo "3. Pestaña 'Sistema' → Busca 'mitmproxy'"
echo ""
echo "🔍 INTERCEPTAR TRÁFICO:"
echo "1. Configura el proxy en Android"
echo "2. Ejecuta mitmproxy"
echo "3. Usa aplicaciones en Android"
echo "4. Ve el tráfico en tiempo real"
}
# EJECUCIÓN PRINCIPAL
echo "Este script configurará mitmproxy como alternativa a Charles Proxy"
echo ""
read -p "¿Continuar con la instalación? (s/N): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[SsYy]$ ]]; then
echo "Cancelado"
exit 0
fi
# Instalar mitmproxy
if ! install_mitmproxy; then
exit 1
fi
# Generar certificado
if ! generate_certificate; then
echo "❌ Error generando certificado"
exit 1
fi
# Verificar si hay dispositivo Android para instalar
echo ""
read -p "¿Instalar certificado en dispositivo Android ahora? (s/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[SsYy]$ ]]; then
if install_to_android; then
echo ""
echo "🎉 ¡INSTALACIÓN COMPLETADA!"
echo "=========================="
show_usage_instructions
else
echo "❌ Error instalando en Android"
echo "Pero el certificado está disponible en: charles-ssl-proxying-certificate.pem"
fi
else
echo "Certificado disponible en: charles-ssl-proxying-certificate.pem"
echo "Puedes instalarlo manualmente después"
fi
show_usage_instructions
echo ""
echo "📚 RECURSOS ADICIONALES:"
echo "========================"
echo "• Documentación mitmproxy: https://docs.mitmproxy.org/"
echo "• Tutorial Android: https://docs.mitmproxy.org/stable/howto-install-system-trusted-ca-android/"
echo "• Certificado para instalación manual: ./charles-ssl-proxying-certificate.pem"
(el script completo que tengo crea el CA con mitmproxy, genera charles-ssl-proxying-certificate.pem, calcula el hash antiguo con openssl y crea el HASH.0, sube y pone permisos, y da instrucciones de uso del proxy.)
Script 2 — Instalación forzada (resumen)
#!/bin/bash
echo "🔥 INSTALACIÓN FORZADA CON SUPERUSUARIO TOTAL"
echo "============================================="
echo "Este método usa su -c para TODOS los comandos"
echo ""
CERT_FILE="charles-ssl-proxying-certificate.pem"
HASH="c8750f0d"
OUT_FILE="${HASH}.0"
# Verificar que tenemos los archivos
if [ ! -f "$CERT_FILE" ]; then
echo "❌ No se encuentra $CERT_FILE"
exit 1
fi
# Preparar archivo si no existe
if [ ! -f "$OUT_FILE" ]; then
echo "Preparando $OUT_FILE..."
cp "$CERT_FILE" "$OUT_FILE"
openssl x509 -inform PEM -text -in "$CERT_FILE" >> "$OUT_FILE"
echo "✅ Archivo preparado localmente"
fi
echo "Archivo a instalar: $OUT_FILE ($(wc -c < "$OUT_FILE") bytes)"
echo ""
# Verificar dispositivo y root
if ! adb devices | grep -q "device$"; then
echo "❌ No hay dispositivo conectado"
exit 1
fi
if ! adb shell "su -c 'whoami'" 2>/dev/null | grep -q "root"; then
echo "❌ Sin acceso root"
exit 1
fi
echo "✅ Dispositivo y root verificados"
echo ""
# MÉTODO 1: Subir a /data/local/tmp y usar su -c para todo
echo "🚀 MÉTODO 1: Via /data/local/tmp con su -c total"
echo "==============================================="
echo "1. Subiendo a /data/local/tmp (área writable)..."
if adb push "$OUT_FILE" /data/local/tmp/; then
echo "✅ Subido a /data/local/tmp/"
echo "2. Ejecutando todos los comandos con su -c..."
# Deshabilitar temporalmente SELinux si es posible
adb shell "su -c 'setenforce 0'" 2>/dev/null || echo "⚠️ No se pudo cambiar SELinux (normal)"
# Montar /system como RW usando su -c
echo "3. Montando /system RW..."
adb shell "su -c 'mount -o remount,rw /system'"
# Verificar montaje
if adb shell "su -c 'touch /system/.test 2>/dev/null && rm /system/.test 2>/dev/null'"; then
echo "✅ /system montado como RW"
else
echo "⚠️ /system aún protegido, probando métodos alternativos..."
# Métodos alternativos de montaje
adb shell "su -c 'mount -o remount,rw \$(mount | grep system | cut -d\\ -f1) /system'" 2>/dev/null
adb shell "su -c 'mount -o remount,rw /dev/root /system'" 2>/dev/null
if ! adb shell "su -c 'touch /system/.test 2>/dev/null && rm /system/.test 2>/dev/null'"; then
echo "❌ No se puede hacer /system writable"
echo "Tu dispositivo tiene protección adicional (dm-verity, etc.)"
echo ""
echo "SOLUCIONES ALTERNATIVAS:"
echo "1. Usar Magisk systemless (recomendado)"
echo "2. Flashear kernel permisivo"
echo "3. Usar TWRP para instalar manualmente"
# Intentar instalación systemless
echo ""
echo "🎩 Probando instalación Magisk systemless..."
if adb shell "su -c 'test -d /data/adb/modules'"; then
echo "Creando módulo Magisk..."
MODULE_PATH="/data/adb/modules/custom_ca_certs"
# Crear estructura del módulo
adb shell "su -c 'rm -rf $MODULE_PATH'"
adb shell "su -c 'mkdir -p $MODULE_PATH/system/etc/security/cacerts/'"
# Copiar certificado
adb shell "su -c 'cp /data/local/tmp/$OUT_FILE $MODULE_PATH/system/etc/security/cacerts/$OUT_FILE'"
# Crear module.prop
adb shell "su -c 'cat > $MODULE_PATH/module.prop << EOF
id=custom_ca_certs
name=Custom CA Certificates
version=v1.0
versionCode=1
author=AndroidCertInstaller
description=Install custom CA certificates as system trusted
EOF'"
# Establecer permisos
adb shell "su -c 'chmod 644 $MODULE_PATH/system/etc/security/cacerts/$OUT_FILE'"
adb shell "su -c 'chmod 755 $MODULE_PATH'"
# Limpiar tmp
adb shell "su -c 'rm /data/local/tmp/$OUT_FILE'"
echo "✅ Módulo Magisk creado exitosamente"
echo "⚠️ REINICIA EL DISPOSITIVO para activar el módulo"
rm -f "$OUT_FILE"
exit 0
else
echo "❌ Magisk no disponible"
adb shell "su -c 'rm /data/local/tmp/$OUT_FILE'"
rm -f "$OUT_FILE"
exit 1
fi
fi
fi
# 4. Crear directorio si no existe
echo "4. Creando directorio de certificados..."
adb shell "su -c 'mkdir -p /system/etc/security/cacerts/'"
# 5. Copiar archivo usando su -c
echo "5. Copiando certificado al sistema..."
if adb shell "su -c 'cp /data/local/tmp/$OUT_FILE /system/etc/security/cacerts/$OUT_FILE'"; then
echo "✅ Certificado copiado exitosamente"
# 6. Establecer permisos correctos
echo "6. Estableciendo permisos..."
adb shell "su -c 'chmod 644 /system/etc/security/cacerts/$OUT_FILE'"
adb shell "su -c 'chown root:root /system/etc/security/cacerts/$OUT_FILE'" 2>/dev/null
# 7. Establecer contexto SELinux correcto
echo "7. Configurando contexto SELinux..."
adb shell "su -c 'chcon u:object_r:system_file:s0 /system/etc/security/cacerts/$OUT_FILE'" 2>/dev/null || echo "⚠️ SELinux context no cambiado (puede ser normal)"
# 8. Verificar instalación
echo "8. Verificando instalación..."
if adb shell "su -c 'test -f /system/etc/security/cacerts/$OUT_FILE'"; then
echo "✅ Certificado verificado en destino"
# Mostrar información
echo ""
echo "Información del certificado instalado:"
adb shell "su -c 'ls -la /system/etc/security/cacerts/$OUT_FILE'"
# Verificar contenido
if adb shell "su -c 'head -1 /system/etc/security/cacerts/$OUT_FILE'" | grep -q "BEGIN CERTIFICATE"; then
echo "✅ Formato correcto verificado"
else
echo "⚠️ Formato posiblemente incorrecto"
fi
else
echo "❌ Verificación falló"
adb shell "su -c 'rm /data/local/tmp/$OUT_FILE'"
rm -f "$OUT_FILE"
exit 1
fi
# 9. Limpiar archivos temporales
echo "9. Limpiando archivos temporales..."
adb shell "su -c 'rm /data/local/tmp/$OUT_FILE'"
# 10. Remontar /system como RO
echo "10. Remontando /system como solo lectura..."
adb shell "su -c 'mount -o ro,remount /system'" 2>/dev/null
# Restaurar SELinux si se cambió
adb shell "su -c 'setenforce 1'" 2>/dev/null || true
# Limpiar archivo local
rm -f "$OUT_FILE"
echo ""
echo "🎉 ¡INSTALACIÓN COMPLETADA EXITOSAMENTE!"
echo "========================================"
echo ""
echo "Certificado instalado en: /system/etc/security/cacerts/$OUT_FILE"
echo ""
echo "SIGUIENTE PASO OBLIGATORIO:"
echo "Reinicia tu dispositivo Android para que el certificado sea reconocido:"
echo ""
echo " adb reboot"
echo ""
echo "Después del reinicio:"
echo "1. Ve a: Configuración → Seguridad → Certificados de confianza → Sistema"
echo "2. Busca: 'mitmproxy'"
echo "3. Configura proxy WiFi a tu IP local puerto 8080"
echo "4. Ejecuta: mitmproxy --listen-port 8080"
echo ""
# Preguntar si reiniciar ahora
read -p "¿Reiniciar dispositivo ahora? (s/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[SsYy]$ ]]; then
echo "Reiniciando..."
adb reboot
fi
else
echo "❌ Error copiando archivo"
adb shell "su -c 'rm /data/local/tmp/$OUT_FILE'"
rm -f "$OUT_FILE"
exit 1
fi
else
echo "❌ No se pudo subir a /data/local/tmp/"
echo "Verifica que el dispositivo esté conectado correctamente"
rm -f "$OUT_FILE"
exit 1
fi
si quieres, pego aquí el script completo tal cual (son unos cuantos cientos de líneas), o te lo dejo listo para que lo copies y lo pegues en un .sh.
6) después de instalar la CA: notas prácticas
-
puede que el navegador por defecto siga sin funcionar y que Google o algunas webs den errores. muchas veces vuelven a la normalidad con el tiempo, pero no te fíes: no podrás descargar APKs desde el navegador.
-
solución práctica: descargar en otro dispositivo la APK de Firefox / Fennec / Aurora Store y pasarla al S2 para instalarla. luego desde Firefox puedes usar f-droid.org para instalar más apps.
-
sobre tiendas y repositorios: f-droid suele ser la mejor opción libre, pero algunos repos no funcionan bien en Android tan antiguo. Aurora Store y droid-ify son alternativas; droid-ify funciona más o menos si activas varios repos y te toca uno que funcione. aurora store da acceso a apps que muchas veces son privativas y pueden dejar de funcionar o perder compatibilidad.
7) torrent y enlaces
-
acabo de crear un torrent con CyanogenMod 13 —si me hacen el favor de bajarlo y compartirlo para que no se pierda estaría de ■■■■ madre.
cm-13.0-20161218-NIGHTLY-i9100.zip.torrent.txt (42,9 KB) (cambienle la extensión solamente)
-
vídeo donde encontré el enlace original (el segundo enlace en la descripción apuntaba al ZIP):
https://www.youtube.com/watch?v=KUXt6zCF0to -
firmware recuperado: https://samfw.com/firmware/GT-I9100
-
recovery (androidfilehost):
https://androidfilehost.com/?fid=24591000424954841
8) conclusiones y siguiente paso
ya con esto puedes tener una vida “normal” con el dispositivo, aunque el S2 es viejo y algunas cosas van a fallar. en un rato publicaré (o puedo publicar ahora si quieren) qué aplicaciones he probado y qué funciona y qué no, más detalles de UX y bugs concretos.
Dato final:
es posible que el navegador, ya sea firefox o fennec, no funcione la descarga en un principio, esto es normal, o lo creo que es normal, no se ni ■■■■ idea… tienen varias opciones, intentar descargar otra vez, cerrar la aplicación y volverla a abrir, o reiniciar el dispositivo, luego de ahi deberia funcionar. deberia…
