La configuración de seguridad de instalación y actualización de nginx más completa de la historia

Fuente: Cuenta oficial de DevOpSec
Autor: DevOpSec

fondo

Nginx es un software de servicio de proxy de uso común. La capa de proxy suele estar relativamente cerca del usuario. La seguridad de la capa de proxy es muy importante. Necesitamos configurar y actualizar la configuración relacionada con la seguridad y actualizar la capa de proxy en nuestro diario trabajar.

Aquí elegimos implementar openrestry.OpenResty es una plataforma de desarrollo web con Nginx como núcleo, que puede analizar y ejecutar scripts de Lua, lo cual es conveniente para el desarrollo web posterior basado en nginx o WAF de desarrollo propio.

1. Descargar openrestry

Visite el sitio web oficial https://openresty.org/cn/para descargar la última versión de openrestry

cd /root/
wget https://openresty.org/download/openresty-1.21.4.1.tar.gz

2. configuración de seguridad de compilación nginx

tar xvf openresty-1.21.4.1.tar.gz
cd /root/openresty-1.21.4.1/bundle/nginx-1.21.4/

# - 1.隐藏版本
vim src/core/nginx.h
#define NGINX_VERSION      "6666"
#define NGINX_VER          "FW/" NGINX_VERSION ".6"

#define NGINX_VAR          "FW"

# - 2.修改头部
vim  src/http/ngx_http_header_filter_module.c
# 49 static u_char ngx_http_server_string[] = "Server: FW" CRLF;

# - 3.修改错误页响应头部(response header)
vim src/http/ngx_http_special_response.c
# 22 "<hr><center>FW</center>" CRLF
# ...
# 29 "<hr><center>FW</center>" CRLF
# ...
# 36 "<hr><center>FW</center>" CRLF

3. Agregar módulos tripartitos

3.1 Configuración dinámica de módulos aguas arribanginx_upstream_check_module

Mira el código de github

cd /root
git clone https://github.com/yzprofile/ngx_http_dyups_module.git

3.2 Agregar módulo de monitoreo y verificación aguas arribanginx_upstream_check_module

Mira el código de github

git clone https://github.com/yaoweibin/nginx_upstream_check_module.git

3.3 Agregar módulo de monitoreo nginxnginx-module-vts

Mira el código de github

https://github.com/vozlt/nginx-module-vts.git

4. Compilar nginx seguro

Debe parchear nginx antes de compilar, porque nginx-module-vtsel monitoreo del módulo requiere

切到nginx源码目录
cd /root/openresty-1.21.4.1/bundle/nginx-1.21.4/
打补丁
patch -p1 < /root/nginx_upstream_check_module/check_1.20.1+.patch 

compilar nginx seguro

cd /root/openresty-1.21.4.1/

./configure --prefix=/apps/nginx --with-http_realip_module  --with-http_v2_module --with-http_image_filter_module --with-http_iconv_module  --with-stream_realip_module --with-stream --with-stream_ssl_module --with-stream_geoip_module --with-http_slice_module --with-http_sub_module --add-module=/root/ngx_http_dyups_module --add-module=/root/nginx_upstream_check_module --with-http_stub_status_module --with-http_geoip_module --with-http_gzip_static_module --add-module=/root/nginx-module-vts

make

make install

Si se informa el siguiente error, verifique si el parche no se ha aplicado

/root/nginx-module-vts/src/ngx_http_vhost_traffic_status_display_json.c: In function ‘ngx_http_vhost_traffic_status_display_set_upstream_grou’:
/root/nginx-module-vts/src/ngx_http_vhost_traffic_status_display_json.c:604:61: error: ‘ngx_http_upstream_rr_peer_t’ {aka ‘struct ngx_http_upstream_rr_peer_s’} has no member named ‘check_index’; did you mean ‘checked’?
                 if (ngx_http_upstream_check_peer_down(peer->check_index)) {
                                                             ^~~~~~~~~~~
                                                             checked
make[2]: *** [objs/Makefile:3330: objs/addon/src/ngx_http_vhost_traffic_status_display_json.o] Error 1
make[2]: Leaving directory '/root/openresty-1.21.4.1/build/nginx-1.21.4'
make[1]: *** [Makefile:10: build] Error 2
make[1]: Leaving directory '/root/openresty-1.21.4.1/build/nginx-1.21.4'
make: *** [Makefile:9: all] Error 2
[[email protected] openrest

Solución:

yum install patch

cd /root/openresty-1.21.4.1/bundle/nginx-1.21.4/

patch -p1 < /root/nginx_upstream_check_module/check_1.20.1+.patch    

iniciar nginx

启动:
 /apps/nginx/nginx/sbin/nginx -c /apps/nginx/nginx/conf/nginx.conf
 
 reload:
  /apps/nginx/nginx/sbin/nginx -s reload -c /apps/nginx/nginx/conf/nginx.conf
 

5. actualización de nginx

En nuestro trabajo, encontraremos vulnerabilidades de nginx como vulnerabilidades de openssl y necesitaremos actualizar la versión de nginx, o necesitamos actualizar nginx debido a ciertas características de nginx.
Hay dos formas de actualizar (aquí estamos hablando principalmente de la implementación en la máquina virtual, y se puede volver a crear una imagen del contenedor): una es abrir
una nueva máquina virtual para actualizar directamente la versión de nginx y luego copiar el nginx configuración para comenzar.Después de verificar que no hay ningún problema, móntelo en el LB y reemplace gradualmente el antiguo nginx;
el segundo es actualizar la máquina original.Aquí hablamos principalmente sobre el segundo método.
Pasos de actualización:

前提: 
1. 有多台nginx,且从LB上摘掉一台不影响服务
2. pid路径: /data/data/nginx/conf/nginx.pid;
3. conf目录路径独立: /data/data/nginx/conf/


升级步骤:
1. 从LB上摘除要升级的nginx,观察nginx日志确保没有流量后做下一步动作
2. configure 时指定新的./configure --prefix=/apps/nginx_new 目录
3. 安装完后把nginx_new 目录下的conf 做软连指向/data/data/nginx/conf/
4. nginx reload :  /apps/nginx_new/nginx/sbin/nginx -s reload -c /data/data/nginx/conf//nginx.conf
5. 验证升级后的nginx,如果没有问题然后挂载到LB上,继续重复上述步骤完成其他nginx升级

6. configuración de seguridad nginx

6.1 Divulgación de información, desactivar la visualización del número de versión de nginx

http{
server_tokens off
....

6.2 Deshabilitar módulos Nginx innecesarios

El Nginx instalado automáticamente tendrá muchos módulos incorporados, no todos los módulos son necesarios, y los módulos no esenciales se pueden desactivar, como el módulo de autoíndice, a continuación se muestra cómo desactivar

# ./configure --without-http_autoindex_module
# make
# make install

6.3 Recursos y límites de control

Para evitar posibles ataques de DOS en Nginx, se puede establecer un límite de tamaño de búfer para todos los clientes, configurado de la siguiente manera:

## Start: Size Limits & Buffer Overflows ##
client_body_buffer_size  1K;
client_header_buffer_size 1k;
client_max_body_size 1k;
large_client_header_buffers 2 1k;
## END: Size Limits & Buffer Overflows ##

client_body_buffer_size 1k;: (predeterminado 8k o 16k) Esta instrucción puede especificar el tamaño del búfer de la entidad de solicitud de conexión. Si las solicitudes de conexión exceden el valor especificado por el caché, todas o parte de esas entidades de solicitud intentarán escribir en un archivo temporal.
client_header_buffer_size 1k;: especifica el tamaño del búfer del encabezado de solicitud del cliente. En la mayoría de los casos, un encabezado de solicitud no tendrá más de 1k, pero si hay una cookie más grande del cliente wap, puede ser más grande que 1k, Nginx le asignará un búfer más grande, este valor se puede establecer en large_client_header_buffers.
client_max_body_size 1k;: la directiva especifica el tamaño máximo de la entidad de solicitud que el cliente puede conectar, que aparece en el campo Longitud del contenido del encabezado de la solicitud. Si la solicitud es mayor que el valor especificado, el cliente recibirá un error de "Entidad de solicitud demasiado grande" (413). Recuerde, los navegadores no saben cómo mostrar este error.
large_client_header_buffers 2 1k;: especifica el número y el tamaño de los búferes utilizados por algunos encabezados de solicitud relativamente grandes en el cliente. El campo de solicitud no puede ser más grande que el tamaño de un búfer. Si el cliente envía un encabezado más grande, nginx devolverá "URI de solicitud demasiado grande" (414). Además, el campo más largo en el encabezado de la solicitud no puede ser más grande que un búfer, de lo contrario, el servidor devolverá "Solicitud incorrecta" (400). Los búferes solo se dividen cuando es necesario. El tamaño predeterminado de un búfer es el tamaño del archivo de paginación en el sistema operativo, generalmente 4 K o 8 K. Si una solicitud de conexión finalmente cambia el estado a mantener vivo, el búfer que ocupa se liberará.

También necesita controlar el tiempo de espera para mejorar el rendimiento del servidor y desconectarse del cliente, la configuración es la siguiente:

## Start: Timeouts ##
client_body_timeout   10;
client_header_timeout 10;
keepalive_timeout     5 5;
send_timeout          10;
## End: Timeouts ##

client_body_timeout 10;: la directiva especifica el tiempo de espera para leer la entidad de solicitud. El tiempo de espera aquí significa que una entidad de solicitud no ingresa al paso de lectura. Si la conexión excede este tiempo y el cliente no responde, Nginx devolverá un error de "Tiempo de espera de solicitud" (408).
client_header_timeout 10;: la directiva especifica el tiempo de espera para leer el encabezado de la solicitud del cliente. El tiempo de espera aquí significa que un encabezado de solicitud no ingresa al paso de lectura. Si la conexión excede este tiempo y el cliente no responde, Nginx devolverá un error de "Tiempo de espera de solicitud" (408).
keepalive_timeout 5 5; : el primer valor del parámetro especifica el período de tiempo de espera de la conexión larga entre el cliente y el servidor, y el servidor cerrará la conexión si se excede el tiempo de espera. El segundo valor del parámetro (opcional) especifica el valor de tiempo de Keep-Alive: timeout=time en el encabezado de respuesta.Este valor permite que algunos navegadores sepan cuándo cerrar la conexión para que el servidor no necesite cerrarla repetidamente. Si no se especifica este parámetro, nginx no enviará información de Keep-Alive en el encabezado de respuesta. (Pero esto no se refiere a cómo "Keep-Alive" una conexión) Los dos valores del parámetro pueden ser diferentes.
send_timeout 10;: especifica el período de tiempo de espera después de que se envía la respuesta al cliente. El tiempo de espera significa que no ha ingresado al estado completamente establecido y solo completó dos protocolos de enlace. Si el cliente no responde dentro de este tiempo, nginx cerrará la conexión.

6.4 Deshabilitar todos los métodos HTTP innecesarios

Deshabilite todos los métodos HTTP innecesarios. La siguiente configuración significa que solo se permiten los métodos GET, HEAD y POST, y se filtran los métodos como DELETE y TRACE.

location / {
limit_except GET HEAD POST { deny all; }
}

Otro método es configurarlo en el bloque del servidor, pero esto se configura globalmente, preste atención para evaluar el impacto.

if ($request_method !~ ^(GET|HEAD|POST)$ ) {
    return 444; }

6.5 Prevención de ataques de encabezado de host

Agregue un servidor predeterminado. Cuando el encabezado del host se modifica y no puede coincidir con el servidor, saltará al servidor predeterminado y el servidor predeterminado devolverá directamente un error 403.

server {
       listen 80 default;

       server_name _;

       location / {
            return 403;
       }
}

6.6 Configurar conjuntos de cifrado y SSL

Nginx permite el uso de protocolos SSL antiguos inseguros de forma predeterminada, ssl_protocols TLSv1 TLSv1.1 TLSv1.2, se recomienda realizar los siguientes cambios:

ssl_protocols TLSv1.2 TLSv1.3;

Además, para especificar conjuntos de cifrado, puede asegurarse de que los elementos de configuración del lado del servidor se utilicen durante el protocolo de enlace TLSv1 para mejorar la seguridad.

ssl_prefer_server_ciphers on

6.7 Evitar el hotlinking de imágenes

La vinculación activa de imágenes o HTML significa que alguien usa directamente la URL de la imagen de su sitio web para mostrarla en su sitio web. El resultado final es que debe pagar más por la banda ancha. Esto suele estar en foros y blogs. Le recomiendo encarecidamente que bloquee y evite los hotlinking.

location /images/ {
  valid_referers none blocked www.example.com example.com;
   if ($invalid_referer) {
     return   403;
   }
}

Por ejemplo: redirigir y mostrar la imagen especificada.

valid_referers blocked www.example.com example.com;
if ($invalid_referer) {
rewrite ^/images/uploads.*.(gif|jpg|jpeg|png)$ http://www.examples.com/banned.jpg last
}

6.8 Restricciones de directorio

Puede establecer permisos de acceso para directorios específicos. Todos los directorios de sitios web deben configurarse uno por uno, permitiendo solo el acceso necesario al directorio.

Puede restringir el acceso a los directorios por dirección IP

location /docs/ {
  ## block one workstation
  deny    192.168.1.1;
 
  ## allow anyone in 192.168.1.0/24
  allow   192.168.1.0/24;
 
  ## drop rest of the world
  deny    all;
}

También puede proteger directorios con contraseña
Primero cree un archivo de contraseña y agregue el usuario "usuario"

mkdir /app/nginx/nginx/conf/.htpasswd/
htpasswd -c /app/nginx/nginx/conf/.htpasswd/passwd user

Edite nginx.conf, agregue el directorio a proteger

location ~ /(personal-images/.*|delta/.*) {
  auth_basic  "Restricted";
  auth_basic_user_file   /usr/local/nginx/conf/.htpasswd/passwd;
}

Una vez que se ha generado el archivo de contraseña, también puede agregar usuarios a los que se les permite el acceso con el siguiente comando

htpasswd -s /usr/local/nginx/conf/.htpasswd/passwd userName

6.9 Denegar algunos agentes de usuario

Bloquee algunos agentes de usuario
Puede bloquear fácilmente agentes de usuario como escáneres, bots y spammers que abusan de su servidor.

## Block download agents ##
if ($http_user_agent ~* LWP::Simple|BBBike|wget) {
return 403;
}
##

6.10 nginx ir a IP de red externa

Si nginx tiene una vulnerabilidad, puede haber un comportamiento de ejecución remota. Descargue la herramienta de ataque a la máquina nginx a través de ip y use la máquina nginx como trampolín para los ataques.
Proxy nginx a través de LB, el tráfico primero pasa a través de LB y luego a nginx, no envíe nginx directamente a través de la IP de la red externa.

6.11 Configurar un encabezado de respuesta razonable

Para mejorar aún más el rendimiento de Nginx web, se pueden agregar varios encabezados de respuesta diferentes.X
-Frame-OptionsEl
encabezado de respuesta HTTP de X-Frame-Options se puede usar para indicar si se debe permitir \<frame\>que \<iframe\>muestre la página en formato o . Esto evita los ataques de clickjacking.
Añadir al archivo de configuración:

add_header X-Frame-Options "SAMEORIGIN";

Strict-Transport-Security
Seguridad estricta de transporte HTTP, conocida como HSTS. Permite un sitio web HTTPS, requiere que el navegador acceda siempre a través de HTTPS, y rechaza las solicitudes de HTTP al mismo tiempo, el funcionamiento es el siguiente:

add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload";

CSP
Content Security Policy (CSP) protege tu sitio web de ser atacado por medios como XSS, inyección SQL, etc., el funcionamiento es el siguiente:

add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;

Cuando sirva contenido proporcionado por el usuario, incluya la opción de encabezado X-Content-Type-Options: nosniff, junto con la opción de encabezado Content-Type:
para deshabilitar la detección del tipo de contenido en algunos navegadores.

add_header X-Content-Type-Options nosniff;

X-XSS-Protection: significa habilitar el filtrado XSS (deshabilitar el filtrado es X-XSS-Protection: 0), mode=block significa detener la visualización de la página si se detecta un ataque XSS

add_header X-XSS-Protection "1; mode=block";

6.12 Sitio completo https

redirigir todo http a https

server {
  listen 80 default_server;
  listen [::]:80 default_server;
  server_name .example.com;
  return 301 https://$host$request_uri;
}

6.13 Control del número de conexiones simultáneas

El número de conexiones simultáneas de una IP puede estar limitado por el módulo ngx_http_limit_conn_module

http {
    limit_conn_zone $binary_remote_addr zone=limit1:10m;

    server {
        listen 80;
        server_name example.com;
           
        root /apps/project/webapp;
        index index.html;
        location / {
            limit_conn limit 10;
        }
        access_log /data/log/nginx/nginx_access.log main;
    }
}

limit_conn_zone: establece los parámetros del espacio de memoria compartida que guarda el estado de cada clave (como binary_remoteaddr), zona = nombre del espacio: el cálculo del tamaño está relacionado con variables, como los parámetros del espacio de memoria compartida de binary_remote_addr) estado, zone=espacio nombre: tamaño Los cálculos son relativos a variables, comobinario _ _rEmoticono _ _ _ _undd r ) estado de parámetros de espacio de memoria compartida, zona n e=nombre del espacio:El cálculo del tamaño está relacionado con variables, por ejemplo, el tamaño de la variable binary_remote_addr se fija en 4 bytes para registrar direcciones IPV4, mientras que se fija en 16 bytes para registrar direcciones IPV6, el estado de almacenamiento ocupa 32 o 64 bytes en una plataforma de 32 bits, pero en una plataforma de 64 bits Ocupa 64 bytes. 1 m de espacio de memoria compartida puede guardar alrededor de 32 000 estados de 32 bits y 16 000 estados de 64 bits
limit_conn: especifique un espacio de memoria compartida que se haya establecido (por ejemplo, el espacio cuyo nombre es limit1), y cada valor de clave dado Número máximo de conexiones

El ejemplo anterior significa que solo se permiten 10 conexiones al mismo tiempo para la misma IP

Cuando se configuran varias directivas limit_conn, todos los límites de conexión tendrán efecto

http {
    limit_conn_zone $binary_remote_addr zone=limit1:10m;
    limit_conn_zone $server_name zone=limit2:10m;
    
    server {
        listen 80;
        server_name example.com;
        
        root /data/project/webapp;
        index index.html;
        
        location / {
            limit_conn limit1 10;
            limit_conn limit2 2000;
        }
    }
}

La configuración anterior no solo limitará la cantidad de conexiones desde una sola fuente de IP a 10, sino que también limitará la cantidad total de conexiones a un solo servidor virtual a 2000

6.14 Control de autoridad de conexión

De hecho, el número máximo de conexiones de nginx es el número total de procesos_trabajadores multiplicado por conexiones_trabajadores.

En otras palabras, la siguiente configuración es 4X65535. En términos generales, enfatizaremos que los procesos_trabajadores se configuran para que sean iguales a la cantidad de núcleos, y no se requiere conexiones_trabajadores. Pero al mismo tiempo, esta configuración le da espacio al atacante, que puede iniciar tantas conexiones al mismo tiempo y estropear su servidor. Por tanto, deberíamos configurar estos dos parámetros de forma más razonable.

user  www;
worker_processes  4;
error_log  /data/log/nginx/nginx_error.log  crit;
pid        /data/data/nginx/conf/nginx.pid;
events {
    use epoll;
    worker_connections 65535;
}

Sin embargo, no es completamente imposible de limitar. A partir de nginx0.7, se han lanzado dos nuevos módulos:

HttpLimitReqModul:    限制单个 IP 每秒请求数
HttpLimitZoneModule:     限制单个 IP 的连接数

Estos dos módulos deben definirse primero en la capa http y luego restringirse en el contexto de la ubicación, el servidor y http. Usan el algoritmo de depósito con fugas que restringe el acceso a una sola IP, es decir, se informarán errores 503 si el se excede el límite definido, por lo que todos los ataques de cc que estallaron fueron restringidos. Por supuesto, a veces puede haber docenas de personas que visitan el sitio web con la misma IP en una determinada empresa, que pueden lesionarse accidentalmente, y es necesario hacer un buen trabajo de devolución de llamada de error 503.

Mire HttpLimitReqModul primero:

http {
    limit_req_zone $binary_remote_addr zone=test_req:10m rate=20r/s;
     …
     server {
         …
         location /download/ {
            limit_req zone=test_req burst=5 nodelay;
         }
     }
}

La capa http anterior es la definición. Este es un espacio limit_req_zone llamado test_req, que se usa para almacenar datos de sesión. El tamaño es de 10M de memoria y 1M puede almacenar alrededor de 16,000 sesiones IP. Puede configurar tantas como desee. Con binaryremoteaddr como clave, esta definición es la IP del cliente, que se puede cambiar a binary_remote_addr como clave, esta definición es la IP del cliente, que se puede cambiar abinario _ _rEmoticono _ _ _ _undd r es clave , _Esta definición es la IP del cliente , que se puede cambiar a server_name y otros, y el número promedio de solicitudes por segundo está limitado a 20. Si se escribe como 20r/m, es por minuto y también depende de su visita. volumen _

La siguiente capa de ubicación aplica esta restricción. De acuerdo con la definición anterior, la solicitud de acceso a la carpeta de descarga está limitada a no más de 20 solicitudes por segundo para cada IP, y la cantidad de cubos de ráfaga es 5. Brust significa que si el primero , se permiten 19 solicitudes en 2, 3 y 4 segundos, y 25 solicitudes en el quinto segundo. Pero si realiza 25 solicitudes en el primer segundo y más de 20 solicitudes en el segundo segundo devuelve un error 503. nodelay, si no se establece esta opción, cuando hay 25 solicitudes en el primer segundo, se ejecutarán 5 solicitudes en el segundo segundo, si se establece nodelay, se ejecutarán 25 solicitudes en el primer segundo.

En lo que respecta a esta definición de limitación, limitar el número de solicitudes para cada IP tiene un efecto obvio en los ataques masivos de solicitudes de cc. Por ejemplo, es más obvio limitar a 1r/s una solicitud por segundo, pero como se mencionó en la Al principio, para las grandes empresas con varias personas que acceden a la misma IP al mismo tiempo, es inevitable que ocurran lesiones accidentales, por lo que se debe prestar más atención.

Luego mira HttpLimitZoneModule:

http {
    limit_conn_zone test_zone $binary_remote_addr 10m;
    server {
        location /download/ {
            limit_conn test_zone 10;
            limit_rate 500k;
        }
    }
}

Similar a lo anterior, la capa http superior es la definición general. Este es un espacio limit_conn_zone llamado test_zone, el tamaño también es 10M y la clave es la dirección IP del cliente. Sin embargo, no hay límite para la cantidad de veces, por lo que cambiar la definición de abajo.

La siguiente capa de ubicación está realmente definida, porque la definición clave es la ip del cliente, por lo que limit_conn es un límite de 10 conexiones por IP, si es $server_name, son 10 conexiones por nombre de dominio. Entonces el siguiente limit_rate es para limitar el ancho de banda de una conexión, si una ip tiene dos conexiones, es 500x2k, aquí es 10, es decir, la velocidad máxima de 5000K se le puede dar a esta ip.

6.15 Actualizaciones periódicas

Nginx en sí y la biblioteca de clases de terceros utilizada por nginx pueden tener vulnerabilidades importantes con el desarrollo de iteraciones de tiempo y tecnología. Somos responsables de los servicios relacionados con nginx y debemos prestar atención regularmente a las actualizaciones de la versión de nginx y las vulnerabilidades relacionadas, y actualizar selectivamente .

Supongo que te gusta

Origin blog.csdn.net/linuxxin/article/details/129376658
Recomendado
Clasificación