Rollin Logo
Server Security Hardening for Drupal: Your Complete 2025 Guide

Server Security Hardening for Drupal: Your Complete 2025 Guide

Alex Rollin
Alex Rollin
2025-06-16
Last update: 2025-06-18
Your Drupal site might have the latest security patches and strong passwords, but if your server is vulnerable, none of that matters. A compromised server can lead to data theft, malware infections, or complete site takeover—regardless of how well you've secured Drupal itself.

This guide walks you through the essential steps to harden your server for Drupal 11.x. You'll learn what to do, why it matters, and how to implement each security measure effectively.

Why Server Security Hardening Matters More Than You Think for Drupal CMS

Server vulnerabilities create multiple attack vectors that bypass your Drupal security entirely. Attackers can:

  • Access your database directly
  • Inject malicious code into your files
  • Steal sensitive data before it reaches Drupal
  • Use your server to attack other systems

The 2024 Drupal security report showed that 73% of compromised Drupal sites had server-level vulnerabilities, not application-level ones. This means your first line of defense isn't your Drupal configuration—it's your server setup.

Step 1: Keep Your Drupal Software Stack Current and Updated

Start with your foundation: outdated software is the easiest target for attackers.

Update Drupal Core and Security Modules

Check for updates weekly, not monthly. Set up automatic notifications:

# Enable update notifications in Drupal
drush pm:enable update
drush updatedb

Always remove unused modules and themes. Each installed component increases your attack surface, even if it's disabled.

Maintain Your Server Software Stack

Use Long-Term Support (LTS) versions when possible:

  • Ubuntu 24.04 LTS or RHEL 9 for your OS
  • PHP 8.2 or 8.3 (avoid older versions)
  • MariaDB 10.11 or PostgreSQL 15 
  • Nginx 1.24 or Apache 2.4.57 

Set up automatic security updates for your OS:

# Ubuntu/Debian
sudo apt install unattended-upgrades
sudo dpkg-reconfigure unattended-upgrades

# CentOS/RHEL
sudo yum install yum-cron
sudo systemctl enable yum-cron

Step 2: Implement HTTPS SSL Certificate and Security Headers

Install SSL/TLS Certificates for Drupal

Use Let's Encrypt for free certificates or purchase commercial ones for business sites:

# Install Certbot
sudo apt install certbot python3-certbot-nginx

# Get certificate
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

Configure Security Headers for Drupal Sites

Add these headers to your Nginx configuration:

server {
    listen 443 ssl http2;
    server_name yourdomain.com;

    # Security headers
    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 Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
}

Test your headers using Mozilla Observatory to ensure they're working correctly.

Step 3: Secure User Access and Authentication for Drupal Admin

Enable Two-Factor Authentication for Drupal

Install the TFA module for admin accounts:

composer require drupal/tfa
drush en tfa

Configure it to require 2FA for all users with administrative roles.

Set Strong Password Policies in Drupal

Use the Password Policy module:

composer require drupal/password_policy
drush en password_policy

Configure minimum requirements:

  • 12 characters minimum
  • Mix of uppercase, lowercase, numbers, and symbols
  • No common passwords or dictionary words
  • No reuse of last 5 passwords

Limit User Permissions in Drupal CMS

Review user roles monthly. Remove permissions that users don't actively need. Create specific roles for different tasks instead of giving everyone administrative access.

Step 4: Harden File and Directory Permissions for Drupal Sites

Set Correct File Permissions for Drupal

Your Drupal files need specific permissions to function securely:

# Set file permissions
find /var/www/html -type f -exec chmod 644 {} \;

# Set directory permissions
find /var/www/html -type d -exec chmod 755 {} \;

# Secure sensitive files
chmod 400 /var/www/html/sites/default/settings.php
chmod 400 /var/www/html/sites/default/services.yml

Prevent PHP Execution in Upload Directories

Add this to your .htaccess file in the files directory:

    Require all denied

For Nginx, add this to your server block:

location ~* ^/sites/.*/files/.*\.php$ {
    deny all;
}

Move Private Files Outside Web Root

Configure private file storage outside your web directory:

// In settings.php
$settings['file_private_path'] = '/var/drupal/private';

Create the directory and set permissions:

sudo mkdir -p /var/drupal/private
sudo chown www-data:www-data /var/drupal/private
sudo chmod 755 /var/drupal/private

Step 5: Configure Web Server Security for Drupal Hosting

Disable Directory Listings

For Apache, add this to your configuration:

Options -Indexes

For Nginx:

autoindex off;

Restrict Access to Sensitive Drupal Files

Block access to Drupal's administrative files:

# Apache .htaccess

    Require ip 127.0.0.1
    Require ip ::1

# Nginx location ~ ^/(cron|install|update|authorize)\.php$ { allow 127.0.0.1; allow ::1; deny all; try_files $uri =404; fastcgi_pass unix:/var/run/php/php8.2-fpm.sock; fastcgi_index index.php; include fastcgi_params; }

Step 6: Harden PHP Configuration for Drupal Performance

Disable Dangerous PHP Functions

Edit your php.ini file:

disable_functions = exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source

Set Security Directives for PHP

expose_php = Off
allow_url_fopen = Off
allow_url_include = Off
enable_dl = Off
display_errors = Off
log_errors = On
max_execution_time = 30
max_input_time = 30
memory_limit = 256M
upload_max_filesize = 10M
post_max_size = 10M

Configure Open Basedir for Drupal

Restrict PHP to your Drupal directory:

open_basedir = /var/www/html:/tmp:/var/tmp

Step 7: Secure Your Drupal Database Configuration

Create a Restricted Database User for Drupal

Don't use the root user for Drupal. Create a specific user with minimal permissions:

CREATE USER 'drupal_user'@'localhost' IDENTIFIED BY 'strong_password_here';
CREATE DATABASE drupal_db;
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, LOCK TABLES ON drupal_db.* TO 'drupal_user'@'localhost';
FLUSH PRIVILEGES;

Bind Database to Localhost

In your MySQL configuration (/etc/mysql/mysql.conf.d/mysqld.cnf):

bind-address = 127.0.0.1

Change the Default Table Prefix

In your Drupal settings.php:

$databases['default']['default']['prefix'] = 'dp_';

This makes SQL injection attacks harder by obscuring standard table names.

Step 8: Configure Network Security for Drupal Server

Set Up a Firewall for Drupal Hosting

Configure UFW (Uncomplicated Firewall) on Ubuntu:

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp  # SSH
sudo ufw allow 80/tcp  # HTTP
sudo ufw allow 443/tcp # HTTPS
sudo ufw enable

Harden SSH Access for Drupal Server

Edit /etc/ssh/sshd_config:

Port 2222  # Change from default 22
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
ClientAliveInterval 300
ClientAliveCountMax 2

Install and configure Fail2ban to block brute force attempts:

sudo apt install fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

Step 9: Implement Monitoring and Logging for Drupal Security

Set Up Centralized Logging

Configure rsyslog to collect all security events:

# In /etc/rsyslog.d/50-drupal.conf
local0.*    /var/log/drupal.log

Install Security Monitoring Tools

Set up file integrity monitoring with AIDE:

sudo apt install aide
sudo aide --init
sudo mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db

Create a daily cron job to check for changes:

# Add to crontab
0 2 * * * /usr/bin/aide --check

Monitor Failed Login Attempts in Drupal

Use the Login Security module:

composer require drupal/login_security
drush en login_security

Configure it to block IP addresses after 5 failed attempts.

Step 10: Automate Backups and Recovery for Drupal Sites

Set Up Automated Drupal Backups

Create a backup script that runs daily:

#!/bin/bash
# backup-drupal.sh

DATE=$(date  %Y%m%d_%H%M%S)
BACKUP_DIR="/var/backups/drupal"
DRUPAL_ROOT="/var/www/html"
DB_NAME="drupal_db"
DB_USER="drupal_user"
DB_PASS="your_password"

mkdir -p $BACKUP_DIR

# Backup database
mysqldump -u$DB_USER -p$DB_PASS $DB_NAME | gzip > $BACKUP_DIR/db_$DATE.sql.gz

# Backup files
tar -czf $BACKUP_DIR/files_$DATE.tar.gz -C $DRUPAL_ROOT sites/default/files

# Keep only last 7 days of backups
find $BACKUP_DIR -name "*.gz" -mtime  7 -delete

Test Your Drupal Backups

Create a staging environment and regularly test backup restoration. A backup you can't restore is worthless.

Common Drupal Security Mistakes to Avoid

Running services as root: Always use dedicated users with minimal permissions.

Ignoring log files: Set up log monitoring and review them regularly.

Using default ports: Change SSH and other service ports from defaults.

Skipping security updates: Apply security patches within 24-48 hours of release.

Weak file permissions: Regularly audit and correct file permissions.

Your Next Steps for Drupal Server Hardening

  • Audit your current setup using the Security Review module
  • Implement these changes gradually to avoid breaking your site
  • Test each change in a staging environment first
  • Document your security configuration for future reference
  • Set up monitoring alerts for security events
  • Schedule regular security reviews monthly

Server security isn't a one-time setup—it's an ongoing process. Start with the most critical items (HTTPS, updates, and backups) and work through the rest systematically. Your Drupal site will be much more secure with a properly hardened server foundation.

Remember: the best security strategy combines multiple layers of protection. No single measure will protect you from all threats, but implementing these steps together creates a robust defense system that makes your Drupal site a much harder target for attackers.

Share this article

Ready to start
your project?

Our development team is ready to transform your vision into reality and bring your next innovation to life.