Ficheros php.ini y httpd.conf completamente securizados, explicando parámetro a parámetro las modificaciones aplicadas para ocultar información del servidor, deshabilitar funciones peligrosas, limitar recursos y restringir accesos no deseados. Para convertir un XAMPP (servidor web Apache) de desarrollo en un servidor listo para entornos de producción, pendiente únicamente de la migración a HTTPS. Mostramos algunos ejemplos de ataques, intentos de intrusión o de detectar vulnerabilidades en servidor web y cómo saber si han sido bloqueados.
- ¿Por qué es necesario endurecer la configuración de XAMPP (servidor web Apache)?.
- php.ini para PHP y httpd.conf para Apache.
- Ejemplo de php.ini securizado y parámetros añadidos.
- Ejemplo de httpd.conf securizado y parámetros añadidos.
- Ejemplos de intentos de descubrir vulnerabilidades y de ataques a nuestro servidor web.
- Recomendaciones adicionales para fortalecer la seguridad de un servidor web.
¿Por qué es necesario endurecer la configuración de XAMPP (servidor web Apache)?
XAMPP es una herramienta excelente para el desarrollo local, pero su configuración por defecto está orientada a la facilidad de uso, y al desarrollo, no a la seguridad. Directivas como display_errors=On, Options Indexes o la exposición de la versión de PHP y Apache son útiles durante el desarrollo, pero representan vulnerabilidades críticas en un entorno de producción.
Cuando desplegamos una API REST en un servidor accesible desde Internet, estamos exponiendo nuestro código a todo tipo de sondeos automáticos: bots que buscan archivos sensibles como .env, .git/config, rutas de administración no protegidas o intentos de ejecución remota de comandos. Sin una configuración adecuada, el servidor puede filtrar información valiosa para un atacante (versiones exactas de software, rutas absolutas del sistema de archivos, estructura de directorios) o incluso permitir la ejecución de código malicioso.
Hay que tener en cuenta que los entornos XAMPP no son los ideales para despliegues de producción. Aún así, si tenemos que exponerlos a Internet, será muy recomendable aplicar las buenas prácticas que indicaremos en este tutorial.
Cada parámetro que modifiquemos para endurecer la seguridad irá acompañado de su justificación técnica, el riesgo que mitiga y el posible impacto en la funcionalidad de la aplicación.
Consideración importante: Antes de aplicar cualquier cambio en un entorno de producción, es imprescindible:
- Realizar una copia de seguridad de los archivos de configuración originales (
php.ini,httpd.conf) y del código fuente de la aplicación. - Probar cada cambio de forma individual en un entorno de pruebas idéntico al de producción. Probando cada parámetro o grupo de parámetros modificado de forma progresiva, no incluyéndolos todos «de golpe» porque puede que el servidor web no se inicie y no sepamos cuál está provocando el error.
- Verificar el funcionamiento completo de la API después de cada modificación, incluyendo autenticación, subida de archivos, consumo de servicios externos y cualquier otra funcionalidad crítica.
- Monitorizar los logs durante el proceso para detectar errores inesperados o falsos positivos en los bloqueos.
php.ini para PHP y httpd.conf para Apache
A continuación, presentamos dos archivos de configuración completos que representan el estado final de nuestro proceso de hardening:
php.ini– Configuración del intérprete PHP con directivas de seguridad activas.httpd.conf– Configuración del servidor Apache con restricciones de acceso y ocultación de información.
Ambos archivos se muestran sin comentarios para facilitar su lectura y comprensión directa de las directivas activas.
Limitaciones de esta configuración
El proceso que mostramos aquí es un punto de partida sólido, pero no exhaustivo. Quedan fuera del alcance de este artículo aspectos como:
- Configuración de HTTPS con certificados válidos (aunque mencionaremos los pasos necesarios).
- Implementación de un WAF (Web Application Firewall).
- Sistemas de detección de intrusiones.
- Monitorización avanzada de logs y alertado en tiempo real.
- Configuración para entornos específicos.
El siguiente paso lógico después de aplicar estas configuraciones sería migrar la comunicación a HTTPS, ya que muchas de las directivas de seguridad relacionadas con cookies (session.cookie_secure) o la integridad de los datos requieren una conexión cifrada para ser realmente efectivas.
Ejemplo de php.ini securizado y parámetros añadidos
php.ini
La descarga del fichero php.ini securizado de ejemplo:
El contenido del fichero php.ini securizado:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
[PHP] engine=On short_open_tag=Off precision=14 output_buffering=4096 zlib.output_compression=Off implicit_flush=Off unserialize_callback_func= unserialize_max_depth=20 serialize_precision=-1 zend.enable_gc=On zend.exception_ignore_args=On zend.exception_string_param_max_len=0 expose_php=Off max_execution_time=30 max_input_time=20 max_input_nesting_level=64 max_input_vars=1000 memory_limit=128M open_basedir="D:\xampp\htdocs;D:\xampp\tmp" error_reporting=E_ALL & ~E_DEPRECATED & ~E_STRICT display_errors=Off display_startup_errors=Off log_errors=On log_errors_max_len=0 html_errors=Off ignore_repeated_errors=On ignore_repeated_source=On report_memleaks=On variables_order="GPCS" request_order="GP" register_argc_argv=Off auto_globals_jit=On post_max_size=10M upload_max_filesize=10M max_file_uploads=5 auto_prepend_file= auto_append_file= default_mimetype="text/html" default_charset="UTF-8" doc_root= user_dir= extension_dir="D:\xampp\php\ext" enable_dl=Off file_uploads=On upload_tmp_dir="D:\xampp\tmp" allow_url_fopen=Off allow_url_include=Off default_socket_timeout=30 disable_functions=exec,system,passthru,shell_exec,proc_open,popen,curl_multi_exec,parse_ini_file,show_source,pcntl_exec,dl,leak,listen,chown,chgrp,chmod,apache_setenv,chdir,chroot,disk_free_space,disk_total_space,diskfreespace,getcwd,getmyuid,getmygid,getmypid,getlastmod,getrusage,phpinfo,posix_getpwuid,posix_getgrgid,posix_kill,posix_mkfifo,posix_setpgid,posix_setsid,posix_setuid,posix_setgid extension=bz2 extension=curl extension=fileinfo extension=gd extension=gettext extension=mbstring extension=exif extension=mysqli extension=openssl extension=pdo_mysql extension=pdo_sqlite asp_tags=Off track_errors=Off y2k_compliance=On allow_call_time_pass_reference=Off safe_mode=Off safe_mode_gid=Off error_log="D:\xampp\php\logs\php_error_log" register_globals=Off register_long_arrays=Off magic_quotes_gpc=Off magic_quotes_runtime=Off magic_quotes_sybase=Off [Date] date.timezone=UTC [Session] session.save_handler=files session.save_path="D:\xampp\tmp" session.use_strict_mode=1 session.use_cookies=1 session.use_only_cookies=1 session.name=PHPSESSID session.auto_start=0 session.cookie_lifetime=0 session.cookie_path=/ session.cookie_domain="localhost" session.cookie_httponly=1 session.cookie_secure=1 session.cookie_samesite="Strict" session.serialize_handler=php session.gc_probability=1 session.gc_divisor=1000 session.gc_maxlifetime=1800 session.cache_limiter="" session.use_trans_sid=0 session.sid_length=32 session.sid_bits_per_character=6 [curl] curl.cainfo="D:\xampp\apache\bin\curl-ca-bundle.crt" [openssl] openssl.cafile="D:\xampp\apache\bin\curl-ca-bundle.crt" |
Parámetros modificados/añadidos en php.ini y su finalidad técnica
| Parámetro | Valor original | Nuevo valor | Finalidad técnica |
|---|---|---|---|
expose_php | On | Off | Elimina la cabecera X-Powered-By: PHP/X.X.X en las respuestas HTTP, dificultando la fingerprinting del servidor. |
max_execution_time | 120 | 30 | Limita el tiempo máximo de ejecución de cada script. Mitiga ataques de denegación de servicio (DoS) mediante bucles infinitos o procesos largos. |
max_input_time | 60 | 20 | Restringe el tiempo de parseo de datos entrantes (POST, GET, FILES). Previene ataques de slowloris a nivel de aplicación. |
max_input_nesting_level | (sin límite) | 64 | Limita la profundidad de anidamiento en arrays de entrada ($_GET, $_POST). Previene ataques de agotamiento de pila mediante JSON/XML profundamente anidados. |
max_input_vars | (sin límite) | 1000 | Limita el número de variables de entrada por petición. Protege contra ataques de hash flooding en arrays asociativos. |
memory_limit | 512M | 128M | Restringe la memoria máxima que un script puede consumir. Mitiga ataques de tipo memory exhaustion (ej: procesamiento de imágenes gigantes). |
open_basedir | (sin definir) | D:\xampp\htdocs;D:\xampp\tmp | Restringe el acceso del sistema de archivos a los directorios especificados. Previene Local File Inclusion (LFI) y acceso a archivos sensibles del sistema. |
display_errors | On | Off | Evita que los errores PHP se muestren al cliente. Previene la fuga de información sensible (rutas, credenciales, estructura de BD). |
display_startup_errors | On | Off | Oculta errores ocurridos durante el inicio de PHP. Previene exposición de configuración interna. |
log_errors_max_len | 1024 | 0 | Establece longitud máxima del log de errores. Valor 0 sin límite para registro completo en entornos forenses. |
html_errors | On | Off | Deshabilita el formato HTML en mensajes de error. Reduce información útil para atacantes. |
ignore_repeated_errors | Off | On | No registra errores repetidos en el mismo archivo y línea. Reduce ruido en logs y evita ataques de relleno. |
post_max_size | 40M | 10M | Limita el tamaño máximo de datos POST. Protege contra ataques de DoS mediante peticiones masivas. |
upload_max_filesize | 40M | 10M | Restringe el tamaño de archivos subidos. Mitiga ataques de subida de archivos maliciosos de gran tamaño. |
max_file_uploads | 20 | 5 | Limita el número de archivos por petición. Previene DoS mediante subida masiva de archivos pequeños. |
allow_url_fopen | On | Off | Deshabilita la apertura de archivos remotos (HTTP/FTP). Previene ataques de Remote File Inclusion (RFI). |
allow_url_include | Off | Off (mantenido) | Previene inclusión remota de archivos. Crítico contra RFI. |
default_socket_timeout | 60 | 30 | Tiempo de espera para conexiones de socket. Mitiga ataques de slow reading. |
disable_functions | (vacío) | 35+ funciones | Deshabilita funciones peligrosas como exec(), system(), proc_open(), phpinfo(). Previene ejecución remota de comandos (RCE) y fuga de información. |
session.use_strict_mode | 0 | 1 | Rechaza IDs de sesión no inicializados. Previene fijación de sesión (session fixation). |
session.cookie_httponly | (vacío) | 1 | Impide acceso a la cookie de sesión desde JavaScript. Mitiga robo de sesión por XSS. |
session.cookie_secure | (vacío) | 1 | Fuerza que la cookie de sesión solo se transmita por HTTPS. Previene captura en redes no seguras. |
session.cookie_samesite | (vacío) | «Strict» | Previene envío de cookies en peticiones cross-site. Mitiga CSRF (Cross-Site Request Forgery). |
session.gc_maxlifetime | 1440 | 1800 | Tiempo de vida de sesión en segundos. Reduce ventana de ataque en sesiones inactivas. |
session.sid_length | 26 | 32 | Aumenta longitud del ID de sesión. Incrementa entropía y dificulta ataques de fuerza bruta. |
session.sid_bits_per_character | 5 | 6 | Aumenta bits por carácter en ID de sesión (0-9, a-z, A-Z, -, ,). Mejora entropía total. |
date.timezone | Europe/Berlin | UTC | Evita dependencia de zona horaria local. Mejora consistencia de logs forenses. |
zend.exception_ignore_args | Off | On | Oculta argumentos en stack traces de excepciones. Previene fuga de parámetros sensibles. |
zend.exception_string_param_max_len | 15 | 0 | Suprime completamente valores de strings en excepciones. Previene exposición de datos sensibles. |
Ejemplo de httpd.conf securizado y parámetros añadidos
httpd.conf
La descarga del fichero httpd.conf securizado de ejemplo:
El contenido del fichero httpd.conf securizado (con dos IP públicas bloqueadas, a modo de ejemplo):
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
Define SRVROOT "D:/xampp/apache" ServerRoot "D:/xampp/apache" Listen 80 LoadModule access_compat_module modules/mod_access_compat.so LoadModule actions_module modules/mod_actions.so LoadModule alias_module modules/mod_alias.so LoadModule allowmethods_module modules/mod_allowmethods.so LoadModule asis_module modules/mod_asis.so LoadModule auth_basic_module modules/mod_auth_basic.so LoadModule authn_core_module modules/mod_authn_core.so LoadModule authn_file_module modules/mod_authn_file.so LoadModule authz_core_module modules/mod_authz_core.so LoadModule authz_groupfile_module modules/mod_authz_groupfile.so LoadModule authz_host_module modules/mod_authz_host.so LoadModule authz_user_module modules/mod_authz_user.so LoadModule autoindex_module modules/mod_autoindex.so LoadModule cgi_module modules/mod_cgi.so LoadModule dav_lock_module modules/mod_dav_lock.so LoadModule dir_module modules/mod_dir.so LoadModule env_module modules/mod_env.so LoadModule headers_module modules/mod_headers.so LoadModule include_module modules/mod_include.so LoadModule log_config_module modules/mod_log_config.so LoadModule cache_disk_module modules/mod_cache_disk.so LoadModule mime_module modules/mod_mime.so LoadModule negotiation_module modules/mod_negotiation.so LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_ajp_module modules/mod_proxy_ajp.so LoadModule rewrite_module modules/mod_rewrite.so LoadModule setenvif_module modules/mod_setenvif.so LoadModule socache_shmcb_module modules/mod_socache_shmcb.so LoadModule ssl_module modules/mod_ssl.so LoadModule version_module modules/mod_version.so User daemon Group daemon ServerAdmin postmaster@localhost ServerName localhost:80 <Directory /> AllowOverride none Require all denied </Directory> DocumentRoot "D:/xampp/htdocs" <Directory "D:/xampp/htdocs"> <FilesMatch "\.(htaccess|htpasswd|ini|log|sh|sql|bak|config|json|yml|yaml)$"> Require all denied </FilesMatch> Options -Indexes +FollowSymLinks -Includes -ExecCGI AllowOverride All <IfModule rewrite_module> RewriteEngine On RewriteCond %{HTTP_USER_AGENT} (Keydrop|onlyscans|infrawatch|zgrab) [NC] RewriteRule .* - [F,L] RewriteCond %{REMOTE_ADDR} ^172\.234\.203\.40$ [OR] RewriteCond %{REMOTE_ADDR} ^193\.176\.31\.155$ RewriteRule .* - [F,L] RewriteCond %{REQUEST_URI} !^/apirestnu/ [NC] RewriteRule .* - [F,L] </IfModule> Require all granted </Directory> <IfModule dir_module> DirectoryIndex index.php index.html index.htm </IfModule> <Files ".ht*"> Require all denied </Files> ErrorLog "logs/error.log" LogLevel warn <IfModule log_config_module> LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%h %l %u %t \"%r\" %>s %b" common CustomLog "logs/access.log" combined </IfModule> <IfModule alias_module> ScriptAlias /cgi-bin/ "D:/xampp/cgi-bin/" </IfModule> <Directory "D:/xampp/cgi-bin"> AllowOverride All Options None Require all denied </Directory> <IfModule headers_module> RequestHeader unset Proxy early Header always set X-Frame-Options "SAMEORIGIN" Header always set X-Content-Type-Options "nosniff" Header always set X-XSS-Protection "1; mode=block" Header always set Referrer-Policy "strict-origin-when-cross-origin" </IfModule> <IfModule mime_module> TypesConfig conf/mime.types AddType application/x-compress .Z AddType application/x-gzip .gz .tgz </IfModule> <IfModule mime_magic_module> MIMEMagicFile "conf/magic" </IfModule> EnableMMAP off EnableSendfile off Timeout 60 KeepAlive On MaxKeepAliveRequests 100 KeepAliveTimeout 5 LimitRequestBody 10485760 <LimitExcept GET POST HEAD> Require all denied </LimitExcept> Include conf/extra/httpd-mpm.conf Include conf/extra/httpd-languages.conf Include conf/extra/httpd-vhosts.conf Include conf/extra/httpd-default.conf #Include conf/extra/httpd-info.conf #Include conf/extra/httpd-autoindex.conf <IfModule proxy_html_module> Include conf/extra/proxy-html.conf </IfModule> Include conf/extra/httpd-ssl.conf <IfModule ssl_module> SSLRandomSeed startup builtin SSLRandomSeed connect builtin </IfModule> AcceptFilter http none AcceptFilter https none ServerTokens Prod ServerSignature Off TraceEnable Off ErrorDocument 403 " " ErrorDocument 404 " " ErrorDocument 400 " " ErrorDocument 500 " " |
Parámetros modificados/añadidos en httpd.conf y su finalidad técnica
| Parámetro/Directiva | Valor original | Nuevo valor | Finalidad técnica |
|---|---|---|---|
Options | Indexes FollowSymLinks Includes ExecCGI | -Indexes +FollowSymLinks -Includes -ExecCGI | Desactiva listado de directorios (-Indexes), SSI (-Includes) y ejecución de CGI (-ExecCGI). Previene fuga de información y ejecución remota de scripts. |
ServerTokens | (no definido) | Prod | Reduce información en cabecera Server. Muestra solo «Apache», sin versión ni SO. Dificulta fingerprinting. |
ServerSignature | (no definido) | Off | Elimina firma del servidor en páginas de error. Previene fuga de información sobre versión y módulos. |
TraceEnable | (no definido) | Off | Deshabilita el método HTTP TRACE. Previene ataques de Cross-Site Tracing (XST). |
EnableMMAP | On | off | Deshabilita memory-mapping. Previene problemas con archivos en sistemas de red y evita ciertos ataques de timing. |
EnableSendfile | Off (mantenido) | off | Deshabilita sendfile syscall. Previene ataques de race condition en sistemas de archivos remotos. |
Timeout | 300 | 60 | Reduce tiempo máximo de espera por petición. Mitiga ataques Slowloris y DoS. |
KeepAliveTimeout | 5 | 5 (mantenido) | Tiempo de espera para siguiente petición en misma conexión. Balance entre rendimiento y seguridad. |
LimitRequestBody | (no definido) | 10485760 (10MB) | Limita tamaño máximo del cuerpo de petición HTTP. Previene DoS por peticiones masivas. |
LimitExcept GET POST HEAD | (no definido) | Require all denied | Bloquea métodos HTTP no estándar (PUT, DELETE, OPTIONS, TRACE). Reduce superficie de ataque. |
RewriteCond %{REQUEST_URI} | (no definido) | !^/apirestnu/ | Restringe acceso solo al directorio de la API. Bloquea sondeos automáticos a rutas sensibles (/.env, /.git/, /.well-known/). |
RewriteCond %{HTTP_USER_AGENT} | (no definido) | Bloqueo de User-Agent maliciosos | Bloquea escáneres automáticos (Keydrop, onlyscans, infrawatch). Reduce ruido en logs y consumo de recursos. |
RewriteCond %{REMOTE_ADDR} | (no definido) | Bloqueo de IPs específicas | Bloqueo a nivel de firewall virtual de IPs con comportamiento malicioso detectado. |
Header always set X-Frame-Options | (no definido) | SAMEORIGIN | Previene clickjacking. Controla que la página solo pueda ser embebida en iframes del mismo origen. |
Header always set X-Content-Type-Options | (no definido) | nosniff | Previene MIME type sniffing. Evita ejecución de scripts camuflados como otros tipos MIME. |
Header always set X-XSS-Protection | (no definido) | 1; mode=block | Activa filtro XSS del navegador. Bloquea páginas al detectar ataques cross-site scripting. |
Header always set Referrer-Policy | (no definido) | strict-origin-when-cross-origin | Controla información enviada en cabecera Referer. Previene fugas de URLs sensibles a sitios externos. |
ErrorDocument | (no definido) | " " (espacio vacío) | Sustituye páginas de error por respuesta vacía. Previene fuga de información sobre estructura del servidor. |
Directory cgi-bin | Require all granted | Require all denied | Deshabilita completamente el directorio CGI. Previene ejecución de scripts CGI maliciosos. |
#Include conf/extra/httpd-autoindex.conf | Incluido | Comentado | Desactiva módulo de listado de directorios. Previene exposición de estructura de archivos. |
#Include conf/extra/httpd-info.conf | Incluido | Comentado | Desactiva módulo de información del servidor. Previene acceso a /server-status y /server-info. |
Ejemplos de intentos de descubrir vulnerabilidades y de ataques a nuestro servidor web
Si abrimos el fichero access.log de Apache, podremos observar si hay intentos de descubrir vulnerabilidades o de ataques a nuestro servidor web, no es la mejor opción, pero de forma rápida se pueden obtener determinados comportamientos de bots y agentes atacantes.
Un ejemplo de contenido de fichero access.log:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
47.91.97.187 - - [12/Apr/2026:09:43:41 +0200] "\x16\x03\x01" 400 1 "-" "-" 47.91.97.187 - - [12/Apr/2026:09:43:41 +0200] "GET /T6bHkeeG3IixY7Bh0noD1QyFLiPlD23T05_fYYWAB0SqWLgWGk-3zAazG2k0MqhO6AxISCCvosgJ0eBTxGrQHktud-cN20EuWN5bCgJQ7zQLOPyK5jhNF7Y2p-_JSxpBpQvWHxM5plh6NA2yELiAvVST24ah1aKWBxJ3EDpy2DOgE3DO9xUsIIP6R9Vy49sZRKRZKYyU6s9Z3QCfH7jzY3ZFQsI-dvC37Aw HTTP/1.1" 403 1 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36" 78.128.112.74 - - [12/Apr/2026:09:51:35 +0200] "SSH-2.0-Go" 400 1 "-" "-" 161.35.238.241 - - [12/Apr/2026:09:52:37 +0200] "\x16\x03\x03\x01\xa8\x01" 400 1 "-" "-" 161.35.238.241 - - [12/Apr/2026:09:52:37 +0200] "\x16\x03\x03\x01\xa8\x01" 400 1 "-" "-" 161.35.238.241 - - [12/Apr/2026:09:52:37 +0200] "\x16\x03\x03\x01Y\x01" 400 1 "-" "-" 161.35.238.241 - - [12/Apr/2026:09:52:38 +0200] "\x16\x03\x03\x01K\x01" 400 1 "-" "-" 161.35.238.241 - - [12/Apr/2026:09:52:38 +0200] "\x16\x03\x03\x01\x9c\x01" 400 1 "-" "-" 161.35.238.241 - - [12/Apr/2026:09:52:38 +0200] "\x16\x03\x02\x01\x9d\x01" 400 1 "-" "-" 161.35.238.241 - - [12/Apr/2026:09:52:39 +0200] "\x16\x03\x01\x01\xaa\x01" 400 1 "-" "-" 161.35.238.241 - - [12/Apr/2026:09:52:39 +0200] "\x16\x03\x01\x01\xaa\x01" 400 1 "-" "-" 161.35.238.241 - - [12/Apr/2026:09:52:39 +0200] "\x16\x03\x01\x01\xa0\x01" 400 1 "-" "-" 161.35.238.241 - - [12/Apr/2026:09:52:40 +0200] "\x16\x03\x01\x01\xb7\x01" 400 1 "-" "-" 161.35.238.241 - - [12/Apr/2026:09:52:40 +0200] "\x16\x03\x01" 400 1 "-" "-" 161.35.238.241 - - [12/Apr/2026:09:52:40 +0200] "\x16\x03\x01" 400 1 "-" "-" 37.49.228.141 - - [12/Apr/2026:11:31:40 +0200] "GET / HTTP/1.1" 403 1 "-" "Mozilla/5.0 (Windows NT 5.1; rv:9.0.1) Gecko/20100101 Firefox/9.0.1" 37.49.228.141 - - [12/Apr/2026:11:31:40 +0200] "GET /HNAP1/ HTTP/1.1" 403 1 "http://185.227.100.171:8080/" "Mozilla/5.0 (Windows NT 5.1; rv:9.0.1) Gecko/20100101 Firefox/9.0.1" 65.49.1.212 - - [12/Apr/2026:12:12:37 +0200] "GET / HTTP/1.1" 403 1 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0" 65.49.1.216 - - [12/Apr/2026:12:17:09 +0200] "GET http://api.ipify.org/?format=json HTTP/1.1" 403 1 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/110.0" 65.49.1.219 - - [12/Apr/2026:12:17:32 +0200] "CONNECT www.shadowserver.org:443 HTTP/1.1" 403 1 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/110.0" 65.49.1.212 - - [12/Apr/2026:12:18:00 +0200] "GET /geoserver/web/ HTTP/1.1" 403 1 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/110.0" 78.128.112.74 - - [12/Apr/2026:12:30:53 +0200] "SSH-2.0-Go" 400 1 "-" "-" 95.214.53.42 - - [12/Apr/2026:13:00:42 +0200] "GET / HTTP/1.1" 403 1 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36" 45.205.1.30 - - [12/Apr/2026:13:07:34 +0200] "GET /dispatch.asp HTTP/1.1" 403 1 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36 Edg/90.0.818.46" 104.28.197.63 - - [12/Apr/2026:13:14:54 +0200] "GET /apiui/ HTTP/1.1" 403 1 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36 Edg/146.0.0.0" 104.28.197.63 - - [12/Apr/2026:13:15:54 +0200] "-" 408 - "-" "-" 45.148.10.166 - - [12/Apr/2026:13:16:40 +0200] "\x16\x03\x01\x02" 400 1 "-" "-" |
Análisis de los logs: Tipos de ataques detectados
| Entrada | Tipo de ataque | Objetivo del atacante |
|---|---|---|
"\x16\x03\x01" | TLS/SSL handshake malformado | Intentar negociar conexión HTTPS insegura o explotar vulnerabilidades en OpenSSL |
"GET /T6bHkeeG3IixY7Bh0..." (URL larga aleatoria) | Fuzzing / Path traversal | Buscar buffer overflows o inyección mediante URLs extremadamente largas |
"SSH-2.0-Go" | Escaneo de servicios | Intentar conexión SSH en puerto 80 (protocolo incorrecto) |
"GET /HNAP1/" | Escaneo de routers/iot | Buscar dispositivos Huawei/D-Link vulnerables (CVE conocidos) |
"CONNECT www.shadowserver.org:443" | Proxy abuse | Intentar usar el servidor como proxy abierto para actividades maliciosas |
"GET /geoserver/web/" | Escaneo de software específico | Buscar GeoServer vulnerable (CVE-2024-36401, RCE crítico) |
"GET /dispatch.asp" | Escaneo de aplicaciones ASP | Buscar paneles de administración expuestos |
"GET /apiui/" | Typosquatting / variantes | Intentar encontrar endpoints mal escritos de tu API |
"GET http://api.ipify.org/..." | Server-side request forgery (SSRF) | Intentar que el servidor haga peticiones a servicios externos |
"GET / HTTP/1.1" (con User-Agent sospechoso) | Escaneo de superficie | Descubrir qué servicios están expuestos |
¿Cómo saber si se están bloqueando estos ataques?
La respuesta está en el código de estado HTTP y el tamaño de la respuesta.
En los logs de access.log:

Interpretación de los códigos de respuesta:
| Código | Significado | ¿Bloqueado? |
|---|---|---|
| 200 | OK – El recurso existe | ❌ NO bloqueado (peligro si es un acceso no autorizado) |
| 403 | Forbidden – Acceso denegado | ✅ SÍ bloqueado |
| 404 | Not Found – No existe | ⚠️ Parcial (revela que no existe) |
| 400 | Bad Request – Petición malformada | ✅ SÍ bloqueado (error genérico) |
| 408 | Request Timeout | ⚠️ Neutro |
Recomendaciones adicionales para fortalecer la seguridad de un servidor web
Para entornos de producción crítica, se recomienda complementar esta configuración con:
- WAF (Web Application Firewall) como ModSecurity con reglas OWASP Core Rule Set o sistemas WAF comerciales (Sonicwall, Sophos, CheckPoint, Fortinet, etc.).
- Fail2ban para bloqueo automático de IPs maliciosas.
- HTTPS obligatorio con certificado válido (Let’s Encrypt o comercial).
- Monitorización de logs con herramientas como ELK Stack o SIEM como Splunk, QRadar.
- Actualizaciones periódicas del sistema operativo del servidor, de PHP, de Apache y sus módulos.
- Principio de mínimo privilegio en usuarios y grupos del sistema.
- Aplicar medidas de desarrollo en las API o cualquier servicio web expuesto.