Existe uma maneira elegante de bloquear um monte de referências ao mesmo tempo?

21

Para evitar spam de referência, meu nginx.conf contém uma seção como esta:

if ($http_referer ~* spamdomain1\.com) {
    return 444;
}
if ($http_referer ~* spamdomain2\.com) {
    return 444;
}
if ($http_referer ~* spamdomain3\.com) {
    return 444;
}

Essas regras dizem ao nginx apenas para fechar a conexão se o usuário tiver um desses referenciadores definidos. Existe uma maneira mais elegante de fazer isso? Posso definir uma lista desses domínios e dizer algo como: “Se o referenciador estiver nesta lista, retorne 444”?

Bdesham
fonte
crie um arquivo grande como o da amostra e use-o como arquivo de inclusão, quando necessário.
Hrvoje Špoljar

Respostas:

31

Eu tentaria um map:

map $http_referer $bad_referer {
    default                  0;
    "~spamdomain1.com"       1;
    "~spamdomain2.com"       1;
    "~spamdomain3.com"       1;
}

Em seguida, use-o assim:

if ($bad_referer) {
    return 444;
}
Michael Hampton
fonte
1
Como o mapa usa tabelas de hash, essa abordagem terá um desempenho melhor do que uma série de verificações individuais. Leia a documentação para opções que poderiam ser usados, como hostnamese possiblely includede um arquivo separado onde são listados poderia torná-lo mais fácil de manter.
Brian
Lendo os documentos relacionados a mapeu estava interessado em ver se alguém poderia usar regex para corresponder a determinados referenciadores, já que o OP está fazendo a correspondência de regex usando o ~*operador e, de fato, simplesmente especificar a regra do mapa como "~*spamdomain4.com" 1;fará o truque. Arrumado!
Hrvoje Špoljar
Você está certo, e isso precisa usá-lo de qualquer maneira.
Michael Hampton
Usando a hostnamesopção seria simplesmente.spamdomain4.com 1;
Brian
4
@Brian O campo de referência é um URL completo, não simplesmente um nome de host. Então isso não funciona.
Michael Hampton
13

Você pode usar lógico ORpara criar uma declaração de correspondência múltipla, por exemplo

if ($http_referer ~ "spamdomain1\.com|spamdomain2\.com|spamdomain3\.com")  { 
  return 444;
}

EDIT por comentário; removendo break;do bloco

Hrvoje Špoljar
fonte
2
A diretiva de interrupção nunca será alcançada, pois o retorno interrompe o processamento da solicitação atual.
Xavier Lucas