Este artículo es apto para principiantes, ya que los datos se presentan de simples a complejos. Cuando comencé mi carrera como ingeniero DevOps, carecía de esos materiales. Intentaré hablar sobre cómo funciona Nginx y algunos consejos y trucos de la experiencia práctica.
NGINX se basa en una arquitectura sin bloqueo y basada en eventos. Tiene un proceso primario, varios procesos_trabajadores y dos procesos de administración de caché. Para ver esto, solo necesita ejecutar el comando ps con los interruptores:
ps -ef --forest | grep nginx
El proceso principal se ejecuta como raíz y realiza operaciones que requieren elevación, como:
configuración de lectura;
apertura de puertos;
creación de nuevos procesos.
Los trabajadores hacen todo el trabajo:
Por lo general, la cantidad de trabajadores es igual a la cantidad de núcleos de CPU. Eso le permite usar los recursos del sistema de la manera más eficiente posible.
Worker_processes escucha en dos tipos de sockets:
Los procesos_trabajadores esperan un evento usando dos tipos de API: epoll o kqueue . Al recibir un nuevo evento de cliente en el socket de escucha, el proceso de trabajo crea una nueva conexión de socket.
Habiendo recibido un evento en el socket de conexión, el proceso_trabajador ejecuta esta solicitud. Después de procesar el evento, no se bloquea, sino que entra en modo de espera y, por lo tanto, minimiza la cantidad de cambios de contexto de un sistema operativo.
Con la arquitectura anterior, actualizar la configuración de NGINX es tan simple como enviar una señal SIGHUP al proceso principal. Con NGINX adecuadamente configurado, cada proceso de trabajo es capaz de procesar cientos de miles de conexiones al mismo tiempo.
Después de eso, los procesos_trabajadores dejarán de aceptar nuevas conexiones, y las conexiones actuales, después de haber procesado el evento, se cerrarán (sin esperar a que se mantenga vivo). Tan pronto como se cierren todas las conexiones, el proceso de trabajador finalizará. Eso le permite actualizar la configuración del servidor sin perder conexiones, recursos inactivos o interrumpir el servicio al cliente.
1. Comprobar la corrección de la configuración escrita antes de aplicarla
Después de cambiar o crear una configuración, debe verificar la sintaxis y la corrección de escribir el archivo de configuración. Nginx le permite verificar la corrección de escribir la configuración con el siguiente comando:
nginx -t
2. Vuelva a cargar Nginx sin reiniciar el servicio
Es una buena práctica aplicar la configuración sin reiniciar el servicio. Esto no termina las conexiones actuales y elimina el período de espera al cargar el servicio, es decir, no hay tiempo de inactividad:
nginx -s reload
o
/etc/init.d/nginx reload
o
service nginx reload
3. Deshabilite los tokens del servidor Nginx
De forma predeterminada, la directiva server_tokens en Nginx muestra el número de versión de Nginx. Es directamente visible en todas las páginas de error generadas automáticamente y en todas las respuestas HTTP en el encabezado del servidor.
Esto puede dar lugar a la divulgación de información: un usuario no autorizado puede conocer su versión de Nginx. Ayudaría si deshabilitara server_tokens
la directiva en el archivo de configuración de Nginx configurando:
server_tokens off;
4. Deshabilite los protocolos SSL/TLS heredados
ssl_protocols TLSv1.2 TLSv1.3;
5. Deshabilite cualquier método HTTP no deseado
Deshabilite todos los métodos HTTP que no se utilizarán y que no es necesario implementar en el servidor web.
Si agrega la siguiente condición al bloque de ubicación del archivo de configuración del host virtual de Nginx, el servidor solo permitirá los métodos GET, HEAD
y POST
y filtrará métodos como DELETE
y TRACE
:
location / { limit_except GET HEAD POST { deny all; } }
Otro enfoque es agregar la siguiente condición a la sección del servidor (o bloque del servidor). Puede considerarse más genérico, pero debe tener cuidado con las declaraciones if en el contexto de la ubicación:
if ($request_method !~ ^(GET|HEAD|POST)$ ) { return 444; }
6. Instale y configure los registros de error y acceso de Nginx
Los registros de acceso y error de Nginx están habilitados de forma predeterminada y se encuentran en logs/error.log
y logs/access.log,
respectivamente.
Puede usar la directiva error_log en el archivo de configuración de Nginx si desea cambiar la ubicación. También puede utilizar esta directiva para especificar los registros que se registrarán según su nivel de gravedad.
Por ejemplo, la gravedad crítica hará que Nginx registre problemas críticos y todos los problemas con un nivel de gravedad más alto que los críticos. Para establecer el nivel de gravedad en crítico, establezca la directiva error_log de la siguiente manera:
error_log logs/error.log crit;
Puede encontrar una lista completa de los niveles de gravedad de error_log en la documentación oficial de Nginx.
También puede cambiar la directiva access_log en el archivo de configuración de Nginx para especificar una ubicación no estándar para los registros de acceso.
Finalmente, puede usar la directiva log_format para personalizar el formato de los mensajes registrados, como se describe en la documentación de Nginx.
7. Conexiones de trabajadores Nginx
Una configuración crucial que configuramos es la cantidad de procesos de trabajo y la cantidad de conexiones de trabajo en el archivo de configuración de Nginx /etc/nginx/nginx.conf
.
Ajustaremos gradualmente el flujo de trabajo y las conexiones de los trabajadores a un valor más alto o más bajo para manejar los ataques DDoS:
events { worker_connections 20000; }
Esta configuración permite que cada proceso de trabajo maneje hasta 20 000 conexiones.
8. Límite de tasa de solicitud
Entre las muchas tácticas valiosas para prevenir ataques DDoS, una de las más simples y efectivas es limitar la tasa de tráfico entrante.
Por ejemplo, puede especificar la tasa a la que NGINX acepta solicitudes entrantes a la tasa promedio para su servicio desde una dirección IP de cliente específica durante un período específico.
Configuramos la directiva limit_req_zone en el archivo de configuración de Nginx para limitar la cantidad de solicitudes:
limit_req_zone $binary_remote_addr zone=req_per_ip:1m rate=30r/m; server { location /login { limit_req zone=req_per_ip; } }
Este ejemplo crea un área de almacenamiento llamada one que puede contener hasta 16 000 (1 m) de direcciones IP únicas, y 30 r/m significa que solo se permiten 30 solicitudes por minuto.
Luego usamos la directiva limit_req para limitar la velocidad de las conexiones a una ubicación o archivo específico, en este caso, iniciar sesión.
9. Limitar el número de conexiones
Puede limitar la cantidad de conexiones que se pueden abrir desde una sola dirección IP de cliente, y aquí estamos configurando las directivas limit_conn_zone y limit_conn
para restringir la cantidad de conexiones por dirección IP:
limit_conn_zone $binary_remote_addr zone=conn_per_ip:1m; server { location / { limit_conn conn_per_ip 10; } }
Este ejemplo crea una zona de almacenamiento denominada conn_per_ip
para almacenar solicitudes de la clave especificada, en este caso, la dirección IP del cliente, $binary_remote_addr. La directiva limit_conn
luego establece diez conexiones desde la dirección IP de cada cliente.
10. Opciones de tiempo de espera
Las conexiones lentas pueden representar un intento de mantener las conexiones abiertas durante mucho tiempo. Como resultado, el servidor no puede aceptar nuevas conexiones:
server { client_body_timeout 5s; client_header_timeout 5s; }
En este ejemplo, la directiva client_body_timeout
especifica cuánto tiempo espera Nginx entre las entradas del cuerpo del cliente y client_header_timeout
especifica cuánto tiempo espera Nginx entre las entradas del encabezado del cliente. Ambos están configurados en 5 segundos.
11. Limite el tamaño de las solicitudes
Del mismo modo, los valores de búfer grandes o los tamaños de solicitud HTTP grandes facilitan los ataques DDoS. Por lo tanto, limitamos los siguientes valores de búfer en el archivo de configuración de Nginx para mitigar los ataques DDoS:
client_body_buffer_size 200K; client_header_buffer_size 2k; client_max_body_size 200k; large_client_header_buffers 3 1k;
Dónde,
client_body_buffer_size 1k
— (predeterminado 8k o 16k) La directiva especifica el tamaño del búfer del cuerpo de la solicitud del cliente;
client_header_buffer_size 1k
: la directiva establece el tamaño del búfer del encabezado para el encabezado de solicitud del cliente. Un tamaño de búfer de 1 Kb es suficiente para la gran mayoría de las solicitudes.
Aumente este valor si tiene un encabezado personalizado o una cookie gigante enviada por un cliente (como un cliente wap);
client_max_body_size 1k
: la directiva establece el tamaño máximo permitido del cuerpo de la solicitud del cliente, especificado por la línea Content-Length en el encabezado de la solicitud.
Si el tamaño es mayor que el especificado, el cliente recibe un error de "Entidad de solicitud demasiado grande" (413). Aumente este valor cuando cargue archivos utilizando el método POST;
large_client_header_buffers 2 1k
: la directiva asigna el número y tamaño máximos de búferes para leer encabezados grandes de una solicitud de cliente.
De forma predeterminada, el tamaño de un búfer es igual al tamaño de la página según la plataforma, es 4K u 8K.
Si la conexión pasa al estado de mantenimiento al final de la solicitud de trabajo, estos búferes se liberan.
Por ejemplo, 2x1k aceptará un URI de datos de 2 KB. También ayudará a combatir los bots malos y los ataques DoS.
12. Lista negra de direcciones IP
Si puede identificar las direcciones IP del cliente utilizadas para el ataque, puede incluirlas en la lista negra con la directiva de denegación para que NGINX y NGINX Plus no acepten sus conexiones o solicitudes:
location / { deny 111.111.111.4; deny 111.111.111.0/24; }
En este ejemplo, el primer Denegar bloquea una dirección IP específica y el segundo Denegar bloquea todo el rango de direcciones IP.
13. Lista blanca de direcciones IP
Si solo se permite el acceso a su sitio web o aplicación desde uno o más conjuntos o rangos específicos de direcciones IP de clientes, puede usar las directivas allow y deny juntas para permitir que solo esas direcciones accedan al sitio o la aplicación:
location / { allow 111.111.111.4; deny all; }
Puede restringir el acceso solo a direcciones en una red local específica. Aquí, la directiva deny all bloquea todas las direcciones IP de clientes que no están en el rango especificado por la directiva allow.
14. Bloquear el acceso a un archivo o ubicación
Puede usar Nginx para bloquear completamente el acceso a un archivo o ubicación. Por ejemplo, si observa que el archivo register.php es el objetivo de un ataque, puede bloquear completamente el acceso a este archivo:
location /register { deny all; return 444; }
Eso eliminará todas las solicitudes que intenten acceder a este archivo. El código 444 cierra la conexión sin respuesta.
15. Habilite la protección basada en sysctl
Habilite la protección basada en sysctl. Podemos modificar las variables del kernel y del sistema en nuestro servidor. Edite el archivo /etc/sysctl.conf
y establezca estas dos líneas en 1 de la siguiente manera:
net.ipv4.conf.all.rp_filter = 1 net.ipv4.tcp_syncookies = 1
La primera configuración habilita la protección contra la suplantación de direcciones IP y la segunda configuración habilita la protección de cookies TCP SYN.
16. Nginx como balanceador de carga
Cuando se utiliza Nginx como equilibrador de carga, los ajustes se pueden configurar para limitar la cantidad de conexiones por servidor:
upstream domain { server 111.111.111.4:80 max_conns=100; server 111.111.111.5:80 max_conns=100; queue 20 timeout=10s; }
Aquí, la directiva max_conns especifica la cantidad de conexiones que Nginx puede abrir al servidor. La directiva de cola limita la cantidad de solicitudes en cola cuando todos los servidores de ese grupo han alcanzado el límite de conexión.
Finalmente, la directiva de tiempo de espera especifica cuánto tiempo se puede mantener una solicitud en la cola.
17. Denegar ciertos agentes de usuario
Puede bloquear fácilmente los agentes de usuario, es decir, rastreadores, bots y spammers que podrían estar abusando de su servidor:
## Block download agents ## if ($http_user_agent ~* LWP::Simple|BBBike|wget) { return 403; }
## Block some robots ## if ($http_user_agent ~* msnbot|scrapbot|PxBroker) { return 403; }
18. Bloquear el spam de referencia
El spam de referencia es peligroso. Eso puede dañar su ranking de SEO a través de weblogs (si se publican) ya que el campo de referencia se vincula a su sitio de spam. Con estas líneas, puede bloquear el acceso a los remitentes de spam:
if ( $http_referer ~* (babes|forsale|girl|jewelry|love|nudit|organic|poker|porn|sex|teen) ) { return 403; }
19. Detener el hotlinking de imágenes
Un enlace de imagen o HTML significa que alguien vincula su sitio a una de sus imágenes pero la muestra en su sitio.
Terminará pagando por el ancho de banda y haciendo que el contenido parezca parte de un sitio. Esto generalmente se hace en foros y blogs. Recomiendo encarecidamente que bloquee y detenga la vinculación de imágenes en el mismo nivel de su servidor:
location /images/ { valid_referers none blocked www.domain.com domain.com; if ($invalid_referer) { return 403; } }
20. Limita el número de conexiones por dirección IP a nivel de firewall
El servidor web debe monitorear las conexiones y limitar el número de conexiones por segundo. Esto sirve 101. Tanto pf como iptables pueden bloquear a los usuarios finales antes de acceder a su servidor Nginx.
Linux Iptables: limitación de conexiones Nginx por segundo.
En el siguiente ejemplo, las conexiones entrantes se eliminarán si la IP realiza más de 15 intentos de conexión en el puerto 80 en 60 segundos:
/sbin/iptables -A INPUT -p tcp --dport 80 -i eth0 -m state --state NEW -m recent --set && \ /sbin/iptables -A INPUT -p tcp --dport 80 -i eth0 -m state --state NEW -m recent --update --seconds 60 --hitcount 15 -j DROP && \ service iptables save
21. Deshabilite la detección de tipo de contenido en algunos navegadores
Si una respuesta especifica un tipo de contenido incorrecto, los navegadores pueden procesar la respuesta de formas inesperadas.
Si se determina que el tipo de contenido es un formato basado en texto procesable, entonces el navegador generalmente intentará interpretar la respuesta como si estuviera en ese formato, independientemente del contenido real de la respuesta.
Además, algunos otros tipos de contenido especificados a veces pueden interpretarse como HTML debido a peculiaridades en navegadores particulares. Esto podría llevar a contenido "seguro", como imágenes que se procesan como HTML, lo que permite ataques de secuencias de comandos entre sitios en ciertas condiciones. Agregue lo siguiente a su configuración:
add_header X-Content-Type-Options nosniff;
22. Habilite el filtro de secuencias de comandos entre sitios (XSS)
Agregue la siguiente línea a su archivo de configuración para habilitar el encabezado X-XSS-Protection en su servidor web Nginx. Cuando haya terminado, guarde los cambios y vuelva a cargar Nginx:
add_header X-XSS-Protection "1; mode=block";
23. Configurar soporte HTTP/2
HTTP/2 es el sucesor del protocolo de red HTTP 1.x. HTTP/2 se usa ampliamente para reducir la latencia, minimizar la sobrecarga del protocolo, agregar soporte para la priorización de solicitudes y acelerar la carga de aplicaciones web.
Por lo tanto, es vital mantenerse actualizado con las técnicas y estrategias de optimización del rendimiento. El objetivo principal de HTTP/2 es reducir el tiempo de carga general de una página web, lo que optimiza el rendimiento.
También se enfoca en el uso de los recursos de la red y del servidor, así como en una mayor seguridad, ya que el cifrado SSL/TLS es obligatorio cuando se usa HTTP/2.
Como requisito previo, asegúrese de que la versión de Nginx sea 1.9.5 o superior a medida que se crea; de lo contrario, deberá agregarla manualmente y el servidor debe habilitar SSL/TLS. Su bloque de servidor HTTPS ahora debería verse así:
server { listen 443 ssl http2; ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5; }
24. Agregar política de seguridad de contenido (CSP)
CSP es una capa adicional de seguridad que ayuda a detectar y mitigar ciertos tipos de ataques, incluidos los ataques de secuencias de comandos entre sitios (XSS) y de inyección de datos. Estos ataques se utilizan para el robo de datos, la corrupción de sitios web y la distribución de malware:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
25. Monitoreo de Nginx
El estado de su servidor debe ser monitoreado constantemente. Puede ver lo que devuelve el servidor enviándole solicitudes periódicamente, por ejemplo, a través de servicios pagos de terceros. O puede ajustarlo todo, y hay muchas maneras de hacerlo; más información al respecto en el blog de Nginx .
En lugar de conclusión
Es fundamental ser flexible y desarrollar una configuración para cada caso por separado.