Actualizar Node.js en z/OS (IBM Open Enterprise SDK for Node.js)
IBM ha publicado las versiones 24.22.1 y 22.23.4 de IBM Open Enterprise SDK for Node.js para z/OS. Como en la era de la IA cada vez aparecen más vulnerabilidades de seguridad (CVE), aprovecho para enseñar cómo actualizar Node.js en z/OS. Pienso que es algo que conviene tener claro antes de necesitarlo de manera urgente.
El 21 de octubre de 2026 el proyecto Node.js publicó CVE-2026-111497 (“Node2Shell”): un fallo en el decodificador Brotli que trae Node.js y que permite ejecución remota de código.
Afecta a las ramas 22.x, 24.x y 26.x anteriores a 22.23.4, 24.22.1 y 26.12.1.
No tengo ninguna confirmación de IBM de que Node.js de z/OS esté afectado: esa información es restringida y no tengo acceso a ella (solo disponible a través de IBM Z and LinuxONE Security Portal).
Aun así, sirve para preparar el procedimiento por si un día nos encontramos ante una situación crítica.
Para obtener información sobre vulnerabilidades y saber si el software está afectado (aunque la versión coincida con las afectadas), hay que dirigirse a IBM a través de IBM Z and LinuxONE Security Portal. No facilitan este tipo de información a través de casos abiertos en IBM Support.
Este Redbook también es muy interesante:
z/OS Patch Velocity: A practical framework for the AI era
Qué versión tenemos y dónde está
La ruta por defecto suele ser /usr/lpp/IBM/cnj/. En mi ADCD hay dos versiones:
- 20.11.0 en /usr/lpp/IBM/cnj/IBM/node-v20.11.0-os390-s390x-202402131732 (Brotli 1.0.9). La rama 20 ya está fuera de soporte en el proyecto Node.js.
- 22.22.1 en /u/nodeJS/node-v22.22.1/node-v22.22.1-os390-s390x-202603191702 (Brotli 1.1.0). Esta versión la descargué hace un tiempo y es el ejemplo perfecto para actualizar a la versión 22.23.4.
Con los siguientes comandos, podemos ver la versión actual de Node.js o la versión de Brotli que usa.
cd /u/nodeJS/node-v22.22.1/node-v22.22.1-os390-s390x-202603191702/bin
./node -v
./node -p "process.versions.brotli"
Si queremos saber en qué zFS están los directorios de Node.js, podemos usar el comando “D OMVS,FILE” y ver si tiene alguno propio o está contenido en algún zFS de una ruta superior, pero también podemos usar el siguiente comando de OMVS que es más rápido.
df -kP /usr/lpp/IBM/cnj /u/nodeJS/node-v22.22.1En este caso, vemos que hay dos zFS.
ZFS.Z31B.CNJ
IBMUSER.NODEJS.V22R22M1.ZFS

Como tengo un zFS concreto para la versión v22.22.1, si hay un riesgo de vulnerabilidad y puedo parar las STCs que lo usen (porque no son críticas o no quiero asumir riesgos, etc.), podría desmontar el zFS de esta versión concreta y evitar que esté disponible en el sistema.
Luego haría un nuevo directorio y zFS para la nueva versión.
En la ruta superior (/u/nodeJS/) se puede crear un enlace simbólico llamado “current” que apunte a la versión que queramos usar. Así no hay que modificar las STCs para que apunten a la nueva versión.
Descargar la versión nueva
Hay dos opciones para obtener este software: Shopz (SMP/E, PTF, etc.) o la edición PAX.
En mi caso, solo tengo acceso a la edición PAX (y agradezco mucho que esté disponible).
El enlace es el siguiente.
https://www.ibm.com/es-es/products/sdk-nodejs-compiler-zos
Entrar en “Descárguelo ahora”.

Después de hacer login con nuestra cuenta, podremos descargar la versión que queramos.

En este enlace también podemos ver las nuevas versiones que van publicando:
Fix list for IBM Open Enterprise SDK for Node.js
https://www.ibm.com/support/pages/fix-list-ibm-open-enterprise-sdk-nodejs
Para hacer la instalación, vamos a seguir los pasos de la guía de IBM.
https://www.ibm.com/docs/en/sdk-nodejs-zos/22.0.0?topic=configuring-installing-pax-format
Previamente debemos verificar que cumplimos los requisitos:

Una vez lo hemos descargado, deberemos subirlo por FTP, pero antes, vamos a crear un zFS para esta versión.
Desde la utilidad zFS Generator de la web, podemos crear el job fácilmente. Por ejemplo:
//ZFSNEW JOB (ACCT),'CREATE ZFS',CLASS=A,MSGCLASS=X
//* 1. Mount point
//MKDIR EXEC PGM=BPXBATCH
//STDOUT DD SYSOUT=*
//STDERR DD SYSOUT=*
//STDPARM DD *
SH mkdir -p /u/nodeJS/node-v22.23.4
/*
//* 2. Define the aggregate (ZFS: EA, formatted at mount)
//DEFINE EXEC PGM=IDCAMS,COND=(0,NE)
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
DEFINE CLUSTER (NAME(IBMUSER.NODEJS.V22R23M4.ZFS) -
ZFS -
CYLINDERS(900 0) -
SHAREOPTIONS(3))
/*
//* 3. Mount it
//MOUNT EXEC PGM=IKJEFT01,COND=(0,NE)
//SYSTSPRT DD SYSOUT=*
//SYSTSIN DD *
MOUNT FILESYSTEM('IBMUSER.NODEJS.V22R23M4.ZFS') +
MOUNTPOINT('/u/nodeJS/node-v22.23.4') +
TYPE(ZFS) MODE(RDWR)
/*
Terminará correctamente.

Tendremos el nuevo zFS montado. Este MOUNT no se mantiene tras un IPL: para que se monte siempre, hay que añadirlo al miembro BPXPRMxx de la PARMLIB de la instalación.

Ahora podemos subir Node.js a ese directorio usando FTP (por ejemplo) en modo BINARY.


Descomprimir el software
Desde OMVS (TSO OMVS), dar los siguientes comandos:
cd /u/nodeJS/node-v22.23.4
pax -rf ibm-node-v22.23.4-os390-s390x-202611040343.pax.Z -ppx
ls -lAl dar el último comando, veremos que aparece el directorio “node-v22.23.4-os390-s390x-202611040343”.

Si hacemos el siguiente comando, veremos el contenido del directorio.
ls -l node-v22.23.4-os390-s390x-202611040343
Preparar el entorno (setup.sh y .env)
Según la guía de IBM, después de descomprimir hay que ejecutar setup.sh dentro del directorio de la versión. Este script comprueba los requisitos del sistema y genera el fichero .env con las variables de entorno que necesita Node.js.
cd /u/nodeJS/node-v22.23.4/node-v22.23.4-os390-s390x-202611040343
./setup.sh
. ./.envAl ejecutar setup.sh vemos cómo va comprobando cada requisito: plataforma, hardware, versión del sistema operativo, que ICSF esté activo, memoria, Python, Make y las cabeceras de C/C++.
En mi caso termina con 2 avisos (warnings). Uno es que la versión de Make es antigua: Make 4.1 o superior solo hace falta para instalar add-ons nativos de Node.js (por ejemplo vsam.js, zcrypto, racf o zrexx), así que no impide usar Node.js.



Al final nos muestra dónde están node y npm, el log que ha generado y el comando para cargar el entorno, que es el que ejecutamos después con un punto seguido de un espacio (. ./.env). No muestra nada, pero desde ese momento la sesión tiene las variables de Node.js y el directorio bin de la versión en el PATH. Es importante el punto y el espacio: si ejecutamos ./.env sin él, las variables se definen en otro proceso y se pierden al terminar.
Ahora podemos volver a comprobar las versiones:
cd /u/nodeJS/node-v22.23.4/node-v22.23.4-os390-s390x-202611040343/bin
./node -v
./node -p "process.versions.brotli"
El .env también define las variables CC, CXX y LINK (compilador de C/C++). Si usamos el compilador para otras cosas, habrá que revisarlas.
Como setup.sh escribe el .env y el log dentro del directorio de la versión, hay que ejecutarlo con el zFS montado en modo RDWR. Si después queremos montarlo en modo READ, lo haremos al terminar.
Aquí el contenido del fichero .env:

Cambiar a la versión nueva
Ahora vamos a crear un enlace simbólico a la nueva versión. Esto sirve porque podemos configurar “current” en las STCs para que apunten al Node.js actual.
Cuando instalemos una nueva versión, solo tendremos que modificar el enlace “current”.
cd /u/nodeJS
rm -f current # only if it already exists
ln -s node-v22.23.4/node-v22.23.4-os390-s390x-202611040343 current
ls -l current
En el .profile del usuario (en la carpeta HOME del usuario) debemos añadir una línea si queremos que cargue las variables de entorno de Node.js cuando entremos, por ejemplo, a OMVS.
Para saber el home del usuario, con entrar a OMVS (TSO OMVS), ya veremos cuál es. En este caso, “/u/ibmuser”.

Pero si tenemos permisos de RACF y queremos mirar el HOME de nuestro usuario (o de otro), usaremos el comando:
TSO LU IBMUSER OMVS
Al final, si el usuario tiene definido el segmento OMVS, deberíamos ver el parámetro HOME.

Ahora vamos a ese directorio y editamos el fichero .profile.

Añadimos lo siguiente al final:
. /u/nodeJS/current/.env
Ahora, al entrar a OMVS, si escribimos “node -v” nos aparecerá la versión sin tener que buscar la ruta concreta de Node.js.
node -v
npm -v
node -p "process.versions.brotli"
Brotli sigue mostrando 1.1.0 en la 22.23.4 (igual que en la 22.22.1). Es posible que el parche de la corrección se aplicase sobre la copia ya incluida sin que cambie el número de versión.
Por eso lo que cuenta es node -v: la 22.23.4 es la versión en la que el proyecto Node.js incluye la corrección. Es de esperar que, si la versión para z/OS estaba afectada, la 22.23.4 incluya la corrección.
Volver atrás
En caso de tener que volver a usar la versión anterior, solo habría que rehacer el enlace simbólico. Por este motivo, conviene no borrar lo anterior hasta verificar que todo funciona (en el caso de que la versión anterior contenga vulnerabilidades graves, habría que valorar cómo proceder).
cd /u/nodeJS
rm -f current
ln -s <previous version directory> current
. /u/nodeJS/current/.env
node -vEl .env usa la ruta absoluta de la versión, así que después de cambiar el enlace hay que volver a cargarlo (o volver a entrar en OMVS) para que la sesión use la otra versión. Las STCs que usen Node.js habrá que reiniciarlas.