Собственно зачем вообще запрещать доступ к сайту по географическому признаку ? Да просто 80% IP адресов участвующих в ddos атаке, как правило принадлежат странам, жители которых никогда не зайдут на данный сайт, естественно это сугубо индивидуально для каждого ресурса и если вы знаете что часть ваших посетителей приходит из Эфиопии или Чили, блокировать их, вы вряд-ли захотите. У большинства-же моих клиентов, географическое расположение посетителей, как правило ограничивается Европой и бывшим СССР, остальных можно смело игнорировать.
Описываемый способ блокировки неугодных стран с помощью веб сервера nginx и geoip модуля, в одиночку, и тем более целиком, проблему никак не решит, это лишь одна, из целого ряда всевозможных мер ( настройка ядра, фаервола, штатных сервисов, дополнительного софта ), по минимизации вреда, наносимого данным видом атаки серверу и сайтам, на нем расположенным.
Проекты, часто нуждающиеся в подобного рода защите, я по возможности стараюсь изначально поднимать без участия веб сервера apache, то есть на связке nginx - fastcgi.
Итак, ставить и настраивать все это хозяйство будем на сервере под управлением операционной системы FreeBSD 8.2 and64.
Что-бы модуль geoip заработал, потребуется дополнительная библиотека, ставим:
freebsd82 /usr/ports# make -C net/GeoIP install clean
Далее ставим nginx:
freebsd82 /usr/ports# make -C www/nginx install clean
в опциях сборки нужно включить geoip модуль nginx, поставив галку напротив пункта Enable http_geoip module.
Далее идем на страницу http://www.maxmind.com/app/geolitecountry и скачиваем latest GeoLite Country Binary Format, это бесплатный вариант базы стран и соответствующих им блоков IP адресов. Распаковываем архив и кидаем файл GeIP.dat в папку /usr/local/etc/nginx/conf/geo. Осталось отредактировать конфиги nginx.
Открываем nginx.conf, дописываем в секцию http следующий блок директив:
geoip_country /usr/local/etc/nginx/conf/geo/GeoIP.dat; # подключаем GeIP базу map $geoip_country_code $bad_country { # модуль map создает переменные, значения которых зависят от других переменных, очень полезная штука default 1; # значение по умолчанию include geo/good_countries; # инклудим файл, к нему вернемся чуть позже }
Этот блок map, означает, что все страны находящиеся в базе данных, являются запрещенными по умолчанию, а в файле good_countries, будут перечислены разрешенные страны. Если у вас например ситуация, когда разрешенных стран больше чем запрещенных, можно легко инвертировать данную логику и создать файл bad_countries со списком запрещенных стран, разрешив все остальные.
Теперь настройки хоста. Я предпочитаю держать хосты в отдельной папке, например hosts, каждый в своем файле.
server { listen IP:80; server_name testhost.com; if ($bad_country){ # если данная переменная установлена, то есть если страна не перечислена в файле good_countries return 444; # выдаем клиенту пустой ответ ( незачем отдавать 403 ошибку или еще какую-либо ) } ................. ................. }
Теперь вернемся к файлу good_countries. Тут все предельно просто, страны, которым разрешен доступ на сайт, перечислены в следующем формате:
TM 0; UA 0; UZ 0; RU 0; ....... ....... и т.д.
То есть, что-бы разрешить какую-либо страну, достаточно добавить ее двухбуквенный код и 0, после чего перезагрузить конфиг nginx:
freebsd82 /# nginx -s reload
Сами коды стран, на раз два, находятся через гугл.
Проверить, работает geoip модуль или нет, можно, удалив из списка разрешенных стран свою, и попробовав зайти на сайт.
Собственно такова общая схема использования geoip модуля nginx для защиты от ddos атак.
Естественно можно придумать массу других вариантов применения данного модуля для решения различных задач связанных с географическим расположением посетителя сайта.