Proper log management is essential for monitoring server activity, debugging issues, and identifying
security threats. NGINX and PHP-FPM logs provide valuable insights into your server's operations.
Viewing NGINX Logs
Navigate to the NGINX log directory and view log files:
cd /var/log/nginx
ls
sudo cat log_file_name.log
sudo less log_file_name.log
Tip: Use less for large log files as it allows pagination and search
functionality.
2. PHP-FPM Pool Configuration
PHP-FPM pools allow you to run multiple PHP applications with different users and configurations,
enhancing security and resource management.
PHP-FPM Pool Architecture
NGINX Web Server
↓
Unix Socket Communication
↓
PHP-FPM Pool (example.com)
↓
PHP Application
Step 1: Create System User
Create a dedicated user for your website to improve security isolation:
sudo useradd username
Step 2: Configure User Groups
Add users to appropriate groups for proper permissions:
sudo usermod -a -G username_group www-data
sudo usermod -a -G www-data username_group
sudo usermod -a -G username_group $USER
Step 3: Create PHP-FPM Pool Configuration
Navigate to the PHP-FPM pool directory and create a new configuration:
cd /etc/php/8.3/fpm/pool.d/
ls
sudo cp www.conf example.com.conf
sudo nano example.com.conf
Essential Pool Configuration
; Start a new pool named 'example'
[example]
; Unix user/group of the child processes
user = username
group = username
; The address on which to accept FastCGI requests
listen = /run/php/php8.3-fpm-example.com.sock
; Set open file descriptor rlimit
rlimit_files = 15000
; Set max core size rlimit
rlimit_core = 100
; PHP error logging configuration
php_flag[display_errors] = off
php_admin_value[error_log] = /var/log/fpm-php.example.com.log
php_admin_flag[log_errors] = on
Step 4: Create FPM Log File
Create and configure the PHP-FPM log file with proper permissions:
Note: Use reuseport only on the first server block listening on port 443.
Additional server blocks should omit this directive.
Testing HTTP/3 Configuration
Disable browser caching temporarily to test HTTP/3:
location / {
# Prevents browser caching - use only for testing
add_header Cache-Control 'no-cache,no-store';
# Remove after confirming HTTP/3 is enabled
}
Add HTTP_HOST Parameter
Include the HTTP_HOST parameter in PHP processing:
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_param HTTP_HOST $host;
fastcgi_pass unix:/run/php/php8.3-fpm-example.com.sock;
include /etc/nginx/includes/fastcgi_optimize.conf;
}
Test SSL/TLS Configuration
curl -I http://example.com
curl -I http://www.example.com
curl -I https://www.example.com
curl -I https://example.com
Test and Reload NGINX
sudo nginx -t
sudo systemctl reload nginx
Verification Tools
Tool
Purpose
URL
SSL Labs
SSL/TLS Configuration Testing
https://www.ssllabs.com/ssltest/
HTTP/3 Check
Verify HTTP/3 Support
https://http3check.net/
Browser DevTools
Network Protocol Inspection
Console → Network → Protocol Column
Browser Verification: In Chrome/Edge DevTools, enable the "Protocol" column in the
Network tab. Look for "h3" indicating HTTP/3 is active.
5. Security Headers
HTTP security headers protect your website from common vulnerabilities such as clickjacking, XSS, and
MIME-type sniffing attacks.
Certificate Management with Certbot
Certbot Commands Reference
Command
Description
sudo certbot certificates
List all certificates
sudo certbot delete
Delete a certificate
sudo certbot renew
Renew certificates
sudo certbot renew --force-renewal
Force certificate renewal
Automated SSL Certificate Renewal
Configure automatic renewal using cron jobs:
sudo crontab -e
# Renew certificates on the 14th and 28th of each month at 1:00 AM
00 1 14,28 * * certbot renew --force-renewal
# Reload NGINX at 2:00 AM after renewal
00 2 14,28 * * systemctl reload nginx
cd /var/www/example.com/public_html/wp-content/plugins/
sudo rm test556.php
Security Note: Only allow PHP execution for specific, trusted plugin files. Always use
exact path matching with location =.
Additional WordPress Security
Add to your wp-config.php file to disable file modifications:
define('DISALLOW_FILE_MODS', true);
sudo systemctl reload php8.3-fpm
7. Rate Limiting
Rate limiting protects your server from brute-force attacks, DDoS attempts, and excessive resource
consumption by limiting the number of requests from a single IP address.
# Rate limit wp-login.php to prevent brute-force attacks
location = /wp-login.php {
limit_req zone=wp burst=20 nodelay;
limit_req_status 444;
include snippets/fastcgi-php.conf;
fastcgi_param HTTP_HOST $host;
fastcgi_pass unix:/run/php/php8.3-fpm-example.com.sock;
include /etc/nginx/includes/fastcgi_optimize.conf;
}
# Rate limit XML-RPC to prevent DDoS attacks
location = /xmlrpc.php {
limit_req zone=wp burst=20 nodelay;
limit_req_status 444;
include snippets/fastcgi-php.conf;
fastcgi_param HTTP_HOST $host;
fastcgi_pass unix:/run/php/php8.3-fpm-example.com.sock;
include /etc/nginx/includes/fastcgi_optimize.conf;
}
Step 3: Include Rate Limiting in Site Configuration
cd /etc/nginx/sites-available/
sudo nano example.com.conf
Add in the server block:
# Rate Limiting Include
include /etc/nginx/includes/rate_limiting_example.com.conf;
sudo nginx -t
sudo systemctl reload nginx
Rate Limiting Parameters Explained
Parameter
Description
Value
zone=wp
Name of the rate limit zone
10m memory allocation
rate=30r/m
Maximum request rate
30 requests per minute
burst=20
Allow burst of requests
20 additional requests
nodelay
Process burst immediately
No queueing delay
limit_req_status
Status code for rejected requests
444 (close connection)
Recommendation: Monitor your logs after implementing rate limiting to ensure legitimate
users are not being blocked. Adjust rates as needed for your specific traffic patterns.
8. Web Application Firewall (Ninja Firewall)
A Web Application Firewall (WAF) provides an additional security layer by intercepting and filtering
HTTP/HTTPS requests before they reach your WordPress application. NinjaFirewall is a powerful,
lightweight WAF specifically designed for WordPress.
Ninja Firewall Architecture
HTTP/HTTPS Request
↓
NGINX Web Server
↓
PHP-FPM
↓
🛡️ Ninja Firewall (Hook/Scan/Filter)
↓
Allow → WordPress Core
Deny → Block Request
Key Features of Ninja Firewall
True Web Application Firewall: Intercepts requests before they reach WordPress
Low Resource Usage: Minimal CPU and memory footprint
Comprehensive Protection: Protects all scripts, including plugins, themes, and
custom code
Encoded Script Detection: Identifies and blocks obfuscated malicious code
Multiple Protection Modes: Basic, Intermediate, and Advanced policies
Real-time Monitoring: Live traffic monitoring and threat detection
Event Logging: Detailed logs of blocked requests and security events
Installation Steps
Step 1: Access WordPress Admin Dashboard
Navigate to your WordPress admin area:
https://example.com/wp-admin/
Step 2: Install Ninja Firewall Plugin
Click on Plugins in the left sidebar
Click Add New Plugin
Search for "NinjaFirewall" in the search box
Locate NinjaFirewall (WP Edition)
Click Install Now
Wait for installation to complete
Prerequisites: Before activating NinjaFirewall, ensure your file permissions are
correctly set to allow the plugin to create and modify the .user.ini file.
Step 3: Verify File Permissions
Check for existing hidden files in document root:
cd /var/www/example.com/public_html/
ls -la
Ensure permissions are set correctly:
sudo find /var/www/example.com/public_html/ -type d -exec chmod 770 {} \;
sudo find /var/www/example.com/public_html/ -type f -exec chmod 660 {} \;
Step 4: Activate Ninja Firewall
Return to WordPress admin dashboard
Navigate to Plugins → Installed Plugins
Locate NinjaFirewall (WP Edition)
Click Activate
Step 5: Initial Configuration Wizard
After activation, NinjaFirewall will guide you through initial setup:
Welcome Screen: Click "Got it" to proceed
Enable Firewall: Firewall is enabled by default
Select Mode: Choose Full WAF Mode
HTTP Server: Select Nginx + CGI/FastCGI or PHP-FPM
PHP Initialization File: Select .user.ini
Protected Folders: Verify all directories are listed
Enable Sandbox: Click to enable sandboxed environment
Finish Installation: Complete setup wizard
Success: Ninja Firewall is now running in Full WAF Mode, providing comprehensive
protection for your WordPress site.
Configuration Overview
Access Ninja Firewall Dashboard
Navigate to: WordPress Admin → NinjaFirewall → Dashboard
Main Configuration Areas
Section
Purpose
Recommendation
Firewall Options
Core firewall settings
Review before modifying
Firewall Policies
Protection level configuration
Start with Basic, increase gradually
Basic Policies
Fundamental security rules
Enable recommended settings
Intermediate Policies
Enhanced protection rules
Test on staging first
Advanced Policies
Maximum security rules
Use with caution
Live Log
Real-time request monitoring
Monitor after configuration changes
Event Notifications
Alert configuration
Set up email notifications
Important Considerations
Testing Protocol:
Always test configuration changes on a development or staging server first
Monitor live logs for false positives after making changes
Gradually increase security policies from Basic to Intermediate to Advanced
Document all configuration changes
Keep backup of working configurations
Documentation and Support
Access comprehensive documentation through the NinjaFirewall dashboard:
WordPress Admin → NinjaFirewall → Dashboard → Help and Configuration
The documentation covers:
Detailed explanation of all options and features
Security best practices for WordPress
Configuration examples for common scenarios
Troubleshooting common issues
Performance optimization tips
Integration with other security plugins
Recommended Initial Settings
Start with Conservative Settings
Operating Mode: Full WAF Mode
Firewall Policies: Basic level
Log Level: Medium (monitor for 1-2 weeks)
Email Notifications: Enable for critical events
IP Whitelist: Add your administrative IP addresses
After Stabilization Period (2-4 weeks)
Review logs for false positives
Adjust policies based on your site's specific needs
Gradually increase to Intermediate policies
Consider Advanced policies for high-security requirements
Fine-tune notification thresholds
Best Practice: Ninja Firewall provides an excellent balance between security and
performance. Regular monitoring and gradual policy adjustments will ensure optimal protection without
interfering with legitimate site functionality.
9. Database Privileges
Implementing the principle of least privilege for database users enhances security by limiting potential
damage from compromised credentials or SQL injection attacks.
Understanding Database Privileges
WordPress requires specific database operations for normal functionality. By restricting privileges to
only necessary operations, you reduce the attack surface.
Database Security Model
WordPress Application
↓
Database User (Limited Privileges)
↓
MySQL/MariaDB Server
↓
WordPress Database
Standard WordPress Database Privileges
Step 1: Revoke All Existing Privileges
REVOKE ALL PRIVILEGES ON site_db.* FROM 'site_user'@'hostname';
Step 2: Grant Essential Privileges
For normal WordPress operation, grant only these privileges:
GRANT SELECT, INSERT, UPDATE, DELETE ON site_db.* TO 'site_user'@'hostname';
Step 3: Apply Changes
FLUSH PRIVILEGES;
Additional Privileges for Plugin Installation
When installing plugins or themes that modify database structure, temporarily grant additional
privileges:
GRANT CREATE, ALTER, INDEX ON site_db.* TO 'site_user'@'hostname';
FLUSH PRIVILEGES;
Security Recommendation: After completing plugin/theme installation, revoke these
additional privileges and return to the minimal privilege set.
Database Privilege Reference
Privilege
Purpose
Required For
SELECT
Read data from tables
Standard operations ✓
INSERT
Add new records
Standard operations ✓
UPDATE
Modify existing records
Standard operations ✓
DELETE
Remove records
Standard operations ✓
CREATE
Create new tables
Plugin installation only
ALTER
Modify table structure
Plugin installation only
INDEX
Create/modify indexes
Plugin installation only
DROP
Delete tables
❌ Not recommended
Complete Privilege Management Example
Initial Setup (Minimal Privileges)
-- Connect to MySQL
mysql -u root -p
-- Switch to WordPress database
USE wordpress_db;
-- Revoke all privileges
REVOKE ALL PRIVILEGES ON wordpress_db.* FROM 'wp_user'@'localhost';
-- Grant minimal required privileges
GRANT SELECT, INSERT, UPDATE, DELETE ON wordpress_db.* TO 'wp_user'@'localhost';
-- Apply changes
FLUSH PRIVILEGES;
-- Exit MySQL
EXIT;
Temporary Extension for Plugin Installation
-- Grant additional privileges for installation
GRANT CREATE, ALTER, INDEX ON wordpress_db.* TO 'wp_user'@'localhost';
FLUSH PRIVILEGES;
-- After installation, revoke additional privileges
REVOKE CREATE, ALTER, INDEX ON wordpress_db.* FROM 'wp_user'@'localhost';
FLUSH PRIVILEGES;
Verifying Current Privileges
Check what privileges are currently granted to a user:
SHOW GRANTS FOR 'wp_user'@'localhost';
Multiple Database Users Strategy
For enhanced security, consider using separate database users for different purposes:
User Type
Privileges
Use Case
wp_user
SELECT, INSERT, UPDATE, DELETE
Normal site operation
wp_admin
SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, INDEX
Plugin/theme installation
wp_backup
SELECT
Backup operations only
Configuration Tip: When using separate database users, configure wp-config.php to use
the appropriate credentials based on the operation being performed. This can be automated through
environment-specific configuration files.
Additional Security Measures
1. Regular Privilege Audits
Periodically review and audit database user privileges:
-- List all users and their privileges
SELECT user, host FROM mysql.user;
-- Check specific user privileges
SHOW GRANTS FOR 'wp_user'@'localhost';
2. Connection Security
Ensure database connections are secure:
Use localhost connections when database and web server are on same machine
Implement SSL/TLS for remote database connections
Use strong, unique passwords for database users
Regularly rotate database passwords
3. WordPress Configuration
Disable automatic database repairs in production:
// In wp-config.php
define('WP_ALLOW_REPAIR', false);
Security Benefit: Implementing minimal database privileges significantly reduces the
potential impact of SQL injection attacks and compromised database credentials, protecting your
WordPress installation and data.