Actualizar ThunderHub: la guía robusta

La guía oficial para actualizar ThunderHub funciona, pero le faltan tres piezas que no deberían faltar: verificación de firmas GPG, manejo del package-lock.json, y modo producción para que el JWT secret no sea el default 123456789.
Actualizar ThunderHub: la guía robusta

Actualizar ThunderHub: la guía robusta

La guía habitual para actualizar ThunderHub funciona, pero le faltan tres piezas importantes que, en mi opinión, no deberían faltar en infraestructura Bitcoin/Lightning: verificación de firmas GPG, manejo del package-lock.json cuando da problemas, y activar el modo producción para que el JWT secret no sea el default 123456789 (sí, en serio, ese es el default si no haces nada).

Esta es esa misma actualización, pero hecha bien. Sirve para cualquier release de ThunderHub a partir de v0.16.x.


Setup único (solo la primera vez)

Antes de la primera actualización con verificación de firma, importa las claves GPG que firman los commits de ThunderHub. Son dos:

sudo su - thunderhub

# Clave 1: clave personal de apotdevin (mantenedor)
gpg --keyserver hkps://keys.openpgp.org --recv-keys 4403F1DFBE779457
# Si el primer keyserver falla, prueba con:
# gpg --keyserver hkps://keyserver.ubuntu.com --recv-keys 4403F1DFBE779457

# Clave 2: clave de GitHub web-flow (no está en keyservers públicos,
# se importa directamente desde GitHub)
curl https://github.com/web-flow.gpg | gpg --import

exit

¿Por qué dos? Porque ThunderHub mezcla commits firmados localmente por el mantenedor (clave 4403F1DFBE779457) con releases generadas vía GitHub Actions o merge desde la UI web (clave B5690EEEBB952194, parte del archivo web-flow.gpg). Las dos firmas son legítimas; solo cambia el origen. Sin las dos importadas, alguna verificación va a fallar.

Activar NODE_ENV=production (crítico, una sola vez)

Por defecto, el servicio arranca ThunderHub sin NODE_ENV=production. Esto tiene una consecuencia poco evidente: el código usa el JWT secret hardcodeado '123456789' en lugar de generar uno fuerte. Cualquiera con acceso a la red local podría forjar tokens de sesión válidos sin saber tu contraseña.

Lo arreglamos con un override de systemd:

sudo mkdir -p /etc/systemd/system/thunderhub.service.d/

sudo tee /etc/systemd/system/thunderhub.service.d/override.conf > /dev/null <<'EOF'
[Service]
Environment="NODE_ENV=production"
EOF

sudo systemctl daemon-reload

A partir de aquí, cada arranque de ThunderHub generará un JWT secret aleatorio fortísimo (128 hex). El único efecto visible: cuando reinicies el servicio se invalidan las sesiones activas y tendrás que volver a hacer login. Para uso personal es totalmente aceptable.


Procedimiento de actualización

Estos son los pasos cada vez que aparezca una versión nueva. Mira primero los releases en github.com/apotdevin/thunderhub/releases y lee el changelog antes de empezar.

1. Parar el servicio

Como usuario admin:

sudo systemctl stop thunderhub

2. Cambiar al usuario thunderhub

sudo su - thunderhub
cd thunderhub

3. Definir la versión objetivo

VERSION=0.16.1   # ← cámbialo a la versión que quieras instalar

4. Descartar cambios locales auto-generados

Tras cada npm install o npm run build, ThunderHub modifica algunos ficheros que luego entran en conflicto al hacer git pull. Los descartamos limpiamente:

git checkout -- package-lock.json schema.gql 2>/dev/null

5. Fetch del tag (sin merge todavía)

git fetch https://github.com/apotdevin/thunderhub.git tag v$VERSION

6. Verificar la firma GPG

Esto es la diferencia más importante con la guía oficial. No mergees a ciegas.

git verify-commit v$VERSION^{commit}

Lo que debe aparecer:

gpg: Good signature from "Anthony Potdevin <potdevin.anthony@gmail.com>"

O alternativamente:

gpg: Good signature from "GitHub <noreply@github.com>"

Cualquiera de las dos es válida. Si aparece “Can’t check signature: No public key” con una clave que no reconoces, o “BAD signature”, PARA y averigua antes de continuar. No es paranoia: es la única forma de detectar un compromiso del repositorio.

El warning “This key is not certified with a trusted signature” es cosmético y se puede ignorar — significa solo que no has marcado las claves como confiables localmente con tu propia clave GPG.

7. Mergear

git merge v$VERSION

8. Leer el changelog antes de instalar

less CHANGELOG.md

Especialmente importante en saltos de minor o major. Busca breaking changes, variables de entorno nuevas, requisitos nuevos de Node, cambios en formatos de configuración. Apunta cualquier variable nueva que veas en la sección del .env.

9. Limpiar el build anterior (solo en saltos grandes)

Tipo de salto ¿Limpiar?
Patch (0.16.1 → 0.16.2) No hace falta
Minor (0.16.x → 0.17.x) Recomendado
Major o salto grande (0.13 → 0.16) Obligatorio
rm -rf node_modules dist src/client/dist
npm cache clean --force

10. Instalar dependencias y construir

npm install

Si te corta con ECONNRESET (típico en redes detrás de Tor o con conexiones inestables), aumenta los timeouts y reintenta:

npm config set fetch-retries 5
npm config set fetch-retry-mintimeout 20000
npm config set fetch-retry-maxtimeout 120000
npm config set fetch-timeout 600000
rm -rf node_modules
npm install

Los warnings de deprecated, ERESOLVE, y npm audit son ruido del ecosistema npm — son responsabilidad del mantenedor del proyecto, no tuya. No ejecutes npm audit fix, puede romper el build.

Cuando termine sin errores, construye:

npm run build

11. Verificar la versión

head -n 3 package.json | grep version

Debe coincidir con $VERSION.

12. Salir y arrancar el servicio

exit
sudo systemctl start thunderhub
sudo journalctl -fu thunderhub

13. Verificaciones críticas en el log

Busca estas dos líneas en los primeros segundos:

Getting production env variables.

Si pone development en lugar de production, el override de systemd no se aplicó. Revisa /etc/systemd/system/thunderhub.service.d/override.conf y haz sudo systemctl daemon-reload && sudo systemctl restart thunderhub.

Nest application successfully started
Application is running on: http://[::1]:3001
Connected to <tu-nodo>

Si todo aparece, sal con Ctrl+C y abre la web para confirmar que carga y conecta con tu nodo. Te pedirá la contraseña otra vez (esperado, el JWT secret cambió).


Solución de problemas comunes

Your local changes to the following files would be overwritten by merge

Te lo da package-lock.json. Solución limpia:

git checkout -- package-lock.json
git merge v$VERSION

gpg: Can't check signature: No public key

Con la clave B5690EEEBB952194, importa la de GitHub web-flow:

curl https://github.com/web-flow.gpg | gpg --import

Y vuelve a verificar.

sh: 1: rimraf: not found durante npm run build

Significa que el npm install anterior falló a mitad. Borra node_modules y reinstala:

rm -rf node_modules
npm install

El servicio arranca pero isProduction: false en el log

El override de systemd no se aplicó. Revisa:

sudo cat /etc/systemd/system/thunderhub.service.d/override.conf

Debe mostrar:

[Service]
Environment="NODE_ENV=production"

Si no, recréalo con el bloque tee del setup inicial.

Si todo lo demás falla

Antes de la opción nuclear (desinstalar y reinstalar), prueba:

rm -rf node_modules package-lock.json dist src/client/dist
git checkout -- package-lock.json
npm install
npm run build

Procedimiento resumido (chuleta)

Cuando ya tengas el setup hecho, esto es todo lo que necesitas mirar:

# Como admin
sudo systemctl stop thunderhub
sudo su - thunderhub
cd thunderhub

VERSION=0.16.2  # ← cambia

git checkout -- package-lock.json schema.gql 2>/dev/null
git fetch https://github.com/apotdevin/thunderhub.git tag v$VERSION
git verify-commit v$VERSION^{commit}     # confirma "Good signature"
git merge v$VERSION

less CHANGELOG.md

# Solo en minor/major:
rm -rf node_modules dist src/client/dist

npm install
npm run build
head -n 3 package.json | grep version

exit

sudo systemctl start thunderhub
sudo journalctl -fu thunderhub | grep -E 'isProduction|jwtSecret|successfully started'

Por qué esto importa

Tu nodo Lightning gestiona dinero real. Cada actualización es una oportunidad para que código nuevo entre en él. Sin verificación de firmas, confías en que GitHub no esté comprometido, en que la cuenta del mantenedor no esté hackeada, y en que tu conexión TLS al servidor de GitHub sea íntegra. Verificar la firma GPG del commit reduce esa cadena de confianza a un único punto: la clave del mantenedor.

Sobre el NODE_ENV=production: este no es un fallo de las guías existentes per se. Es una decisión de diseño de ThunderHub que asume que el operador conoce el estado de su entorno. Si tú no lo sabes, lo razonable es asumir lo peor.

Si encuentras erratas, mejoras o casos no cubiertos, te leo en los comentarios 🤙


Write a comment
No comments yet.