Pregunta Cómo denegar el acceso a recursos basados ​​en encabezados X-forwarded-for


Estoy tratando de restringir el acceso a los recursos detrás de Nginx basado en la IP del cliente que se pasa en los encabezados X-forwarded-for. Nginx se está ejecutando en un contenedor en un grupo de Kubernetes en Google Cloud Platform y los ips reales del cliente se pasan solo en el encabezado reenviado por x

Hasta ahora he logrado hacerlo para una única 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 enteros de IPs? Especificar cientos de IP a mano no tiene mucho sentido.

Toda la ayuda es apreciada.


9
2017-07-31 15:53


origen




Respuestas:


Utilice el módulo RealIP para honrar el valor de la X-Forwarded-For encabezamiento. Conjunto set_real_ip_from a la 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ías poder usar $remote_addr y allow/deny Directivas utilizando la verdadera dirección IP del cliente. Ver este documento para más.


7
2017-07-31 16:41



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 ver 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 inmediata del cliente> es el cliente que se conectó directamente al equilibrador de carga. - p1hr
Para que esto funcione, necesita identificar los rangos de direcciones para <global forwarding rule external IP> y <proxies running in GCP> y añadir set_real_ip_from Declaraciones que cubren todos ellos. - Richard Smith
<global forwarding rule external IP> es la dirección IP externa de mi servicio, no hay otros proxies en GCP, en mis registros de 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 una regla de reenvío global, bbb.bbb.bbb.bbb una ip de cliente inmediata: coincide con lo que veo en whatsmyip.org. ¿Alguna posibilidad de que puedas aconsejarte cómo extraer esa parte? - p1hr
Ok, ahora me estoy confundiendo. Necesitas set_real_ip_from para todas las direcciones a la derecha de la que desea permitir / denegar. Como se indica en el real_ip_recursive sección. - Richard Smith


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

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

los geo módulo funciona como el map módulo, es decir, una variable obtiene valores asignados en función del 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í le asignamos la geo mapa, donde el valor predeterminado para $allow es 0. Si la dirección IP está en la subred 192.168.168.0/24, entonces $allow Obtendrá valor 1, y se permite la solicitud.

Puedes tener tantas líneas en el geo Bloquea como necesitas definir tus rangos de IP.


3
2017-07-31 18:07



¡Gracias! Eso parece funcionar realmente bien, la última cosa a la que me enfrento es ese client_ip de X-forwarded-for. En este momento, desde las 3 direcciones ip que se pasan se usa la última. Yo he añadido real_ip_recursive on; abajo set_real_ip_from pero no ha hecho ninguna diferencia - p1hr
Te refieres a tu X-Forwarded-For El encabezado tiene tres direcciones separadas, es decir, ¿la solicitud se realiza a través de varios proxies? ¿Tiene algún otro encabezado que pueda usar, que contenga solo la IP del cliente? - Tero Kilkanen
Cada proxy de la cadena adjuntará su dirección IP a la X-Forwarded-Forencabezamiento. Además de añadir real_ip_recursive on también necesitas agregar set_real_ip_from Directivas para cada dirección IP de servidor de confianza en su cadena de proxy. Nginx trabajará a través de cada una de estas directivas y devolverá la IP del cliente como el primer valor que alcance en el X-Forwarded-For encabezado que no coincide con ninguno de su especificado set_real_ip_from valores - miknik
FWIW, esta combinación no me funcionó con AWS ALB. Lo que funcionó fue usar la directiva proxy dentro del bloque geo, con la misma ip que set_real_ip - nginx.org/en/docs/http/ngx_http_geo_module.html - talonx