Есть ли элегантный способ заблокировать группу рефереров сразу?

21

Чтобы предотвратить спам реферера, в моем nginx.conf есть такой раздел:

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

Эти правила говорят nginx просто закрыть соединение, если у пользователя установлен один из этих рефереров. Есть ли более элегантный способ сделать это? Могу ли я определить список этих доменов, а затем сказать что-то вроде: «Если реферер находится в этом списке, верните 444»?

bdesham
источник
создайте один большой файл, такой же, как в примере, и используйте его как включаемый файл, где это необходимо.
Hrvoje Špoljar

Ответы:

31

Я бы попробовал map:

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

Тогда используйте это так:

if ($bad_referer) {
    return 444;
}
Майкл Хэмптон
источник
1
Поскольку карта использует хеш-таблицы, этот подход будет работать лучше, чем ряд отдельных проверок. Прочитайте документы, чтобы найти варианты, которые можно использовать, например, hostnamesи, возможно, includeотдельный файл, в котором они перечислены, чтобы упростить его обслуживание.
Брайан
Читая документы по теме, mapмне было интересно посмотреть, можно ли использовать регулярное выражение для сопоставления с определенными ссылками, так как OP выполняет сопоставление регулярного выражения с использованием ~*оператора, и, действительно, простое указание правила карты, как это "~*spamdomain4.com" 1;будет сделано. Ухоженная!
Hrvoje Špoljar
Вы правы, и это нужно использовать в любом случае.
Майкл Хэмптон
Используя hostnamesопцию, это было бы просто.spamdomain4.com 1;
Брайан
4
@Brian Поле referer - это полный URL, а не просто имя хоста. Так что это не работает.
Майкл Хэмптон
13

Вы можете использовать логический ORдля создания одного оператора множественного совпадения, например

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

РЕДАКТИРОВАТЬ за комментарий; снятие break;с блока

Хрвое Шполяр
источник
2
Директива break никогда не будет достигнута, так как return останавливает обработку текущего запроса.
Ксавье Лукас,