Comment refuser l'accès aux ressources basées sur les en-têtes X-forwarded-for


13

J'essaie de restreindre l'accès aux ressources derrière Nginx en fonction de l'adresse IP du client transmise dans les en-têtes X-forwarded-for. Nginx s'exécute dans un conteneur sur un cluster Kubernetes sur Google Cloud Platform et les ips des clients réels sont transmis uniquement dans l'en-tête x-forwarded-for

Jusqu'à présent, j'ai réussi à le faire pour une seule IP avec le code suivant:

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;
}

Mais comment puis-je faire cela pour des plages entières d'adresses IP? La spécification manuelle de centaines d'adresses IP n'a pas beaucoup de sens.

Toute aide est appréciée

Réponses:


11

Utilisez le module RealIP pour honorer la valeur de l'en- X-Forwarded-Fortête. Définissez set_real_ip_froml'adresse IP du proxy inverse (la valeur actuelle de $remote_addr).

Par exemple:

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

Vous devriez maintenant pouvoir utiliser les directives $remote_addret allow/ en denyutilisant la véritable adresse IP du client. Consultez ce document pour en savoir plus.


alors j'ai essayé ce qui suit en vain, est-ce que je le confond? 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

Après avoir consulté les documents Google Load Balancing, j'ai trouvé ce qui suit: X-Forwarded-For: <unverified IP(s)>, <immediate client IP>, <global forwarding rule external IP>, <proxies running in GCP> (requests only) L'entrée <IP immédiate du client> est le client qui s'est connecté directement à l'équilibreur de charge.
p1hr

1
Pour que cela fonctionne, vous devez identifier les plages d'adresses pour <global forwarding rule external IP>et <proxies running in GCP>et ajouter des set_real_ip_fromdéclarations couvrant tous.
Richard Smith

<global forwarding rule external IP>est l'adresse IP externe de mon service, il n'y a pas d' autres mandataires dans GCP, sur mes journaux nginx je vois des demandes dans le format suivant [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"où ccc.ccc.ccc.ccc est règle de transfert globale, bbb.bbb.bbb.bbb un client immédiat ip - correspond à ce que je vois sur whatsmyip.org. Avez-vous des chances de nous conseiller sur la façon d'extraire cette partie?
p1hr

1
Ok, maintenant je suis confus. Vous devez set_real_ip_frompour toutes les adresses à droite de celle que vous souhaitez autoriser / refuser. Comme indiqué dans la real_ip_recursivesection.
Richard Smith

5

La réponse de Richard contenait déjà des informations sur la meilleure façon d'obtenir la vraie adresse IP à nginx.

En attendant, en ce qui concerne la question de la spécification des plages IP, vous pouvez utiliser http://nginx.org/en/docs/http/ngx_http_geo_module.html .

Le geomodule fonctionne comme le mapmodule, c'est-à-dire qu'une variable obtient des valeurs affectées en fonction de la valeur de l'adresse IP.

Un exemple:

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;
    }
}

Ici, nous attribuons la geocarte, où la valeur par défaut pour $allowest 0. Si l'adresse IP est dans le sous 192.168.168.0/24- réseau , alors $allowobtiendra la valeur 1 et la demande est autorisée.

Vous pouvez avoir autant de lignes dans le geobloc que nécessaire pour définir vos plages IP.


Je vous remercie! cela semble très bien fonctionner, la dernière chose à laquelle je suis confronté est le client_ip de X-forwarded-for. À l'heure actuelle, à partir de 3 adresses IP transmises, la dernière est utilisée. J'ai ajouté real_ip_recursive on;ci-dessous set_real_ip_frommais cela n'a fait aucune différence
p1hr

Voulez-vous dire que votre en- X-Forwarded-Fortête a trois adresses distinctes, c'est-à-dire que la demande provient de plusieurs mandataires? Avez-vous un autre en-tête que vous pouvez utiliser, qui ne contient que l'adresse IP du client?
Tero Kilkanen du

Chaque proxy de la chaîne ajoutera son adresse IP à l'en- X-Forwarded-Fortête. En plus de l'ajout, real_ip_recursive onvous devez également ajouter des set_real_ip_fromdirectives pour chaque adresse IP de serveur de confiance dans votre chaîne proxy. Nginx travaillera ensuite à travers chacune de ces directives et retournera l'IP du client comme première valeur qu'il frappe dans l'en- X-Forwarded-Fortête qui ne correspond à aucune de vos set_real_ip_fromvaleurs spécifiées
miknik

FWIW, cette combinaison n'a pas fonctionné pour moi avec AWS ALB. Ce qui a fonctionné était d'utiliser la directive proxy à l'intérieur du bloc géographique, avec la même IP que set_real_ip - nginx.org/en/docs/http/ngx_http_geo_module.html
talonx

3

Je les fais travailler pour moi.

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.
    }

Réf: http://nginx.org/en/docs/http/ngx_http_geo_module.html

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.