En este tutorial, veremos cómo podemos configurar el servidor web Nginx para un entorno de producción
Un servidor web en un entorno de producción es diferente de un servidor web en un entorno de pruebas en términos de rendimiento, seguridad, etc.
Por defecto, siempre hay una configuración lista para usar para un servidor web Nginx una vez que lo ha instalado correctamente. Sin embargo, la configuración por defecto no es lo suficientemente buena para un entorno de producción. Por lo tanto, nos centraremos en cómo configurar Nginx para que funcione mejor durante los picos de tráfico normal y pesado, y cómo protegerlo de los usuarios que pretendan abusar de él
Si no ha instalado Nginx en su máquina, puede consultar cómo hacerlo aquí. Le mostramos cómo instalar Nginx en una plataforma Unix. Elija instalar Nginx a través de los archivos fuente porque los Nginx preconstruidos no vienen con algunos de los módulos utilizados en este tutorial
Requisitos
Necesita tener lo siguiente instalado en su máquina y asegúrese de ejecutar este tutorial en cualquier plataforma basada en Debian como Ubuntu
- Ubuntu o cualquier otra plataforma basada en Debian
- wget
- Vim (editor de texto)
Además, necesita ejecutar o ejecutar algunos comandos en este tutorial como usuario root a través del comando sudo
Comprender la estructura de configuración de Nginx
En esta sección veremos lo siguiente
- Estructura de Nginx
- Secciones como evento, HTTP y correo
- Sintaxis válida de Nginx
Al final de esta sección, comprenderá la estructura de la configuración de Nginx, el propósito o las funciones de las secciones, así como la forma de definir directivas válidas dentro de las secciones
El archivo de configuración completo de Nginx tiene una estructura lógica que se compone de directivas agrupadas en una serie de secciones como la sección de eventos
, la sección http
, la sección de correo
etc.
El archivo de configuración principal se encuentra en /etc/nginx/nginx.conf
mientras que los demás archivos de configuración se encuentran en /etc/nginx
Contexto principal
Esta sección o contexto contiene directrices fuera de secciones específicas como la sección de correo
Cualquier otra directiva como user nginx;
, worker_processes
1 ;
, error_log /var/log/nginx/error.log warn;
y pid /var/run/nginx.
pid puede colocarse dentro de la sección o contexto principal
Pero algunas de estas directivas como worker_processes
también pueden existir en la sección de eventos
Secciones
Las secciones en Nginx definen la configuración para los módulos Nginx
Por ejemplo, la sección http
defina la configuración para el módulo ngx_http_core
, la sección
event define la configuración para el módulo ngx_event_module
mientras que la sección mail define la configuración para el módulo ngx_mail_module
Puede consultar aquí la lista completa de secciones de Nginx
Directivas
Las directivas en Nginx se componen de un nombre de variable y un número de argumentos como los siguientes
Worker_processes
es un nombre de variable mientras que auto
sirve como argumento
worker_processes auto
Las directivas terminan con un punto y coma como se muestra arriba
Por último, el archivo de configuración de Nginx debe atenerse a un conjunto particular de reglas. A continuación se muestra la sintaxis válida de la configuración de Nginx
- Las directivas válidas comienzan con un nombre de variable seguido de uno o más argumentos
- Todas las directivas válidas terminan con un punto y coma
;
- Las secciones se definen con llaves
{}
- Una sección puede estar incrustada en otra sección
- La configuración fuera de cualquier sección forma parte de la configuración global de Nginx.
- Las líneas que comienzan con el signo de almohadilla
#
son comentarios.
Ajuste del rendimiento de Nginx
En esta sección, configuraremos Nginx para que funcione mejor durante tráfico pesado y picos de tráfico
Veamos cómo configurar
- Trabajadores
- Actividad de E/S de disco
- Actividad de red
- Búferes
- Compresión
- Almacenamiento en caché
- Tiempo de espera
Aún así, dentro del entorno virtual activado, escriba los siguientes comandos para cambiar al directorio Nginx y listar su contenido
cd nginx && ls
Busque la carpeta conf
. Dentro de esta carpeta se encuentra el archivo nginx.conf
Haremos uso de este archivo para configurar Nginx
Ahora ejecute los siguientes comandos para navegar hasta la carpeta conf
y abra el archivo nginx
.conf con el <a href="https://geekflare.com/es/best-vim-editors/">editor v</a>
im
cd conf
sudo vim nginx.conf
A continuación se muestra una captura de pantalla del aspecto predeterminado del archivo nginx .conf
Trabajadores
Para que Nginx funcione mejor, necesitamos configurar trabajadores
en la sección de eventos. Configurar los workers de Nginx le permite procesar las conexiones de los clientes de forma eficaz
Suponiendo que no haya cerrado el editor vim, pulse el botón i
del teclado para editar el archivo nginx.conf
Copie y pegue lo siguiente dentro de la sección
de eventos como se muestra a continuación
events {
worker_processes auto;
worker_connections 1024;
worker_rlimit_nofile 20960;
multi_accept on;
mutex_accept on;
mutex_accept_delay 500ms;
use epoll;
epoll_events 512;
}
worker_processes
: Esta directiva controla el número de trabajadores en Nginx. El valor de esta directiva se establece en auto
para permitir que Nginx determine el número de núcleos disponibles, discos, carga del servidor y subsistema de red. Sin embargo, puede descubrir el número de núcleos ejecutando el comando lscpu
en la terminal
worker_connections
: Esta directiva establece el valor del número de conexiones simultáneas que puede abrir un trabajador. El valor por defecto es 512
, pero nosotros lo fijamos en 1.024
para permitir que un trabajador acepte muchas conexiones simultáneas de un cliente
worker_rlimit_nofile:
Esta directiva está relacionada de algún modo con worker_connections
. Para poder manejar conexiones simultáneas grandes, la fijamos en un valor grande
multi_accept:
Esta directiva permite a un trabajador aceptar muchas conexiones en la cola a la vez. Una cola en este contexto significa simplemente una secuencia de objetos de datos a la espera de ser procesados
mutex_accept:
Esta directiva está desactivada por defecto. Pero como hemos configurado muchos trabajadores en Nginx, necesitamos activarla como se muestra en el código anterior para permitir a los trabajadores aceptar nuevas conexiones una a una
mutex_accept_delay:
Esta directiva determina cuánto tiempo debe esperar un trabajador antes de aceptar una nueva conexión. Una vez activada accept_mutex
, se asigna un bloqueo mutex a un trabajador durante un plazo de tiempo especificado por accept_mutex_delay
. Cuando se agota el plazo, el siguiente trabajador en la cola está listo para aceptar nuevas conexiones
use:
Esta directiva especifica el método para procesar una conexión desde el cliente. En este tutorial, decidimos establecer el valor epoll
porque estamos trabajando en una plataforma Ubuntu
. El método epoll
es el método de procesamiento más eficaz para las plataformas Linux
epoll_events:
El valor de esta directiva especifica el número de eventos que Nginx transferirá al núcleo
E/S de disco
En esta sección, configuraremos la actividad de E/S asíncrona en Nginx para permitirle realizar una transferencia de datos eficaz y mejorar la eficacia de la caché
La E/S de disco se refiere simplemente a las operaciones de escritura y lectura entre el disco duro y la RAM. Haremos uso de la función <a href="https://linux.die.net/man/2/sendfile">sendfile(</a>)
dentro del núcleo para enviar archivos pequeños
Puede hacer uso de la sección http
, la sección
ubicación y la sección
servidor para directivas en esta área
La sección de ubicación
, la sección de
servidor pueden estar incrustadas o colocadas dentro de la sección http
para hacer legible la configuración
Copie y pegue el siguiente código dentro de la sección location incrustada dentro de la sección HTTP
location /pdf/ {
sendfile on;
aio on;
}
location
/audio/ {
directio 4m
directio_alignment 512
}
sendfile:
Para utilizar los recursos del sistema operativo, establezca el valor de esta directiva en on
. sendfile transfiere datos entre descriptores de archivo dentro del espacio del núcleo del sistema operativo sin enviarlos a los búferes de la aplicación. Esta directiva se utilizará para servir archivos pequeños
directio:
Esta directiva mejora la eficacia de la caché al permitir que la lectura y la escritura se envíen directamente a la aplicación. directio
es una característica del sistema de archivos de todos los sistemas operativos modernos. Esta directiva se utilizará para servir archivos de mayor tamaño, como vídeos
aio:
Esta directiva habilita el multi-threading cuando se establece en on
para las operaciones de escritura y lectura. El multihilo es un modelo de ejecución que permite que varios hilos se ejecuten por separado unos de otros mientras comparten los recursos de su proceso anfitrión.
directio_alignment:
Esta directiva asigna un valor de tamaño de bloque a la transferencia de datos. Está relacionada con la directiva directio
Capa de red
En esta sección, haremos uso de directivas como tcp_nodelay
y tcp_nopush
para evitar que los paquetes pequeños esperen un tiempo determinado de unos 200 milisegundos antes de ser enviados a la vez
Normalmente, cuando los paquetes se transfieren en "trozos", tienden a saturar una red muy cargada. Así que John Nagle construyó un algoritmo de almacenamiento en búfer para resolver este problema. El propósito del algoritmo de almacenamiento en búfer de Nagle es evitar que los paquetes pequeños saturen la red altamente cargada
Copie y pegue el siguiente código dentro de la sección HTTP
http {
tcp_nopush on;
tcp_nodelay on;
}
tcp_nodelay:
Esta directiva, por defecto, está desactivada para permitir que los paquetes pequeños esperen un tiempo determinado antes de ser enviados a la vez. Para permitir que todos los datos se envíen a la vez, esta directiva está habilitada
tcp_nopush:
Como hemos habilitado la directiva tcp_nodelay
, los paquetes pequeños se envían a la vez. Sin embargo, si aún desea hacer uso del algoritmo de almacenamiento en búfer de John Nagle, también podemos habilitar tcp_nopush
para añadir paquetes entre sí y enviarlos todos a la vez
Búferes
Echemos un vistazo a cómo configurar los búferes de peticiones en Nginx para gestionar las peticiones de forma eficaz. Un búfer es un almacenamiento temporal donde se guardan los datos durante algún tiempo y se procesan
Puede copiar lo siguiente en la sección del servidor
servidor
{
client_body_buffer_size 8k;
client_max_body_size 2m;
client_body_in_single_buffer on;
client_body_temp_pathtemp_files 1 2;
client_header_buffer_size 1m;
large_client_header_buffers 4 8k;
}
Es importante entender lo que hacen esas líneas de búfer
client_body_buffer_size:
Esta directiva establece el tamaño del búfer para el cuerpo de la petición. Si planea ejecutar el servidor web en sistemas de 64 bits, debe establecer el valor en 16k. Si desea ejecutar el servidor web en el sistema de 32 bits, establezca el valor en 8k
client_max_body_size:
Si pretende manejar cargas de archivos de gran tamaño, necesita establecer esta directiva en al menos 2m
o más. Por defecto, está fijada en 1m
client_body_in_file_only
: Si ha desactivado la directiva client_body_buffer_size
con el símbolo hashtag #
y esta directiva client_body_in_file_only
está establecida, Nginx guardará los buffers de petición en un archivo temporal. Esto no es recomendable para un entorno de producción
client_body_in_single_buffer:
A veces no todo el cuerpo de la petición se guarda en un buffer. El resto se guarda o se escribe en un archivo temporal. Sin embargo, si tiene intención de guardar o almacenar todo el cuerpo de la solicitud en un único búfer, deberá activar esta directiva
client_header_buffer_size:
Puede utilizar esta directiva para establecer o asignar un búfer para las cabeceras de las peticiones. Puede fijar este valor en 1m
large_client_header_buffers:
Esta directiva se utiliza para establecer el número y tamaño máximos para la lectura de cabeceras de petición grandes. Puede fijar el número máximo y el tamaño del búfer en 4
y 8k
exactamente
Compresión
Comprimir la cantidad de datos transferidos a través de la red es otra forma de garantizar un mejor rendimiento de su servidor web. En esta sección, haremos uso de directivas como gzip
, gzip_comp_level
y gzip_min_length
para comprimir datos
Pegue el siguiente código dentro de la sección http
como se muestra a continuación
http {
gzip on;
gzip_comp_level 2;
gzip_min_length 1000;
gzip_types text/xml text/css;
gzip_http_version 1.1;
gzip_vary on;
gzip_disable "MSIE [4-6] \.";
}
gzip:
Si desea activar la compresión, establezca el valor de esta directiva en on
. Por defecto, está desactivada
gzip_comp_level:
Puede utilizar esta directiva para establecer el nivel de compresión. Para no malgastar recursos de la CPU, no debe fijar un nivel de compresión demasiado alto. Entre 1
y 9
, puede fijar el nivel de compresión en 2
ó 3
gzip_min_length:
Establezca la longitud mínima de la respuesta para la compresión a través del campo de cabecera de respuesta content-length
. Puede fijarla en más de 20 bytes
gzip_types:
Esta directiva le permite elegir el tipo de respuesta que desea comprimir. Por defecto, siempre se compra el tipo de respuesta text/html
. Puede añadir otro tipo de respuesta, como text/css
como se muestra en el código anterior
gzip_http_version:
Esta directiva le permite elegir la versión HTTP mínima de una solicitud para una respuesta comprimida. Puede utilizar el valor por defecto que es 1.1
gzip_vary:
Cuando la directiva gzip
está activada, esta directiva añade el campo de cabecera Vary:Accept Encoding
a la respuesta
gzip_disabled:
Algunos navegadores como Internet Explorer 6
no son compatibles con la compresión gzip
. Esta directiva hace uso del campo de cabecera de petición User-Agent
para desactivar la compresión en determinados navegadores
Almacenamiento en caché
Aproveche las funciones de almacenamiento en caché para reducir el número de veces que debe cargar los mismos datos varias veces. Nginx proporciona características para almacenar en caché metadatos de contenido estático a través de la directiva open_file_cache
Puede colocar esta directiva dentro de la sección server
, location
y http
http {
open_file_cache max=1,000 inactive=30s;
open_file_cache_valid 30s;
open_file_cache_min_uses 4;
open_file_cache_errors on;
}
open_file_cache:
Esta directiva está desactivada por defecto. Habilítela si desea implementar el almacenamiento en caché en Nginx. Esta directiva almacena metadatos de archivos y directorios solicitados habitualmente por los usuarios
open_file_cache_valid:
Esta directiva contiene información de respaldo dentro de la directiva open_file_cache
. Puede utilizar esta directiva para establecer un periodo válido, normalmente en segundos, tras el cual la información relativa a los archivos y directorios se vuelve a validar de nuevo.
open_file_cache_min_uses:
Nginx suele borrar la información dentro de la directiva open_file_cache
tras un periodo de inactividad basado en el valor de open_file_cache_min_uses
. Puede utilizar esta directiva para establecer un número mínimo de accesos para identificar a qué archivos y directorios se accede activamente
open_file_cache_errors:
Puede hacer uso de esta directiva para permitir que Nginx almacene en caché errores como "permiso denegado" o "no se puede acceder a este archivo" cuando se accede a los archivos. De este modo, cada vez que un usuario que no tiene derecho a acceder a un recurso, Nginx muestra el mismo informe de error "permiso denegado".
Tiempo de espera
Configure el tiempo de espera utilizando directivas como keepalive_timeout
y keepalive_requests
para evitar que las conexiones en espera prolongada malgasten recursos
En la sección HTTP, copie y pegue el siguiente código
http {
keepalive_timeout 30s;
keepalive_requests 30;
send_timeout 30s;
}
keepalive_timeout
: Mantiene vivas las conexiones durante unos 30 segundos. El valor predeterminado es 75 segundos
keepalive_requests
: Configure un número de peticiones para mantener viva la conexión durante un periodo de tiempo específico. Puede configurar el número de peticiones en 20 ó 30
keepalive_disable
: si desea desactivar la conexión keepalive para un grupo específico de navegadores, utilice esta directiva
send_timeout
: Establezca un tiempo de espera para transmitir datos al cliente
Configuración de seguridad para Nginx
A continuación nos centraremos únicamente en cómo configurar de forma segura un Nginx en lugar de una aplicación web. Por lo tanto no miraremos los ataques basados en web como la inyección SQL y demás
En esta sección veremos cómo configurar lo siguiente
- Restringir el acceso a archivos y directorios
- Configurar registros para monitorizar actividades maliciosas
- Prevenir DDoS
- Desactivar el listado de directorios
Restringir el acceso a archivos y directorios
Veamos cómo restringir el acceso a archivos y directorios sensibles mediante los siguientes métodos
Haciendo uso de la autenticación HTTP
Podemos restringir el acceso a archivos sensibles o a áreas no destinadas a ser vistas por el público solicitando autenticación a los usuarios o incluso a los administradores. Ejecute el siguiente comando para instalar una utilidad de creación de archivos de contraseñas si no la tiene instalada
apt-get install -y apache-utils
A continuación, cree un archivo de contraseñas y un usuario utilizando la herramienta htpasswd
como se muestra a continuación. La herramienta htpasswd
es proporcionada por la utilidad apache2-utils
sudo htpasswd -c /etc/apache2/ .htpasswd mike
Puede confirmar si ha creado correctamente un usuario y una contraseña aleatorios mediante el siguiente comando
cat
etc/apache2/ .htpasswd
Dentro de la sección location, puede pegar el siguiente código para solicitar a los usuarios que se autentiquen utilizando la directiva auth_basic
location /admin {
basic_auth "Área Admin";
auth_basic_user_file /etc/apache2/ .htpasswd;
}
Haciendo uso de la directiva Permitir
Además de la directiva basic_auth
podemos hacer uso de la directiva allow
para restringir el acceso
Dentro de la sección location, puede utilizar el siguiente código para permitir que las direcciones IP especificadas accedan al área sensible
location /admin {
allow 192.168.34.12;
allow 192.168.12.34;
}
Configure los registros para supervisar las actividades maliciosas
En esta sección, configuraremos los registros de errores
y de acceso
para supervisar específicamente las solicitudes válidas e inválidas. Puede examinar estos registros para averiguar quién se conectó en un momento determinado, o qué usuario accedió a un archivo concreto, etc.
error_log:
Le permite configurar el registro en un archivo concreto, como syslog
o stderr
. También puede especificar el nivel de los mensajes de error que desea registrar
access_log:
Permite escribir las peticiones de los usuarios en el archivo access.
Registrar
Dentro de la sección HTTP, puede utilizar lo siguiente
http {
access_log logs/access.log combinado;
error_log logs/warn.log warn;
}
Prevenir DDOS
Puede proteger el Nginx de un ataque DDOS mediante los siguientes métodos
Limitando las peticiones de los usuarios
Puede hacer uso de las directivas limit_req_zone
y limit_req
para limitar la tasa de peticiones enviadas por los usuarios en minutos
Añada el siguiente código en la sección de ubicación
incrustada en la sección del servidor
limit_req_zone $binary_remote_addr zone=one:10m rate=30r/m;
server {
location /admin.html {
limit_req zone=one;
}
}
Limitar el número de conexiones
Puede hacer uso de las directivas limit_conn
y limit_conn_zone
para limitar la conexión a determinadas ubicaciones o zonas. Por ejemplo, el código siguiente recibe 15 conexiones de clientes durante un periodo determinado
El código siguiente irá a la sección de ubicaciones
limit_conn_zone
$binary_remote_addr zone=addr:10m;
server {
location /products/ {
limit_conn addr 10;
}
}
Finalizar conexiones lentas
Puede hacer uso de directivas de tiempo de espera como client_body_timeout
y client_header_timeout
para controlar cuánto tiempo esperará Nginx las escrituras del cuerpo del cliente
y de la cabecera del cliente
Añada lo siguiente dentro de la sección del servidor
server {
client_body_timeout 5s;
client_header_timeout 5s;
}
También sería una buena idea detener los ataques DDoS en el borde aprovechando las soluciones basadas en la nube como se menciona aquí
Desactivar el listado de directorios
Puede hacer uso de la directiva auto_index
para evitar el listado de directorios como se muestra en el siguiente código. Debe establecerla en el valor off
para desactivar el listado de directorios
location / {
auto_index off;
}
Conclusión
Hemos configurado el servidor web Nginx para que funcione eficazmente y protegerlo de un abuso excesivo en un entorno de producción. Si utiliza Nginx para aplicaciones web orientadas a Internet, debería considerar también el uso de una CDN y de seguridad basada en la nube para mejorar el rendimiento y la seguridad.