Как настроить Nginx для WordPress: безопасный и быстрый конфиг с нуля

Стандартный конфиг Nginx для WordPress часто копируют с первого попавшегося сайта, не понимая, что там написано. В этой статье — разобранный по блокам конфиг с объяснением каждой директивы: производительность, безопасность, кеширование статики и корректная работа permalink.

Базовый конфиг для WordPress

server {
    listen 80;
    server_name karoche.ru www.karoche.ru;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name karoche.ru www.karoche.ru;

    root /home/b/site/public_html;
    index index.php;

    # SSL
    ssl_certificate     /etc/letsencrypt/live/karoche.ru/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/karoche.ru/privkey.pem;
    ssl_protocols       TLSv1.2 TLSv1.3;
    ssl_ciphers         HIGH:!aNULL:!MD5;
    ssl_session_cache   shared:SSL:10m;

    # Логи
    access_log /var/log/nginx/karoche.access.log;
    error_log  /var/log/nginx/karoche.error.log warn;

    # Charset
    charset utf-8;

    # Базовый лимит тела запроса (для загрузки файлов в WP)
    client_max_body_size 64M;

    # Главное правило WordPress: если файл не существует — отдаём в index.php
    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    # PHP через PHP-FPM
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
        fastcgi_read_timeout 120;
        fastcgi_buffers 16 16k;
        fastcgi_buffer_size 32k;
    }

    # Кеширование статики
    location ~* \.(css|js|png|jpg|jpeg|gif|webp|ico|svg|woff|woff2|ttf|eot)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
        access_log off;
        try_files $uri =404;
    }

    # Запрет доступа к скрытым файлам (.git, .env и т.д.)
    location ~ /\. {
        deny all;
    }

    # Блокировка wp-config.php
    location = /wp-config.php {
        deny all;
    }

    # Блокировка XML-RPC (если не нужен)
    location = /xmlrpc.php {
        deny all;
        return 403;
    }

    # Защита загруженных файлов от выполнения PHP
    location ~* /uploads/.*\.php$ {
        deny all;
        return 403;
    }
}

Разбор по блокам

Строка try_files $uri $uri/ /index.php?$args — ключевая для WordPress. Она говорит Nginx: попробуй отдать файл, потом директорию, иначе передай запрос в index.php. Без неё красивые URL не работают.

Защита /uploads/ от PHP

Блок location ~* /uploads/.*\.php$ закрывает известную уязвимость: если злоумышленник загрузил PHP-файл через форму, этот блок не даст его выполнить.

XML-RPC

xmlrpc.php используется для атак брутфорсом и DDoS. Если вы не используете мобильное приложение WordPress или Jetpack — заблокируйте его полностью.

Добавление FastCGI-кеша

FastCGI Cache — серверный кеш страниц на уровне Nginx, работает быстрее любого WordPress-плагина:

# В http блоке nginx.conf
fastcgi_cache_path /var/cache/nginx levels=1:2
                   keys_zone=wp_cache:100m
                   inactive=60m
                   max_size=1g;

# В server блоке
set $skip_cache 0;

# Пропускаем кеш для авторизованных и страниц корзины/оформления
if ($request_method = POST)         { set $skip_cache 1; }
if ($query_string != "")            { set $skip_cache 1; }
if ($http_cookie ~* "wordpress_logged_in") { set $skip_cache 1; }
if ($request_uri ~* "/cart/|/checkout/|/wp-admin/") { set $skip_cache 1; }

location ~ \.php$ {
    fastcgi_cache          wp_cache;
    fastcgi_cache_valid     200 60m;
    fastcgi_cache_bypass   $skip_cache;
    fastcgi_no_cache       $skip_cache;
    add_header             X-FastCGI-Cache $upstream_cache_status;
    # ... остальные fastcgi параметры
}

Заголовки безопасности

add_header X-Frame-Options "SAMEORIGIN"           always;
add_header X-Content-Type-Options "nosniff"        always;
add_header X-XSS-Protection "1; mode=block"        always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=()" always;

Проверка конфига

# Проверить синтаксис
nginx -t

# Перезагрузить без остановки
systemctl reload nginx

Итог

Хороший Nginx-конфиг для WordPress включает: правильный try_files, блокировку xmlrpc.php и выполнения PHP в uploads, кеширование статики на год, заголовки безопасности. FastCGI Cache опционально, но даёт кратный прирост производительности.