October 24, 2021

Настройки nginx + wordpress

Настройки безопасности Nginx с wordpress

server {

	listen 80;
    listen [::]:80 default_server ipv6only=on;

    if ($host = site.com) {
        return 301 https://$host$request_uri;
    }
	
	set $subdomain "";
	if ($host ~* ^www.site.com$) {
		set $subdomain "";
	}
	if ($host ~* ^([a-z0-9-\.]+)\.site.com$) {
		set $subdomain "";
	}
	if ($host ~* ^([a-z0-9-\.]+)\.site.com) {
		set $subdomain "";
	}


	#if ($host ~* ^([a-z0-9-\.]+)\.site.com$) {
	#	set $subdomain $1;
	#}
	access_log /var/log/nginx/access_log;
	error_log /var/log/nginx/error_log;
	
	server_name site.com *.site.com parsing.ru.com;
	root /var/www/wordpress/$subdomain/;
    index index.php index.html index.htm;

    client_max_body_size 1000M;
	location = /xmlrpc.php {
				deny all;
				}	
				
				
	#####################################
	#Все описанные выше настройки я бы рекомендовал описать в одном файле (secure_wordpress.inc), и подключать в конфигурации каждой секции server { ... } с помощью include secure_wordpress.inc; где установлен WordPress.
	
	# Запрещаем вывод информации об авторах	
	if ($query_string ~* "author=[0-9]") {return 301 $scheme://$host/;}
	# Запрещаем доступ ко всем ULR-ам, которые содержат следующие вхождения
	location ~* /((wp-config|plugin_upload|dl-skin|uploadify|xmlrpc).php|readme.(html|txt|md)|license.(html|txt|md)|(.*)/(revslider|showbiz|infocus|awake|echelon|elegance|dejavu|persuasion|wp-filemanager|churchope|uploadify)/(.*))$ {
	  return 444;
	}
	# Запрещаем доступ ко всем URL, которые СОДЕРЖАТ следующие вхождения
	location ~* /.*((wp-config|xmlrpc).*(php(_bak|~|#)|txt|old|bak|save|orig(|inal)|swp|swo)).*$ {
	  return 444;
	}
	# Запрещаем все URL-ы, в параметрах (..?a=evil) которых есть следующие вхождения
	if ($query_string ~* "^(.*)(wp-config.php|dl-skin.php|xmlrpc.php|uploadify.php|admin-ajax.php|local.xml)(.*)quot;) {
	  return 444;
	}
	# Для противодействия SQL-инъекциям <https://habr.com/company/xakep/blog/259843/>
	if ($query_string ~* "(concat.*\(|union.*select.*\(|union.*all.*select)") {
	  return 444;
	}
	# Запрет для загруженных скриптов
	location ~* /(?:uploads|files)/.*\.(php|cgi|py|pl)$ {return 444;}
	# Запрещаем ссылки вида //blog.ru/wp/wp-content/.. и //blog.ru/page/wp-content/..
	#location ~* /(wp|page)/.*wp-.*/.*$ {return 444;}

	# Закрываем доступ к корню следующих директорий
	#location = /wp-content/ {return 404;}
	location = /wp-includes/ {return 404;}
	#location = /wp-content/plugins/ {return 404;}
	location = /wp-content/themes/ {return 404;}
	location = /wp-content/languages/ {return 404;}
	location = /wp-content/languages/plugins/ {return 404;}
	location = /wp-content/languages/themes/ {return 404;}
	# Закрываем прямой доступ у содержимому корневых директорий плагинов (для усложнения их раскрытия)
	#location ~* /wp-content/plugins/([0-9a-z\-_]+)(/|$) {return 404;}
	# Закрываем доступ к файлам перевода (для невозможности раскрыть версию WP)
	location ~ /wp-content/languages/(.+)\.(po|mo) {return 404;}
	#мы пойдем ещё чуть дальше, отсеив значительное количество различных онлайн-сканеров и веб-аналитику:
	# https://habr.com/post/168739/
	if ($http_user_agent ~* (nmap|nikto|wikto|sf|sqlmap|bsqlbf|w3af|acunetix|havij|appscan|nic.ru|monitoring|semalt|virusdie|indy|perl|php|python|wpscan|monoid.nic.ru|Web-Monitoring|semalt|Baiduspider|virusdie|wget|indy|perl)) {return 403;}
	# Блокируем конкретные юзер-агенты, в частности - пустой и "-"
	if ($http_user_agent ~ ^(|-|_)$) {return 403;}
	
	# Активно препятствуем fingerprinting-у утилиты WPScan (http://wpscan.org/)
	location = /wp-includes/css/buttons-rtl.css {
	  if ($http_referer !~* "/wp-admin") {return 404;}
	}

	location = /wp-includes/js/tinymce/wp-tinymce.js.gz {
	  if ($http_referer !~* "/wp-admin") {return 404;}
	}

	# И так же для WPScan (который запрашивая robots.txt посылает referer сайта, хотя его быть не
	# должно) закрываем доступ к этому самому robots.txt, делая вывод тулзы ещё менее информативный
	location = /robots.txt {if ($http_referer != "") {return 404;}}
	
	###############################################
					
    location / {
        #try_files $uri $uri/ /index.php?$args; 
		try_files $uri $uri/ /index.php?q=$uri&$args;		
    }
    location ~ \.php$ {
    include snippets/fastcgi-php.conf;
	#fastcgi_index /index.php;
    #fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
	fastcgi_pass unix:/run/php/php7.2-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
	location ^~ /phpmyadmin/setup/ { deny all; }
	location ^~ /phpmyadmin/libraries/ { deny all; }


	#WPMU Files
    location ~ ^/files/(.*)$ {
		try_files /wp-content/blogs.dir/$blogid/$uri /wp-includes/ms-files.php?file=$1 ;
		access_log off; log_not_found off;      expires max;
    }
 
    #WPMU x-sendfile to avoid php readfile()
    location ^~ /blogs.dir {
        internal;
        alias /var/www/example.com/htdocs/wp-content/blogs.dir;
        access_log off;     log_not_found off;      expires max;
    }	
	
}