Securitate WordPress Avansată: Nginx, Apache și Fail2Ban – Protejează wp-admin și xmlrpc.php

WordPress rămâne cel mai popular CMS, dar și unul dintre cele mai atacate. Pe lângă plugin-uri de securitate, blocarea accesului la zonele sensibile direct la nivel de server și utilizarea Fail2Ban poate face site-ul mult mai sigur.

Mai jos găsești un exemplu de configurare Nginx și Apache, cu restricții pentru IP-urile de admin și protecții împotriva atacurilor comune (XSS, SQL injection, enumerare de autori etc.)..

Principii folosite

✔ acces la admin doar din IP-uri de încredere
admin-ajax.php și admin-post.php rămân publice (necesar pentru frontend)
✔ dezactivare XML‑RPC
✔ blocare enumerare autori
✔ blocare PHP în uploads
✔ blocare fișiere sensibile
✔ protecție XSS / SQLi la nivel de webserver
✔ Fail2Ban ca layer suplimentar (firewall automat

Nginx – WordPress Security Block (per site)

Înlocuiește IP‑urile dummy cu IP‑urile reale de admin.

############################################
# WORDPRESS SECURITY BLOCK (PER-SITE)
############################################

# --- Trusted admin IPs ---
set $wp_admin_allowed 0;

# Admin IPs (dummy)
if ($remote_addr = 123.123.123.123) { set $wp_admin_allowed 1; }
if ($remote_addr = 111.111.111.111) { set $wp_admin_allowed 1; }
if ($remote_addr = 222.222.222.222) { set $wp_admin_allowed 1; }

# Server itself
if ($remote_addr = 127.0.0.1) { set $wp_admin_allowed 1; }

# PHP socket per site - CHNAGE SOCKET
set $php_sock unix:/run/php/161626534612882.sock; 

#or use set $php_sock 127.0.0.1@843; f

############################################
# BLOCK PHP EXECUTION IN wp-content
############################################
location ~* ^/wp-content/.*\.php$ {
    return 403;
}

############################################
# ADMIN AREA: /wp-admin
############################################

# Allow static assets for all
location ~ ^/wp-admin/.*\.(css|js|png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot|ico)$ {
    access_log off;
    log_not_found off;
}

# Essential PHP scripts allowed for everyone
location ~ ^/wp-admin/(admin-ajax\.php|admin-post\.php)$ {
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass $php_sock;
}

# WP Login - trusted IPs only
location = /wp-login.php {
    if ($wp_admin_allowed = 0) { return 403; }
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass $php_sock;
}

# All other PHP files in admin areas - trusted IPs only
location ~ ^/wp-admin/.*\.php$ {
    if ($wp_admin_allowed = 0) { return 403; }
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass $php_sock;
}

# Protect folders themselves (index.php)
location ~ ^/wp-admin/?$ {
    if ($wp_admin_allowed = 0) { return 403; }
    index index.php;
    try_files $uri $uri/ /index.php?$args;
}

############################################
# AUTHOR ENUMERATION
############################################
location ~* ^/author/ { return 403; }
if ($args ~* "author=\d+") { return 403; }
location ~* ^/wp-json/wp/v2/users { return 403; }

############################################
# DISABLE XML-RPC
############################################
location = /xmlrpc.php { return 403; }

############################################
# COMMON XSS / SQL INJECTION / MALICIOUS REQUESTS
############################################
location ~* "(eval\(|base64_|<script|union.*select|insert.*into|drop.*table|sleep\(|benchmark\(|information_schema|load_file|outfile|concat\()" {
    return 403;
}

############################################
# SENSITIVE FILES
############################################
location ~* ^/(wp-config\.php|readme\.html|license\.txt|\.env|composer\.json|package\.json) { return 403; }

############################################
# PHP IN UPLOADS
############################################
location ~* ^/wp-content/uploads/.*\.php$ { return 403; }

############################################
# DOTFILES & BACKUPS
############################################
location ~ /\. { return 403; }
location ~* \.(bak|old|orig|swp|sql|zip|tar|gz)$ { return 403; }

############################################
# SEO SAFE
############################################
location = /robots.txt { allow all; log_not_found off; access_log off; }
location = /sitemap.xml { allow all; log_not_found off; access_log off; }

############################################
# END WORDPRESS SECURITY BLOCK
############################################

Apache – WordPress Security Block

Funcționează pentru Apache + PHP‑FPM sau mod_php.

# -------------------------------------------
# WORDPRESS SECURITY BLOCK
# -------------------------------------------

<FilesMatch "wp-config.php|readme.html|license.txt|\.env|composer.json|package.json">
    Require all denied
</FilesMatch>

<FilesMatch "\.(bak|old|orig|swp|sql|zip|tar|gz)$">
    Require all denied
</FilesMatch>

<FilesMatch "\.php$">
    SetEnvIf Remote_Addr "^(123\.123\.123\.123|111\.111\.111\.111|222\.222\.222\.222|127\.0\.0\.1)$" WP_ADMIN_ALLOWED
</FilesMatch>

<Directory "/var/www/html/wp-admin">
    <Files "admin-ajax.php">
        Require all granted
    </Files>
    <Files "admin-post.php">
        Require all granted
    </Files>
    <FilesMatch "\.php$">
        Require env WP_ADMIN_ALLOWED
    </FilesMatch>
</Directory>

<Directory "/var/www/html/wp-content/uploads">
    <FilesMatch "\.php$">
        Require all denied
    </FilesMatch>
</Directory>

# Disable XML-RPC
<Files "xmlrpc.php">
    Require all denied
</Files>

# Disable author enumeration
RewriteEngine On
RewriteCond %{QUERY_STRING} author=\d [NC]
RewriteRule ^ /? [L,R=403]

Layer suplimentar de securitate: Fail2Ban

Nginx sau Apache pot proteja site-ul, dar atacurile brute force pot veni rapid și masiv. Fail2Ban poate monitoriza logurile web și bloca automat IP-urile care încearcă login-uri repetate sau exploit-uri.

Exemplu jail WordPress:

# /etc/fail2ban/jail.local
[wordpress]
enabled = true
port = http,https
filter = wordpress
logpath = /var/log/nginx/access.log
maxretry = 5
bantime = 3600

Astfel, chiar dacă cineva evită Nginx sau Apache, Fail2Ban blochează IP-urile suspecte la nivel de firewall.

Concluzie

🔐 Securitatea reală începe la nivel de server, nu în plugin-uri
🧱 Nginx / Apache = primul zid
🔥 Fail2Ban = al doilea zid
🧠 WordPress vede doar trafic deja filtrat

Ne concentrăm pe consilierea întreprinderilor cu privire la cea mai bună utilizare a tehnologiei informației pentru a vă îndeplini obiectivele de afaceri.