Cómo denegar el acceso a recursos basados ​​en encabezados X-reenviados

13

Estoy tratando de restringir el acceso a los recursos detrás de Nginx en función de la IP del cliente aprobada en encabezados X-reenviados. Nginx se ejecuta en un contenedor en un clúster de Kubernetes en Google Cloud Platform y los ips reales del cliente se pasan solo en el encabezado x-forward-for

Hasta ahora he logrado hacerlo para una sola IP con el siguiente código:

set $allow false;
if ($http_x_forwarded_for ~* 123.233.233.123) {
    set $allow true;
}
if ($http_x_forward_for ~* 10.20.30.40) {
    set $allow false;
}
if ($allow = false) {
    return 403;
}

Pero, ¿cómo puedo hacer eso para rangos completos de IP? Especificar cientos de IP a mano no tiene mucho sentido.

Toda ayuda es apreciada

p1hr
fuente

Respuestas:

11

Use el módulo RealIP para honrar el valor del X-Forwarded-Forencabezado. Establezca set_real_ip_fromla dirección IP del proxy inverso (el valor actual de $remote_addr).

Por ejemplo:

server {
    ...
    real_ip_header X-Forwarded-For;
    set_real_ip_from 10.1.2.3;
    ...
}

Ahora debería poder usar $remote_addry allow/ o denydirectivas usando la verdadera dirección IP del cliente. Vea este documento para más información.

Richard Smith
fuente
así que intenté lo siguiente en vano, ¿lo estoy confundiendo? location / { real_ip_header X-Forwarded-For; set_real_ip_from 10.0.0.0/8; real_ip_recursive on; allow xxx.xxx.xxx.xxx;
p1hr
Después de mirar los documentos de Google Load Balancing, encontré lo siguiente: X-Forwarded-For: <unverified IP(s)>, <immediate client IP>, <global forwarding rule external IP>, <proxies running in GCP> (requests only) La entrada <IP del cliente inmediato> es el cliente que se conectó directamente al equilibrador de carga.
p1hr
1
Para que esto funcione, es necesario identificar los rangos de direcciones de <global forwarding rule external IP>e <proxies running in GCP>y añadir set_real_ip_fromdeclaraciones que cubren todos ellos.
Richard Smith
<global forwarding rule external IP>es la ip externa de mi servicio, no hay otros proxies en GCP, en mis registros nginx veo solicitudes en el siguiente formato [31/Jul/2017:20:05:46 +0000] "GET / HTTP/1.1" 403 169 "-" "curl/7.54.0" "aaa.aaa.aaa.aaa, bbb.bbb.bbb.bbb, ccc.ccc.ccc.ccc"donde ccc.ccc.ccc.ccc es la regla de reenvío global, bbb.bbb.bbb.bbb es un cliente inmediato ip: coincide con lo que veo en whatsmyip.org. ¿Alguna posibilidad de que pueda aconsejar cómo extraer esa parte?
p1hr
1
Ok, ahora me estoy confundiendo. Necesita set_real_ip_fromtodas las direcciones a la derecha de la que desea permitir / denegar. Como se indica en la real_ip_recursivesección.
Richard Smith
5

La respuesta de Richard ya contenía la información sobre cómo obtener la mejor dirección IP real para nginx.

Mientras tanto, en lo que respecta a la especificación de rangos de IP, puede usar http://nginx.org/en/docs/http/ngx_http_geo_module.html .

El geomódulo funciona como el mapmódulo, es decir, una variable obtiene valores asignados según el valor de la dirección IP.

Un ejemplo:

geo $allow {
    default 0;
    192.168.168.0/24 1;
}

server {
    real_ip_header X-Forwarded-For;
    set_real_ip_from 10.1.2.3;

    if ($allow = 0) {
        return 403;
    }
}

Aquí asignamos el geomapa, donde el valor predeterminado $allowes 0. Si la dirección IP está en la subred 192.168.168.0/24, $allowobtendrá el valor 1 y se permitirá la solicitud.

Puede tener tantas líneas en el geobloque como necesite para definir sus rangos de IP.

Tero Kilkanen
fuente
¡Gracias! parece funcionar muy bien, la última cosa que enfrento es que client_ip de X-forward-for. Por el momento, de 3 direcciones IP que se pasan, se utiliza la última. He agregado a real_ip_recursive on;continuación, set_real_ip_frompero no ha hecho ninguna diferencia
p1hr
¿Quiere decir que su X-Forwarded-Forencabezado tiene tres direcciones separadas, es decir, la solicitud se realiza a través de múltiples servidores proxy? ¿Tiene algún otro encabezado que pueda usar, que contenga solo la IP del cliente?
Tero Kilkanen
Cada proxy en la cadena agregará su dirección IP al X-Forwarded-Forencabezado. Además de agregar real_ip_recursive on, también debe agregar set_real_ip_fromdirectivas para cada dirección IP de servidor de confianza en su cadena de proxy. Nginx luego trabajará a través de cada una de estas directivas y devolverá la IP del cliente como el primer valor que alcanza en el X-Forwarded-Forencabezado que no coincide con ninguno de sus set_real_ip_fromvalores especificados
miknik
FWIW, esta combinación no funcionó para mí con AWS ALB. Lo que sí funcionó fue usar la directiva proxy dentro del bloque geográfico, con la misma ip que set_real_ip - nginx.org/en/docs/http/ngx_http_geo_module.html
talonx
3

Tengo estos trabajando para mí.

geo $remote_addr $giveaccess {
      proxy 172.0.0.0/8; <-- Private IP range here
      default 0;
      11.22.33.44 1; <-- Allowed IP here
    }


server{
##
    location ^~ /secure_url_here {
        if ($giveaccess = 0){
          return 403; 
        }
        try_files $uri $uri/ /index.php?$args; <-- Add this line specific for your CMS, if required.
    }

Ref: http://nginx.org/en/docs/http/ngx_http_geo_module.html

Seff
fuente