Situación actual: PHP2Shell. Dos vulnerabilidades críticas de PHP (CVSS 9.2) permiten ejecutar código malicioso sin autenticación. Parches desde el 21/10/2026.Qué hacer ahora →

Configurar Apache para PHP de forma segura

Apache es flexible, y precisamente eso lo hace vulnerable a errores de configuración. Cómo conectar PHP mediante PHP-FPM, cerrar .htaccess como puerta trasera y fijar de forma segura las opciones básicas más importantes.

Actualizado 7 min de lecturaRefuerzo y configuración

En resumen: para configurar Apache con PHP de forma segura, conecte PHP mediante PHP-FPM y mod_proxy_fcgi, desactive .htaccess con AllowOverride None y fije ServerTokens Prod, ServerSignature Off, TraceEnable Off y Options -Indexes. Ajuste LimitRequestBody a los límites de PHP y desactive los módulos que no necesite. La configuración no sustituye a la actualización de PHP, pero reduce notablemente la superficie de ataque.

Apache tras PHP2Shell: más que un reinicio

Los responsables de Apache estuvieron en octubre de 2026 bajo una presión especial. El equipo de PHP clasifica el riesgo en mod_php como el más alto, porque allí se demostró un exploit antes de que se ejecute siquiera el código de la aplicación. Los pasos urgentes, es decir, parchear y reiniciar por completo, los describe la página Por qué mod_php soporta el mayor riesgo.

Tras el parche queda la pregunta de lo buena que es la propia configuración de Apache. Los servidores con años encima suelen acumular ajustes de muchos años: listados de directorios, permisos abiertos de .htaccess, módulos que ya nadie necesita. Cada uno de ellos puede hacer mayor de lo necesario un error posterior.

Este artículo describe una configuración básica segura y ligera para Apache 2.4 con PHP-FPM. Los ejemplos usan rutas de Debian y Ubuntu; en la familia RHEL, los archivos están en /etc/httpd/.

Conectar PHP mediante PHP-FPM en lugar de mod_php

Con PHP-FPM, PHP se ejecuta en procesos propios, separados del servidor web. Apache pasa las peticiones mediante mod_proxy_fcgi. Según la documentación de Apache, la conexión mediante SetHandler tiene una ventaja sobre ProxyPassMatch: Apache asigna primero la petición por sí mismo a un archivo del sistema de archivos y solo después la pasa a PHP-FPM.

<FilesMatch "\.php$">
    SetHandler "proxy:unix:/run/php/seite1.sock|fcgi://localhost/"
</FilesMatch>

Los módulos se activan en Debian y Ubuntu con a2enmod proxy_fcgi. Quien abandona mod_php desactiva el módulo de PHP y cambia después del MPM Prefork al MPM Event. Los antecedentes del modo de funcionamiento antiguo los explica mod_php explicado: PHP dentro del proceso de Apache.

Del lado de PHP-FPM, security.limit_extensions = .php pertenece a cada pool. Según el manual de PHP, de lo contrario FPM ejecuta también archivos .phar.

Configurar Apache con PHP de forma segura: las opciones básicas

Algunos ajustes rigen para todo el servidor y pertenecen a un archivo de configuración propio, por ejemplo /etc/apache2/conf-available/haertung.conf, activado con a2enconf haertung.

# Acortar los datos de versión (solo posible para todo el servidor)
ServerTokens Prod
ServerSignature Off

# Desactivar el método TRACE
TraceEnable Off

# En principio no liberar nada; los sitios web lo permiten de forma específica
<Directory />
    Options None
    AllowOverride None
    Require all denied
</Directory>

La tabla siguiente clasifica las opciones más importantes. Los valores por defecto y el efecto proceden de la documentación de Apache.

Directiva Por defecto Recomendación Por qué
ServerTokens Full Prod la cabecera Server solo indica «Apache»
ServerSignature Off Off sin línea de versión bajo las páginas de error
TraceEnable on Off TRACE se rechaza con 405
Options FollowSymlinks -Indexes, enlaces simbólicos solo según el propietario sin listados de directorios
AllowOverride None None .htaccess no se evalúa
LimitRequestBody 1 GiB (desde 2.4.54) acorde con post_max_size rechazar pronto las peticiones grandes

Importante con AllowOverride: muchas distribuciones y guías de CMS fijan AllowOverride All para el webroot. Con ello, cualquier archivo .htaccess puede modificar reglas de reescritura, handlers y, con mod_php, incluso ajustes de PHP. Un atacante con derechos de escritura en una carpeta de subidas puede dejar allí su propio .htaccess. Con AllowOverride None este camino queda cerrado.

Un VirtualHost como plantilla

El VirtualHost siguiente reúne los puntos para un único sitio web. Adapte las rutas de certificado, el socket y los directorios. mod_ssl y mod_headers deben estar activos.

<VirtualHost *:443>
    ServerName www.example.de
    DocumentRoot /var/www/seite1/public

    SSLEngine on
    SSLCertificateFile    /etc/ssl/seite1/fullchain.pem
    SSLCertificateKeyFile /etc/ssl/seite1/privkey.pem

    <Directory /var/www/seite1/public>
        Options -Indexes +SymLinksIfOwnerMatch
        AllowOverride None
        Require all granted
    </Directory>

    <FilesMatch "\.php$">
        SetHandler "proxy:unix:/run/php/seite1.sock|fcgi://localhost/"
    </FilesMatch>

    # Bloquear el control de versiones y los archivos de entorno
    <DirectoryMatch "/\.(git|svn|hg)">
        Require all denied
    </DirectoryMatch>
    <FilesMatch "^\.env">
        Require all denied
    </FilesMatch>

    # 32 MiB, acorde con post_max_size = 32M
    LimitRequestBody 33554432

    Header unset X-Powered-By
    Header always unset X-Powered-By
</VirtualHost>

El doble Header unset no es un descuido. Según la documentación de Apache, las cabeceras de mod_proxy_fcgi acaban en una tabla interna distinta de la de las cabeceras del propio servidor; con ambas variantes se cubren los dos casos. Otras cabeceras que protegen activamente a los visitantes las describe la guía Cabeceras de seguridad para sitios web.

Las carpetas de subidas y de caché necesitan además un bloqueo de ejecución. Cómo encontrar y bloquear todas las carpetas con permiso de escritura figura en Prohibir la ejecución de PHP en las carpetas de subidas.

Depurar los módulos y comprobar el resultado

Cada módulo cargado es código que reacciona a las peticiones. Compruebe qué módulos están activos y desactive los que no necesite. Candidatos típicos son autoindex, status sin restricción de acceso, cgi y userdir.

# Mostrar los módulos activos
apachectl -M | sort
# Ejemplo Debian/Ubuntu: desactivar el módulo de listado de directorios
sudo a2dismod autoindex
# Comprobar la configuración y solo entonces recargar
sudo apachectl configtest && sudo systemctl reload apache2
# Prueba desde fuera: TRACE debe devolver 405, .git 403
curl -s -o /dev/null -w "%{http_code}\n" -X TRACE https://www.example.de/
curl -s -o /dev/null -w "%{http_code}\n" https://www.example.de/.git/HEAD

mod_status merece especial atención. La página de estado muestra las peticiones en curso con direcciones y rutas solicitadas. Si se necesita, limite el acceso con Require ip a sus redes de administración. Lo mismo vale para las páginas de estado de PHP-FPM que se hayan hecho accesibles a través de Apache.

Importante

No cambie AllowOverride sin preparación. Traslade primero al VirtualHost las reglas de todos los archivos .htaccess y pruebe el sitio web en una copia. De lo contrario, las redirecciones y las URL amigables dejarán de funcionar tras la recarga.

Como capa adicional delante de la aplicación puede ser útil un Web Application Firewall propio; la introducción la describe Usar ModSecurity y el OWASP Core Rule Set.

Conclusión: el orden supera a la medida aislada

Una configuración segura de Apache para PHP se compone de pocos elementos bien entendidos. PHP se ejecuta mediante PHP-FPM separado del servidor web, .htaccess no se evalúa, los datos de versión y TRACE están desactivados, los límites de tamaño encajan con PHP y las carpetas con permiso de escritura no ejecutan scripts. Ninguno de estos puntos es espectacular por sí solo. Juntos hacen que un fallo en un punto no conduzca de inmediato a la toma del servidor.

Para la dirección y los responsables de proyecto, una segunda propiedad es casi más importante: una configuración ordenada es comprensible. Si todas las reglas están en el VirtualHost en lugar de dispersas en decenas de archivos .htaccess, ante la próxima vulnerabilidad crítica se puede comprobar con rapidez qué sitio web está conectado y cómo. En una situación como la de octubre de 2026, eso ahorra precisamente el tiempo que importa.

Aun así, planifique el cambio con calma y con un entorno de pruebas. Un cambio precipitado de mod_php a PHP-FPM poco antes de un fin de semana crea más problemas de los que resuelve.

¿Cómo ayuda PHP SOS en concreto?

  • Revisar lo existente: leemos toda la configuración de Apache, todos los módulos activos y todos los archivos .htaccess.
  • Planificar el cambio: donde todavía se ejecuta mod_php, preparamos el paso a PHP-FPM con pools propios por sitio web.
  • Reforzar la configuración: fijamos las opciones básicas, trasladamos las reglas de .htaccess a los VirtualHost y bloqueamos las carpetas con permiso de escritura.
  • Probar y documentar: tras cada cambio comprobamos los sitios web desde fuera y dejamos constancia del estado en el marco del refuerzo de servidores.

Preguntas frecuentes

¿Debería seguir usando mod_php?

Para instalaciones nuevas recomendamos PHP-FPM mediante mod_proxy_fcgi. El equipo de PHP clasifica el riesgo por PHP2Shell como el más alto en mod_php. Con PHP-FPM, PHP se ejecuta separado del servidor web, con usuarios propios por sitio web y límites propios.

¿Por qué AllowOverride None si mi CMS necesita .htaccess?

Un .htaccess puede crearlo cualquiera que tenga permiso de escritura en el webroot, también el código inyectado. Con AllowOverride None, Apache no evalúa esos archivos. Las reglas de su CMS se trasladan entonces una sola vez al VirtualHost. Supone algo de trabajo, pero hace la configuración comprensible y más rápida.

¿Puedo fijar ServerTokens de forma distinta para cada sitio web?

No. Según la documentación de Apache, ServerTokens rige para todo el servidor y no puede cambiarse por VirtualHost. Controla además el dato de versión bajo las páginas de error que muestra ServerSignature.

¿Qué valor tiene LimitRequestBody por defecto?

Desde Apache 2.4.54 el valor por defecto es 1 GiB; en la versión 2.4.53 y anteriores era ilimitado. Fije el valor de acuerdo con post_max_size de su configuración de PHP, para que las peticiones demasiado grandes se rechacen ya en el servidor web.

Fuentes

Contacto inmediato

Cada hora cuenta. Escríbanos ahora.

Describa brevemente el sistema, la versión de PHP y lo que ha observado. Nos pondremos en contacto, aclararemos la situación y trabajaremos en remoto hasta que el incidente quede cerrado y documentado.

Ayuda inmediata