дисклеймер: данная информация может быть полезна только тем, кто может управлять настройками nginx, т.е. владельцам выделенных серверов и различных vps/vds.
в этой статье я хочу на простом примере рассказать, как можно избавиться от нежелательных на сайте гостей при помощи замечательной базы GeoIP и nginx, работающего в качестве front-end'а. GeoIP можно прикрутить и к apache и к iptables, но это тема других статей
1. сначала нужно получить свежую версию базы GeoIP. сделать это можно разными способами в зависимости от используемой ОС и желания. например, если у вас CentOS, то можно установить ее командой "sudo yum install geoip". но в таком случае мы получим старую версию базы. свежую базу нужно скачать с сайта
www.maxmind.com:
Code:
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
и распаковать:
Code:
gunzip -f GeoIP.dat.gz
складывают GeoIP.dat обычно в каталог /usr/share/GeoIP/. для автоматизации процесса обновления базы нужно добавить в список заданий cron следующую запись:
Code:
cd /usr/share/GeoIP/ && wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz && gunzip -f GeoIP.dat.gz
и запускать ее от имени root'a раз в месяц.
2. предполагаю, что nginx уже используется в качестве front-end'a и он собран с поддержкой модуля geoip (проверить командой nginx -V, среди кучи буковок выведенных на экран должен быть следующий набор: --with-http_geoip_module).
в CentOS 6.4 из дефултовых репозиториев скачивается nginx уже с поддержкой geoip, сам GeoIP.dat.gz скачается автоматически в зависимостях (но старая версия!).
3. итак, nginx и geoip есть. осталось настроить nginx.
идем в nginx.conf и в секцию http добавляем следующие строки:
Code:
geoip_country /usr/share/GeoIP/GeoIP.dat;
map $geoip_country_code $good_country {
default yes;
A1 no; # давим анонимусов
CN no; # давим китайцев
}
потом в секции location нужного нам server добавляем следующие строки:
Code:
if ($good_country = no){
return 404;
}
пример части конфига nginx с секцией server:
Code:
server {
server_name google.ws www.google.ws;
listen 8.8.8.8; # по адресу 8.8.8.8 отвечает наш сайт
listen 8.8.8.8:443 ssl;
charset WINDOWS-1251;
index index.php;
set $root_path /var/www/google/data/www/google.ws; # здесь корень нашего форума
location ~* ^.+\.(jpg|jpeg|picture|gif|png|svg|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar|swf)$ {
root $root_path;
}
location / {
proxy_pass http://8.8.8.8:81; # на порту 81 живет apache
proxy_redirect http://8.8.8.8:81/ /;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
if ($good_country = no){
return 404;
}
}
ну и перечитать конфиг nginx'a:
Code:
/etc/init.d/nginx reload
ну вот, китайцев и анонимусов (простите, братья...) мы отсекли полностью. полный список нужных буковок для GeoIP можно посмотреть здесь:
http://dev.maxmind.com/geoip/legacy/codes/iso3166/
3.1 само собой, если нам нужно отсекать много стран, то проще создать для этого отдельный файл и инклюдить его в конфиг nginx'a вместо указания каждой отдельной страны. файл можно назвать, например, bad_countries и он должен быть следующего формата:
Code:
A1 no;
CN no;
US no;
т.е. каждая страна с новой строки и заканчивается точкой с запятой.
в конфиг nginx'a в этом случае в секцию http добавляем следующие строки:
Code:
geoip_country /usr/share/GeoIP/GeoIP.dat;
map $geoip_country_code $good_country {
default yes;
include /etc/nginx/bad_countries;
}
3.2 аналогичным образом можно создавать не список нежелательных гостей, а наоборот - разрешенных. в этом случае в секции location условие нужно поменять на обратное:
Code:
if ($good_country = yes){
return 404;
}
зы. настройку apache для корректной работы с nginx я не рассматриваю. это другой вопрос и он тут много раз обсуждался.
ззы. может я не прав и вместо 404 надо выдавать 403, но мне так захотелось.