Nginx: защита по ip + ограничение частых запросов
Поразбирался с правилами nginx и написал для себя универсальную «закрывашку» системных директорий для всех ip кроме нужных.
Сюда попадут любые запросы в директории manager, core и connectors. Все адреса, кроме разрешенных получат отлуп, а разрешенные обработаются. Так как nginx начинает применять правила после первого точного совпадения — отдельно указываем как обрабатывать *.php файлы.
location ~* ^\/(manager|core|connectors)\/(?:.*)$ { allow айпиадмина-1; allow айпиадмина-2; deny all; location ~* \.php$ { include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass backend-имясайта; } }
А теперь — установка лимита запросов документов сайта. Примитивная защита от DDOS.
Создаём новую зону для работы, в nginx.conf (секция http):
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;Ограничение на запросы — 1 в секунду.
Применяем это ограничение к выполнению *.php файлов сайта:
location ~* \.php$ { limit_req zone=one burst=3; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass backend-bezumkin; }Burst — это разрешенный кратковременный всплеск запросов. Подробнее в документации.
С этим правилом админка MODX работать не будет, ибо там идёт куча одновременных запросов, на которые nginx будет отвечать error 503.
Но нам это не важно, ибо у нас раньше прописан отдельный блок для работы с системными директориями, и там php выполняется без ограничений.
Можете зажать у меня на сайте кнопку F5 на секунду и отпустить — будет error 503. А если нажимать F5 медленно — ошибки не будет. Спасает от настырных роботов и и простеньких атак.
Любопытным —
# указание обработчика php upstream backend-mysite {server unix:/var/run/php5-mysite.sock;} # здесь конфиг сайта server { listen 80; server_name mysite.ru www.mysite.ru; root /var/www/mysite/www; access_log /var/log/nginx/mysite-access.log; error_log /var/log/nginx/mysite-error.log; index index.php; rewrite_log on; # редирект с ww на без-www if ($host != 'mysite.ru' ) { rewrite ^/(.*)$ http://mysite.ru/$1 permanent; } # если нет запрошенного файла - слать в локацию rewrite location / { try_files $uri $uri/ @rewrite; } # отсюда слать всё на index.php - это есть быть friendly urls location @rewrite { rewrite ^/(.*)$ /index.php?q=$1; } # а вот и наша защита системных директорий по ip location ~* ^\/(manager|core|connectors)\/(?:.*)$ { allow 184.55.68.97; deny all; location ~* \.php$ { include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass backend-mysite; } } # а это выполнение всех php файлов, не попавших в предыдущий блок location ~* \.php$ { limit_req zone=one burst=3; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass backend-mysite; } # статику отдаём без участия MODX и php location ~* ^.+\.(jpg|jpeg|gif|css|png|js|ico|bmp|woff|eot)$ { access_log off; expires 10d; break; } # на всякий случай запрещаем чтение .htaccess - вдруг у вас там еще и апач есть? location ~ /\.ht { deny all; } }
Комментарии: 9
limit_req zone=one burst=3;Для всех сайтов эта строка одинаковая?
А еще заметил, что у тебя nginx той же версии: работают service nginx restart/reload? У меня только kill или killall помогает поменять конфиг, иначе выдает
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)потому что процесс nginx не останавливается…
В основном конфиге задаётся зона, дальше эту ограничивающую зону можно применять к любой location любого сайта.Каждому сайту можно подкрутить параметр burst.
Если нужно ограничить частоту запросов не 1 в сек, а, например, 2 — то задавай вторую зону и там прописывай это ограничение.
А потом применяй вторую зону какому-нибудь сайту:
service nginx restart/reload работает без проблем. На домашнем сервере была такая проблема с php5-fpm, решил полным удалением и установкой заново.
Если нужно ограничить частоту запросов не 1 в сек, а, например, 2 — то задавай вторую зону и там прописывай это ограничение.
limit_req_zone $binary_remote_addr zone=two:10m rate=2r/s;
А потом применяй вторую зону какому-нибудь сайту:
location / { limit_req zone=two burst=5; }
service nginx restart/reload работает без проблем. На домашнем сервере была такая проблема с php5-fpm, решил полным удалением и установкой заново.
Решил проблему с nginx, может кому-то еще пригодится. В файле /etc/init.d/nginx в функции stop было /run/$NAME.pid, а у меня все пиды в /var/run/
Вопрос на засыпку.
Есть фронтенд проксирующий, к которому мы не имеем доступа, есть определенная директория, в которую нужно дать доступ пару десяткам IP, так вот, суть в чем. У нас все обращения на бэкенд поступают с 1 проксирующего IP, так как же нам заюзать Allow 123.123.123.123;? =)
PS: конструкции типо if() отпадают сразу---ip пара десятков
Есть фронтенд проксирующий, к которому мы не имеем доступа, есть определенная директория, в которую нужно дать доступ пару десяткам IP, так вот, суть в чем. У нас все обращения на бэкенд поступают с 1 проксирующего IP, так как же нам заюзать Allow 123.123.123.123;? =)
PS: конструкции типо if() отпадают сразу---ip пара десятков
прописал в nginx.conf
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
прописал в sites-available/user.conf
location ~* \.php$ {
limit_req zone=one burst=3;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass backend-mysite;
}
перезапускаю service nginx reload
Вываливается ошибка
Убираю строку limit_req zone=one burst=3;
Перезапускаю nginx, ошибка не вываливается.
В чем может быть дело? :-(
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
прописал в sites-available/user.conf
location ~* \.php$ {
limit_req zone=one burst=3;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass backend-mysite;
}
перезапускаю service nginx reload
Вываливается ошибка
Убираю строку limit_req zone=one burst=3;
Перезапускаю nginx, ошибка не вываливается.
В чем может быть дело? :-(
в логе вот чего:
2014/10/12 12:12:16 [emerg] 11282#0: unknown limit_req_zone «one» in /etc/nginx/sites-enabled/user.conf:31
2014/10/12 12:12:16 [emerg] 11282#0: unknown limit_req_zone «one» in /etc/nginx/sites-enabled/user.conf:31
Василий, а вот тут точно ссылка куда надо?
Burst — это разрешенный кратковременный всплеск запросов. Подробнее в документации.
я так понимаю, что ссылка должна быть сюда nginx.org/ru/docs/http/ngx_http_limit_req_module.html
Burst — это разрешенный кратковременный всплеск запросов. Подробнее в документации.
я так понимаю, что ссылка должна быть сюда nginx.org/ru/docs/http/ngx_http_limit_req_module.html
Поправил, спасибо.
Разобрался с ошибкой.
Идущих по этим же граблям предупреждаю:
В файле nginx.conf строка:
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
должна быть вставлена ДО строки:
include /etc/nginx/sites-enabled/*;
Идущих по этим же граблям предупреждаю:
В файле nginx.conf строка:
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
должна быть вставлена ДО строки:
include /etc/nginx/sites-enabled/*;
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.