El error de la extensión SSH2 de PHP con claves privadas protegidas con contraseña con distros derivadas de Debian

Enlazando con el artículo anterior que explica el problema los packages de las extensiones SSH2 y mcrypt, me he encontrado con otro problema durante la migración del servidor.

Una de las web de la empresa requiere del uso de la extensión SSH2 de PHP ya que tiene que conectarse con un servidor SSH (en realidad es una transferencia de archivos sobre SSH, o sea, SCP) para el intercambio de unos ficheros que contienen puntos de los usuarios (que luego pueden cambiar por regalos, tickets, etc… Algo así como la Travel Club en España).  Alguien podría pensar que para esto podrían haber creado un simple servidor FTP sobre TLS, pero estos japos son así. (Quizás algún día explique las chapuzadas que he visto en el país del Sol Naciente, como por ejemplo, comprobar si un certificado SSL es válido usando Internet Explorer 6 en Windows XP en pleno 2014. La mega compañía de móviles SoftBank para más señas).

ssh-rsa

Pues resulta que tras debugar el código PHP me encuentro con que la función “ssh2_auth_pubkey_file” me devuelve false todo el rato y en los errores de PHP te dice:

ssh2_auth_pubkey_file(): Authentication failed for baka using public key: Callback returned error in /home/baka/www/bacaweb/application/services/PointExchangeBatchService.php

Nota: baka no era el usuario real, pero por motivos de seguridad lo he cambiado (baka significa tonto en japonés)

Así que era evidente que algo estaba fallando.

Para asegurarme que no era un error de la URI del host o de algún certificado me intento conectar manualmente como si fuera Apache2:

sudo su www-data
scp -i /home/baka/www/bakaweb/data/ssh/id_rsa -P 8023 /home/baka/www/bakaweb/data/csv/points.csv [email protected]:send/

Y sí que me dejó enviar el fichero. En principio, todo parecía bien configurado.

Una de las cosas buenas de probar la conexión ssh manualmente es que automáticamente te crea el fichero .ssh/known_hosts al aceptar permanentemente el certificado del servidor. Para evitar problemas y prevenir que Apache2 tratara a la conexión como no “trusted” cada vez que intentaba hacer el scp, decidí cambiar el parámetro “StrictHostKeyChecking” a no en el fichero de configuración SSH /etc/ssh/ssh_config.

Tras probar de nuevo, seguía con el mismo error. ¿ Que narices estaba ocurriendo ?

Tras mucho “googlear”, finalmente encontré la respuesta de que es lo que pasa.

688a30c4484c5e8.jpg

Al parecer se trata de un bug que afecta a todas las distribuciones de Linux basadas en Debian como Ubuntu y demás y resumiendo un poco, el problema aparece cuando usas private keys protegidas con contraseña como era mi caso. Recuerdo que la función “ssh2_auth_pubkey_file” tiene precisamente como último parámetro la contraseña de la clave privada. Simplemente no funciona con claves privadas protegidas con contraseña pero podéis encontrar más info en https://bugs.php.net/bug.php?id=58573

La solución es bastante simple y rápida. Se trata de descifrar la private key (id_rsa) y generar una nueva private key no protegida por contraseña:

sudo mv /home/baka/www/bakaweb/data/ssh/id_rsa /home/baka/www/bakaweb/data/ssh/id_rsa_PASSWDPROTECTED
sudo openssl rsa -in /home/baka/www/bakaweb/data/ssh/id_rsa_PASSWDPROTECTED -out /home/baka/www/bakaweb/data/ssh/id_rsa

En la primera instrucción renombramos la private key y en la segunda, nos pedirá la contraseña y tras comprobar que sea válida nos generará un la misma clave privada pero no cifrada con ninguna contraseña, lista para ser usada con la función “ssh2_auth_pubkey_file” omitiendo, por supuesto, el último parámetro que es la contraseña.

Tener claves privadas no cifradas con contraseña no es lo más seguro del mundo, pero por lo menos, las conexiones SCP están funcionando y la web no está parada.

Si te ha gustado y quieres compartir esta página..