Como negar acesso a recursos com base em cabeçalhos X-encaminhados


13

Estou tentando restringir o acesso aos recursos por trás do Nginx com base no IP do cliente passado nos cabeçalhos X-encaminhados. O Nginx está sendo executado em um contêiner em um cluster Kubernetes no Google Cloud Platform e os ips de clientes reais são passados ​​apenas no cabeçalho x-forwarded-for

Até agora, consegui fazer isso por um único IP com o seguinte 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;
}

Mas como posso fazer isso para intervalos inteiros de IPs? Especificar centenas de IPs manualmente não faz muito sentido.

Toda ajuda é apreciada

Respostas:


11

Use o módulo RealIP para honrar o valor do X-Forwarded-Forcabeçalho. Defina set_real_ip_fromcomo o endereço IP do proxy reverso (o valor atual de $remote_addr).

Por exemplo:

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

Agora você deve poder usar $remote_addre allow/ denydiretivas usando o verdadeiro endereço IP do cliente. Veja este documento para mais informações.


então tentei o seguinte sem sucesso, estou confundindo? 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

Depois de examinar os documentos do Google Load Balancing, encontrei o seguinte: X-Forwarded-For: <unverified IP(s)>, <immediate client IP>, <global forwarding rule external IP>, <proxies running in GCP> (requests only) A entrada <IP do cliente imediato> é o cliente que se conectou diretamente ao balanceador de carga.
p1hr 31/07/19

1
Para que isso funcione, você precisa identificar os intervalos de endereços de <global forwarding rule external IP>e <proxies running in GCP>e adicione set_real_ip_fromdeclarações cobrindo todos eles.
Richard Smith

<global forwarding rule external IP>é o ip externo do meu serviço, não há outros proxies no GCP. Nos meus logs do nginx, vejo solicitações no seguinte formato em [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"que ccc.ccc.ccc.ccc é uma regra de encaminhamento global, bbb.bbb.bbb.bbb um cliente imediato ip - corresponde ao que eu vejo no whatsmyip.org. Alguma chance de você aconselhar como extrair essa parte?
p1hr

1
Ok, agora estou ficando confuso. Você precisa set_real_ip_fromde todos os endereços à direita daquele que deseja permitir / negar. Conforme indicado na real_ip_recursiveseção.
Richard Smith

5

A resposta de Richard já continha as informações sobre a melhor maneira de obter o endereço IP real para o nginx.

Enquanto isso, no que diz respeito à especificação de intervalos de IP, você pode usar http://nginx.org/en/docs/http/ngx_http_geo_module.html .

O geomódulo funciona como o mapmódulo, ou seja, uma variável recebe valores atribuídos, dependendo do valor do endereço IP.

Um exemplo:

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

Aqui atribuímos o geomapa, onde o valor padrão $allowé 0. Se o endereço IP estiver na sub-rede 192.168.168.0/24, $allowobterá o valor 1 e a solicitação é permitida.

Você pode ter quantas linhas no geobloco precisar definir seus intervalos de IP.


Obrigado! que parece funcionar muito bem, a última coisa que estou enfrentando é o client_ip do X-forwarded-for. No momento, dos 3 endereços IP passados, o último é usado. Eu adicionei real_ip_recursive on;abaixo, set_real_ip_frommas isso não fez nenhuma diferença
p1hr

Você quer dizer que seu X-Forwarded-Forcabeçalho tem três endereços separados, ou seja, a solicitação é fornecida por meio de vários proxies? Você tem algum outro cabeçalho que possa usar, que contenha apenas o IP do cliente?
Tero Kilkanen 01/08/19

Todo proxy da cadeia anexa seu endereço IP ao X-Forwarded-Forcabeçalho. Além de adicionar, real_ip_recursive onvocê também precisa adicionar set_real_ip_fromdiretivas para cada endereço IP do servidor confiável em sua cadeia de proxy. Nginx irá trabalhar através de cada uma destas directivas e retornar o IP do cliente como o primeiro valor que bate no X-Forwarded-Forcabeçalho que não corresponde a nenhum dos seus especificados set_real_ip_fromvalores
Miknik

FWIW, essa combinação não funcionou para mim com o AWS ALB. O que fez trabalho foi usar a diretiva de proxy dentro do bloco geo, com o mesmo ip como set_real_ip - nginx.org/en/docs/http/ngx_http_geo_module.html
talonx

3

Tenho estes trabalhando para mim.

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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.