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