nginx Bloqueia o IP com base no URI em um 'local'

4

Atualmente há um bloco de um local /

  location / {
    root  /var/www/docs;
    proxy_pass  http://backend;
    proxy_buffering     on;
    proxy_buffer_size   64k;
    proxy_buffers       256   64k;
  }

que precisa ser filtrado por IP.

Idealmente, para reduzir o número de repetições das mesmas diretivas em location , gostaria de realizar o teste dentro do bloco location

  location / {

    if ($uri ~ '^/(abc|def|ghi)') {
        allow 10.0.0.0/8;
        allow 1.2.3.4;
        deny all;
    }

    root  /var/www/docs;
    proxy_pass  http://backend;
    proxy_buffering     on;
    proxy_buffer_size   64k;
    proxy_buffers       256   64k;
  }

Infelizmente, parece que as diretivas allow / deny não podem ser usadas dentro de um bloco if .

"allow" directive is not allowed here in /etc/nginx/sites-enabled/mysite:20

Existe uma maneira elegante de realizar o teste sem repetir os blocos location ?

(como

  location ~ /(abc|def|ghi) {

        allow 10.0.0.0/8;
        allow 1.2.3.4;
        deny all;

        ... 5 other lines root,proxy...
   }

  location  / {

        ... 5 other lines root,proxy...
   }

    
por Ring Ø 01.04.2011 / 04:49

4 respostas

4

Como o coredump disse, não, use vários locais.

Mas é possível tornar o conteúdo dos blocos location menos repetitivos. A chave aqui é um bloco denominado location que contém as diretivas root e proxy_... .

Por exemplo:

location / {
  try_files $uri @proxy;
}
location ~ /(abc|def|ghi) {
  allow 10.0.0.0/8;
  allow 1.2.3.4;
  deny all;

  try_files $uri @proxy;
}
location @proxy {
  root  /var/www/docs;
  proxy_pass  http://backend;
  proxy_buffering     on;
  proxy_buffer_size   64k;
  proxy_buffers       256   64k;
}

E provavelmente ainda melhor seria colocar a diretiva root fora de todos os blocos location .

    
por 04.04.2013 / 13:01
2

Não. Use vários locations , pode parecer feio, mas você terminará com menos chance de se a loucura .

Lembre-se também que o nginx processa primeiro as correspondências de expressão regular e, se nenhuma corresponder, ele tenta a localização literal mais específica, sendo location / uma espécie de localização de capturar todos . Sabendo que você pode diminuir o número de locais que você precisa. Dê uma olhada no documento para ver como as solicitações são processadas.

    
por 01.04.2011 / 05:11
2

Geralmente, nesses casos, é possível ajudar "locais aninhados" ...

location / {
   root /var/www/docs;
   allow all;

   location /admin {
       deny 1.2.3.4;
   }

}

... mas nem todas as diretivas herdadas em locais aninhados. Infelizmente, mas exatamente proxy_pass , fastcgi_pass e similares não são herdados ... Portanto, a solução proposta anteriormente (com @namedlocation) está correta neste caso. Você também pode usar uma diretiva include para "bloco proxy_pass", é claro.

    
por 04.04.2013 / 13:25
2

Primeiro você tem que definir uma variável que irá manter seus filtros IP. Isso vai para a seção link da configuração do nginx:

map $remote_addr (or $http_x_forwarded_for if behind a proxy) $allowed {
        default deny;
        ~\s*111.222.333.444$ allow;
        ~\s*333.444.555.*$   allow;
    }

então na seção server você escreve a construção if e filtra o local de acesso pelo conteúdo da variável $ allowed :

location / {
        if ( $allowed = "deny" ) { return 403; }
        #...
    }
    
por 06.05.2016 / 05:08

Tags