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;
}
}