Preciso redirecionar para uma URL, a menos que o usuário esteja vindo de nosso endereço IP interno ou esteja acessando um caminho específico.
Eu tentei isso:
location ~* /foobar {
break;
}
location ~* / {
if ($remote_addr != 111.222.333.444) {
rewrite ^ https://external.tld/
}
}
Mas isso não parece funcionar. Essa configuração específica causa um 404 ao acessar https://mydomain.tld/foobar e um "Bem-vindo ao nginx!" página ao acessá-lo de dentro do nosso endereço IP. No entanto, acessar https://mydomain.tld/foobar fora do nosso endereço IP redireciona corretamente para https://external.tld/
Como você não quer (ou não tem permissão) para mostrar seu bloco de servidor completo, farei algumas suposições. O que provavelmente aconteceu com sua configuração? Você criou dois blocos de localização adicionais que são usados para processar qualquer solicitação recebida. Verifique a documentação
location
da diretiva . Os únicos dois tipos de local que podem ultrapassar uma solicitação do local de correspondência de regex são o local exato ( ) e o local do prefixo do-not-check-regex ( ). Caso contrário, o primeiro local de correspondência de regex será escolhido.location = /uri { ... }
location ^~ /prefix { ... }
Cada bloco de servidor tem seu diretório raiz, mesmo que não seja especificado explicitamente usando a
root
diretiva. É escolhido usando prefixo (especificado no momento da compilação , pode ser verificado com onginx -V
comando) e/html
sufixo. Vamos supor que seu prefixo nginx seja/usr/share/nginx
. Então sua raiz padrão estará no/usr/share/nginx/html
diretório, a menos que especificado explicitamente usando aroot /some/path
diretiva.O comportamento padrão do nginx ao atender uma solicitação pode ser descrito como
try_files $uri $uri/ =404
.Vamos supor que temos um
https://mydomain.tld/foobar
pedido. Para servi-lo, seu primeirolocation ~* /foobar { break; }
será escolhido como o primeiro local de regex correspondente. A primeira diretivabreak
significa que o processamento do conjunto atual dengx_http_rewrite_module
diretivas será interrompido. Mas não há nenhuma dessas diretivas (excetobreak
aquela) dentro deste bloco de localização! Sim, isso significa que estabreak
diretiva é inútil aqui. Em seguida, o nginx verificará a existência de um/usr/share/nginx/html/foobar
arquivo, um arquivo de índice do/usr/share/nginx/html/foobar/
diretório (o padrão éindex.html
), e depois que ambas as verificações falharem, retornará umHTTP 404 Not Found
erro.Agora vamos supor que temos um
https://mydomain.tld/
pedido. Seu primeiro bloco de localização não corresponderá a ele, então o segundolocation ~* / { ... }
é escolhido para processar essa solicitação (esse bloco de localização corresponderá a qualquer solicitação válida possível). Se uma verificação de endereço IP não for aprovada, um redirecionamento ocorrerá. Mas se passar, o nginx processará sua solicitação da mesma maneira descrita acima, retornando seuindex.html
arquivo de boas-vindas padrão do/usr/share/nginx/html/
diretório.Parece que você não entende como as diretivas do
ngx_http_rewrite_module
são processadas. Leia novamente a primeira parte da documentação:Você pode colocar suas verificações no nível do bloco do servidor:
A
break
diretiva acima funcionará como esperado, uma execução dengx_http_rewrite_module
diretivas no nível do servidor será interrompida. Isso significa que qualquer outra diretiva desse módulo (comoset
,if
,return
,rewrite
etc.), se houver, deve ser colocada antes do bloco acima. Isso não se aplica àsngx_http_rewrite_module
diretivas colocadas no nível de localização.Há mais uma ressalva possível. Se sua
https://mydomain.tld/foobar
página faz uso de algum recurso (scripts, estilos, imagens etc.), o acesso a esses recursos também deve ser permitido. Por exemplo, você pode alterar a condição para permitir qualquer coisa iniciada com/foobar
prefixo usandoif ($uri ~* ^/foobar) { break; }
block. Se seus endereços não puderem ser verificados com um único regex, você poderá usar váriosif (...) { break; }
blocos.