Защита от DDoS в nginx от ботов с кривым referer

Тема в разделе "Защита от Ddos-атак", создана пользователем Devider, 9 сен 2013.

  1. Иногда ддос-боты имеют кривые рефереры вида "dsfsdfsdf.com", вот пример лога:
    Код:
    85.94.164.50 - - [14/Jul/2013:21:10:28 +0400] "GET / HTTP/1.1" 502 568 "2344.net" "Mozilla/6.0 (compatible; MSIE 6.0; Windows NT 6.1; SV1; .NET CLR 3.5.30729)" "23sdf44fsw.net"
    85.94.164.50 - - [14/Jul/2013:21:10:28 +0400] "GET / HTTP/1.1" 502 166 "23sd34fsw.net" "Opera/7.0 (Windows NT 5.1; rv:20.0) Gecko/20100101 Firefox/20.0" "ssss333v.net"
    195.78.247.11 - - [14/Jul/2013:21:10:28 +0400] "GET / HTTP/1.1" 502 166 "333444nnxxxss" "Mozilla/1.1 (Windows NT 6.1; U; ru)" "-"
    195.78.247.11 - - [14/Jul/2013:21:10:28 +0400] "GET / HTTP/1.1" 502 166 "23sd334fsw.net" "Opera/8.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)" "34554345.com"
    195.78.247.11 - - [14/Jul/2013:21:10:28 +0400] "GET /topic/7145/ HTTP/1.1" 502 166 "-" "Opera/7.0 (compatible; MSIE 5.01; Windows NT 5.0)" "-"
    
    Настоящие рефереры могут быть либо пустыми, либо содержать в начале "http://" или "https://". Таким образом, мы легко сможем отсеять подобных ботов прописав в конфиге nginx следующее:
    Код:
    if ($http_referer !~* ^($|https?://) ) {  return 444;  }
    
    Если же боты чуть поумнее и имеют рефы вида "http://sdff234.net", можно фильтровать их по другим признакам, например, наличию в урле более двух цифр:
    Код:
    if (preg_match("/http:\/\/([^\/]*)/i", $http_referer + '/', $m)) {
      $ref_domain = $m[1];
      if ($ref_domain ~ \d.*\d) {
      return 444;
      }
    }
    
    По крайней мере это условие поисковый трафф точно не обрежет, так как ни Яндекс, Ни Гугл, ни другие поисковики в названии домена цифр не содержат. Если же ваш сайт содержит в названии домена цифры - такой метод не годится.

    Не лишним бывает обрезать трафф с порносайтов и казино - в рефах нередко используются
    названия доменов включающих в себя слова "sex", "porn", "poker" и т.п.:
    Код:
    if (preg_match("/http:\/\/([^\/]*)/i", $http_referer + '/', $m)) {
      $ref_domain = $m[1];
      if ( $ref_domain ~* (babes|forsale|girl|jewelry|love|nudit|organic|poker|porn|sex|teen) ) {
          return 403;
      }
    }
    
    Если заголовки реф-ботов совсем хитрые, можно обрезать весь реф-траф, за исключением своего сайта и поисковиков:
    Код:
    if ( $http_referer ~* (ваш сайт|yandex.ru|google.ru|google.com|mail.ru|yahoo.com|rambler.ru|msn.com) ) {
      return 403;
    }
    
    Если ддосер не ламер, то реф-заголовки у ботов будут пустыми, а в таком случае нам придется их отсекать либо по стране, либо другими способами.

    Мотивирующая картинка:
     
    9 сен 2013

Поделиться этой страницей