# rm-rf.es | Administración de sistemas

Bitácora personal de un SysAdmin Gnu/Linux, Windows, BSD...

suPHP 0.7.1: SecurityException in Application.cpp:511: Unknown Interpreter: php


Hoy he estado actualizando un equipo. Una de las actualizaciones era la de la versión de suPHP a la 0.7.1. La actualización ha ido bien hasta que he comenzado a probar los sitios web.

Todos recibían un error 500 (Internal Server Error), típico de suPHP, y en los logs se volcaba la siguiente información:

[Sun Oct 17 19:08:03 2010] [error] [client XX.XX.XXX.XX] SecurityException in Application.cpp:511: Unknown Interpreter: php
[Sun Oct 17 19:08:03 2010] [error] [client XX.XX.XXX.XX] Premature end of script headers: index.php

En este momento ya había entrado en modo pánico, pero rebuscando por Internet información sobre esta versión, he visto que había un pequeño cambio o bug (bueno, pequeño…) por el cual, en el fichero de configuración de suPHP (/etc/suphp.conf) los handlers tenían que ir entre comillas:

Antes:

;Handler for php-scripts
x-httpd-php=php:/usr/bin/php-cgi

;Handler for CGI-scripts
x-suphp-cgi=execute:!self

Después:

;Handler for php-scripts
x-httpd-php="php:/usr/bin/php-cgi"

;Handler for CGI-scripts
x-suphp-cgi="execute:!self"

Tras este cambio, y reiniciar apache todo ha vuelto a funcionar a la normalidad.

suPHP: “Premature end of script headers” en el error_log


Si acabáis de montar un servidor apache con suPHP y al tratar de ejecutar cualquier PHP el navegador muestra “Internal Server Error“, y el log de apache muestra “Premature end of script headers” lo más probable es que hayáis instalado la versión cliente (CLI) de php en vez de la versión CGI (php-cgi). Para solventar esto debéis copiar el binario de php CGI en donde se supone debe estar instalado el binario de php (donde vaya apache a buscarlo vamos).

En mi caso, en un servidor CentOS el binario php-cgi estaba aquí:

/usr/bin/php-cgi

Y apache utilizaba el binario de php-cliente:

/usr/bin/php

Bien, entonces he guardado un backup del cliente y he creado un enlace simbólico para que /usr/bin/php sea lo mismo que /usr/bin/php-cgi, podéis también sobreescribirlo, lo que queráis. Con este cambio el problema debería quedar solucionado.

suPHP: “/…/” is not in document root of Vhost “/…/”


[Mon Aug 18 04:00:06 2008] [error] [client xx.xx.xx.xx] SoftException in Application.cpp:217: File "/usr/share/phpmyadmin/index.php" is not in document root of Vhost "/var/www/html/"

Este error es provocado a una restricción de seguridad en servidores con Apache con suPHP. Si véis conveniente la resolución del mismo, debéis acceder al fichero de configuración de suphp, normalmente ubicado en /etc/suphp.conf, y hacer lo siguiente:

Modificar esta linea:

;Check wheter script is within DOCUMENT_ROOT
check_vhost_docroot=true

Por esto:

;Check wheter script is within DOCUMENT_ROOT
check_vhost_docroot=false

Y solucionado, ya depende de cada uno si ve correcto quitar la restricción de seguridad o solventar el problema de rutas. Como habréis comprobado, la directiva evita que se acceda a fichero o carpetas que se encuentran fuera del DocumentRoot establecido en el Virtualhost.

Utilizar .htaccess / php.ini en Apache con suPHP


En el momento que compilas apache con suPHP, las directivas incluidas dentro de los ficheros .htaccess dejan de funcionar. Existen dos posibilidades, compilar htscanner para permitir el uso de ficheros .htaccess y todas las directivas que hay dentro de él, o usar un fichero php.ini personalizado dentro de cada virtualhost con las directivas que queramos.

Si preferís la opción de seguir usando .htaccess, acceder aquí para seguir las instrucciones de htscanner, no obstante es mucho más sencilla la segunda opción.

Para la segunda opción, pongamos el caso que para un virtualhost concreto, queremos añadir personalizaciones en un fichero php.ini, para ello añadimos la siguiente línea a su virtualhost, con la ruta en la que se encuentra el fichero php.ini personalizado:

SuPHP_ConfigPath /home/dominio/

Hay que tener en cuenta, que en los php.ini, y suPHP en general no acepta directivas del tipo php_flag o php_admin_flag, os pongo unos ejemplos de como realizar el cambio para que php.ini lo acepte:

Si queremos pasar esta información de un .htaccess:

$ cat .htaccess
php_admin_flag short_open_tag On
php_admin_flag safe_mode Off
php_admin_flag register_globals Off
php_admin_flag magic_quotes_gpc On
php_admin_flag magic_quotes_runtime Off

En un php.ini sería así:

$ cat php.ini
short_open_tag= On
safe_mode= Off
register_globals= Off
magic_quotes_gpc= On
magic_quotes_runtime= Off

En este caso, ubicaríamos el php.ini en /home/dominio/php.ini, y el dominio configurado dentro de este virtualhost recogería estas directivas personalizadas.

Una vez realizado, reiniciando apache recogería los cambios del virtualhost, y creando un phpinfo() podríamos ver si realmente coge las directivas especificadas.

$ vi phpinfo.php

<? phpinfo(); ?>