Este é o comportamento padrão do nginx para esta parte da sua configuração:
location /upload {
if ($http_referer !~ "^http://(.+\.)?foo\.com/"){
rewrite .*\.(jpe?g|gif|bmp|png)$ /nohotlink.gif break;
}
location ~ \.(php|sql|php3|php4|phtml|pl|py|jsp|asp|htm|shtml|sh|cgi)$ {
deny all;
}
}
Por quê?
Deixe-me esclarecer como os locais funcionam: quando o nginx lê os arquivos de configuração, ele classifica os blocos de localização em três tipos:
- Bloqueios de locais Exatos , por exemplo %código%
- Bloqueios de locais Prefixados , por exemplo %código%
- Blocos de localização que contêm expressões regulares , por exemplo %código%
Quando uma solicitação chega ao nginx, o processo de seleção de local é o seguinte:
- Se um bloco de local exato correspondente ao URI for encontrado, o nginx interromperá a pesquisa por outros blocos de local e atenderá a essa solicitação.
- Se não, o nginx pesquisará o bloco de localização prefixado correspondente mais longo e o memorizará antes de passar para a próxima etapa.
- Em seguida, o nginx verifica os blocos de localização que contêm expressões regulares sequencialmente. A primeira correspondência será usada para atender à solicitação.
- Se nada foi encontrado na etapa anterior, o nginx usará o bloco de localização com prefixo da etapa 2 para atender à solicitação. Se nenhum for encontrado, várias coisas podem acontecer, mas não é o assunto.
Portanto, no seu caso, o bloco de localização que corresponde à extensão location = /upload { }
tem precedência sobre o bloco de localização que corresponde à parte location /upload { }
do URI.
Editar : esclarecimento sobre solução, solução alternativa adicionada.
Usando o location ~ /upload { }
, você pode dizer ao nginx para alterar o comportamento dele para a etapa 2, de modo que ele use imediatamente o local prefixado correspondente, ignorando a pesquisa de locais de expressões regulares. Então você tem 2 soluções:
Solução 1 :
upload.access:
if ($http_referer !~ '^http://(.+\.)?foo\.com/') {
rewrite '.*\.(jpe?g|gif|bmp|png)$' '/upload/nohotlink.gif' break;
}
if ($uri ~ '\.(php|sql|php3|php4|phtml|pl|py|jsp|asp|htm|shtml|sh|cgi)$') {
return 403;
}
mesmo bloco de servidor
Solução 2 :
upload.access:
if ($http_referer !~ '^http://(.+\.)?foo\.com/') {
rewrite '.*\.(jpe?g|gif|bmp|png)$' '/upload/nohotlink.gif' break;
}
location ~ \.(php|sql|php3|php4|phtml|pl|py|jsp|asp|htm|shtml|sh|cgi)$ {
deny all;
}
bloco de servidores:
location ^~ /upload {
include /etc/nginx/includes/upload.access;
}
Agora, sua configuração atual não levará a nada se você não configurar um local para encaminhar o processamento de arquivos php: confira nginx módulo fastcgi . Em seguida, você precisará alterar suas regras de regravação no arquivo root.access para que elas não sejam resolvidas no contexto de local atual (ou seja, criar um único local de fallback e alterar .php
to /upload
para informar ao nginx para executar o processo de seleção de local novamente depois de reescrever).