Включить Limit Req Module и Fail2Ban в HestiaCP шаблоне сайта Nginx

В HestiaCP есть возможность создать шаблоны Nginx к важдому сайту. Для этого за основу берем шаблоны wordpress.stpl и wordpress.tpl находящиеся вот здесь

/usr/local/hestia/data/templates/web/nginx/php-fpm

Переименовываем их к примеру сайт1.stpl и сайт1.tpl,оригиналы конечно же оставляем там где они и были. В каждом файле устанавливаем свои зоны, и свои ключи примерно так в файле tpl, зоны peret_tpl и php_tpl. Одна зона защищает PHP скрипты limit_req zone=php_tpl burst=15 nodelay; Вторая весь остальной сайт. Количество rate подбирается под ваш сайт, к примеру для /wp-admin/widgets.php стоит устанавливать более высокое значение, так как если вы перейдете в виджеты, посыпятся ошибки limit_req. Вот тут очень хорошо написано

limit_req_zone $binary_remote_addr zone=peret_tpl:10m rate=1r/s;
limit_req_zone $server_name zone=php_tpl:10m rate=10r/s;

server {
	listen      %ip%:%web_port%;
	server_name %domain_idn% %alias_idn%;
	root        %docroot%;
	index       index.php index.html index.htm;
	access_log  /var/log/nginx/domains/%domain%.log combined;
	access_log  /var/log/nginx/domains/%domain%.bytes bytes;
	error_log   /var/log/nginx/domains/%domain%.error.log error;

	include %home%/%user%/conf/web/%domain%/nginx.forcessl.conf*;

	location = /favicon.ico {
		log_not_found off;
		access_log off;
	}

	location = /robots.txt {
		try_files $uri $uri/ /index.php?$args;
		log_not_found off;
		access_log off;
	}

	location ~ /\.(?!well-known\/) {
		deny all;
		return 404;
	}

	location / {
		try_files $uri $uri/ /index.php?$args;

		location ~* ^.+\.(ogg|ogv|svg|svgz|swf|eot|otf|woff|woff2|mov|mp3|mp4|webm|flv|ttf|rss|atom|jpg|jpeg|gif|png|webp|ico|bmp|mid|midi|wav|rtf|css|pdf|js|jar)$ {
			expires 365d;
			fastcgi_hide_header "Set-Cookie";
		}

		location ~* /(?:uploads|files)/.*.php$ {
			deny all;
			return 404;
		}

		location = /xmlrpc.php {
				deny all;
				access_log off;
				log_not_found off;
				return 403;

		}

		location ~ [^/]\.php(/|$) {
			try_files $uri =404;
			limit_req zone=php_tpl burst=30 nodelay;
			include /etc/nginx/fastcgi_params;

			fastcgi_index index.php;
			fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

			fastcgi_pass %backend_lsnr%;

			include %home%/%user%/conf/web/%domain%/nginx.fastcgi_cache.conf*;

			if ($request_uri ~* "/wp-admin/|/wp-json/|wp-.*.php|xmlrpc.php|index.php|/store.*|/cart.*|/my-account.*|/checkout.*") {
				set $no_cache 1;
			}

			if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in|woocommerce_items_in_cart|woocommerce_cart_hash|PHPSESSID") {
				set $no_cache 1;
			}
		}
	}

	location /error/ {
		alias %home%/%user%/web/%domain%/document_errors/;
	}

	location /vstats/ {
		alias   %home%/%user%/web/%domain%/stats/;
		include %home%/%user%/web/%domain%/stats/auth.conf*;
	}

	include /etc/nginx/conf.d/phpmyadmin.inc*;
	include /etc/nginx/conf.d/phppgadmin.inc*;
	include %home%/%user%/conf/web/%domain%/nginx.conf_*;
}

И в файле stpl зоны peret и php, ключи можно использовать под ваши требования см. ниже файла конфигурации.


limit_req_zone $binary_remote_addr zone=peret:10m rate=1r/s;
limit_req_zone $server_name zone=php:10m rate=10r/s;

server {
	listen      %ip%:%web_ssl_port% ssl;
	server_name %domain_idn% %alias_idn%;
	root        %sdocroot%;
	index       index.php index.html index.htm;
	access_log  /var/log/nginx/domains/%domain%.log combined;
	access_log  /var/log/nginx/domains/%domain%.bytes bytes;
	error_log   /var/log/nginx/domains/%domain%.error.log error;

	ssl_certificate     %ssl_pem%;
	ssl_certificate_key %ssl_key%;
	ssl_stapling        on;
	ssl_stapling_verify on;

	# TLS 1.3 0-RTT anti-replay
	if ($anti_replay = 307) { return 307 https://$host$request_uri; }
	if ($anti_replay = 425) { return 425; }

	include %home%/%user%/conf/web/%domain%/nginx.hsts.conf*;

	location = /favicon.ico {
		log_not_found off;
		access_log off;
	}

	location = /robots.txt {
		try_files $uri $uri/ /index.php?$args;
		log_not_found off;
		access_log off;
	}

	location ~ /\.(?!well-known\/) {
		deny all;
		return 404;
	}

	location = /xmlrpc.php {
			deny all;
			access_log off;
			log_not_found off;
			return 403;
	}

	location / {
		try_files $uri $uri/ /index.php?$args;

		location ~* ^.+\.(ogg|ogv|svg|svgz|swf|eot|otf|woff|woff2|mov|mp3|mp4|webm|flv|ttf|rss|atom|jpg|jpeg|gif|png|webp|ico|bmp|mid|midi|wav|rtf|css|js|pdf|jar)$ {
			expires 365d;
			fastcgi_hide_header "Set-Cookie";
		}

		location ~* /(?:uploads|files)/.*.php$ {
			deny all;
			return 404;
		}

		location ~ [^/]\.php(/|$) {
			try_files $uri =404;
			limit_req zone=php burst=30 nodelay;
			include /etc/nginx/fastcgi_params;

			fastcgi_index index.php;
			fastcgi_param HTTP_EARLY_DATA $rfc_early_data if_not_empty;
			fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

			fastcgi_pass %backend_lsnr%;

			include %home%/%user%/conf/web/%domain%/nginx.fastcgi_cache.conf*;

			if ($request_uri ~* "/wp-admin/|/wp-json/|wp-.*.php|xmlrpc.php|index.php|/store.*|/cart.*|/my-account.*|/checkout.*") {
				set $no_cache 1;
			}

			if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in|woocommerce_items_in_cart|woocommerce_cart_hash|PHPSESSID") {
				set $no_cache 1;
			}
		}
	}

	location /error/ {
		alias %home%/%user%/web/%domain%/document_errors/;
	}

	location /vstats/ {
		alias   %home%/%user%/web/%domain%/stats/;
		include %home%/%user%/web/%domain%/stats/auth.conf*;
	}

	proxy_hide_header Upgrade;

	include /etc/nginx/conf.d/phpmyadmin.inc*;
	include /etc/nginx/conf.d/phppgadmin.inc*;
	include %home%/%user%/conf/web/%domain%/nginx.ssl.conf_*;
}

Добавляем в сайт1.stpl, такие записи. По аналогии после и сай1.tpl. После чего директиву limit_req zone=one burst=5 nodelay; используем например в блоке location ~ \.php$ для защиты PHP, можно добавить в любой блок.

Первой ограничивает количество запросов в секунду, в данном случае до одного. Второе, добавляет burst (возможность создания очереди при всплесках запросов). Третье ограничивает количество запросов к скриптам вашего сайта PHP. Подробнее можно посмотреть здесь.

В директиве limit_req модуля nginx можно использовать следующие временные значения:

  • $binary_remote_addr: IP-адрес клиента в бинарном виде.
  • $remote_addr: IP-адрес клиента в текстовом виде.
  • $server_addr: IP-адрес сервера в текстовом виде.
  • $request_uri: URI запроса.
  • $http_user_agent: User-Agent браузера.
  • $http_referer: HTTP заголовок Referer.
  • $http_cookie: HTTP заголовок Cookie.
  • $http_x_forwarded_for: HTTP заголовок X-Forwarded-For.
  • любые другие HTTP заголовки.

Эти значения могут быть использованы для настройки ограничений на запросы с учетом различных параметров, таких как IP-адрес клиента, URI запроса, заголовки и другие.

limit_req_zone $server_name zone=php:10m rate=30r/m; что означает $server_name

Переменная $server_name в данном контексте означает имя сервера, для которого создается зона ограничения запросов (limit_req_zone). Это позволяет создавать отдельные зоны ограничения для разных серверов или виртуальных хостов на одном сервере. В данном случае, для каждого уникального значения переменной $server_name будет создаваться своя зона ограничения запросов с размером 10 мегабайт и ограничением в 30 запросов в мин.

Для добавления других переменных к limit_req_zone в NGINX, Вы можете использовать специальные ключи для определения их значений. Например, если Вы хотите добавить IP-адрес клиента в текстовом виде, Вы можете использовать $remote_addr. Вот пример:

limit_req_zone $binary_remote_addr$remote_addr$request_uri$http_user_agent$http_referer$http_cookie$http_x_forwarded_for zone=my_zone:10m rate=30r/m;

Вы можете добавить любые другие HTTP заголовки или переменные, которые Вам необходимы, просто указав их после $remote_addr через $.

Загружаем файлы обратно на сервер по FTP сюда

/usr/local/hestia/data/templates/web/nginx/php-fpm

Выбираем в панели для сайта свой шаблон

Включить Limit Req Module и Fail2Ban в HestiaCP шаблоне сайта Nginx

После этого применяем шаблон пересобирая пользователей

v-rebuild-users

Так как в Hestia уже установлен и настроен Fail2Ban, то все что стоит сделать, это добавить и включить Limit Req Module в файле

sudo nano /etc/fail2ban/jail.local

Добавляем вот такой блок

[nginx-limit-req]
enabled = true
filter  = nginx-limit-req
port    = http,https
logpath = /var/log/nginx/*error.log
bantime = 600
maxretry = 5

Перезагружаем Fail2Ban, и Nginx смотрим статусы

sudo systemctl restart fail2ban && sleep 2 && sudo systemctl status fail2ban && sudo fail2ban-client reload && systemctl restart nginx && sleep 2 && systemctl status nginx

Всё. В шаблоны можно добавлять все что угодно. Следите за тем как они меняются(но это очень редко).