An Auditor’s Checklist for Securing Magento 2 Backends on Linode
I. Server-Level Hardening & Linode Configuration
Before diving into Magento-specific configurations, a robust server foundation is paramount. This section outlines essential Linode-specific and general server hardening steps that an auditor would scrutinize.
A. SSH Access Control
Restrict SSH access to authorized IP addresses and disable root login. This is a fundamental security measure to prevent brute-force attacks.
Edit the SSH daemon configuration file:
sudo nano /etc/ssh/sshd_config
Ensure the following directives are set:
PermitRootLogin no PasswordAuthentication no AllowUsers your_admin_user another_allowed_user AllowGroups sshusers # If using key-based auth, ensure PubkeyAuthentication yes # If you have specific IPs that need access, use: # AllowTcpForwarding no # X11Forwarding no
After modifying the configuration, restart the SSH service:
sudo systemctl restart sshd
Auditor Check: Verify that PermitRootLogin is set to no and that PasswordAuthentication is no if key-based authentication is enforced. Check the AllowUsers or AllowGroups directives for strict access control.
B. Firewall Configuration (UFW)
Utilize Uncomplicated Firewall (UFW) for granular control over network traffic. Only essential ports should be open.
Enable UFW and set default policies:
sudo ufw enable sudo ufw default deny incoming sudo ufw default allow outgoing
Allow necessary ports (SSH, HTTP, HTTPS):
sudo ufw allow ssh sudo ufw allow http sudo ufw allow https
If you have specific IP restrictions for SSH, you can configure them:
sudo ufw allow from YOUR_SECURE_IP to any port 22 proto tcp
Check the status:
sudo ufw status verbose
Auditor Check: Confirm that only necessary ports (typically 22, 80, 443) are open. Verify that the default policy is to deny incoming traffic. If specific IPs are allowed for SSH, ensure they are correctly configured.
C. Fail2Ban for Brute-Force Protection
Implement Fail2Ban to automatically block IPs that show malicious signs, such as too many password failures.
Install Fail2Ban:
sudo apt update && sudo apt install fail2ban -y
Create a local configuration file to override defaults:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Edit jail.local to configure bantime, findtime, and maxretry. Enable specific jails, particularly for SSH and web server logs.
[DEFAULT] bantime = 1h findtime = 10m maxretry = 5 ignoreip = 127.0.0.1/8 YOUR_ADMIN_IP [sshd] enabled = true port = ssh filter = sshd logpath = /var/log/auth.log maxretry = 3 [nginx-http-auth] enabled = true port = http,https filter = nginx-http-auth logpath = /var/log/nginx/error.log maxretry = 3 [wordpress] # Example for WordPress, adapt for Magento if a specific filter exists or create one enabled = false # Set to true if a Magento filter is available/created logpath = /var/log/apache2/error.log # Adjust log path as needed
Restart Fail2Ban:
sudo systemctl restart fail2ban
Check status and active jails:
sudo fail2ban-client status sudo fail2ban-client status sshd
Auditor Check: Verify that Fail2Ban is installed and running. Inspect jail.local for appropriate bantime, findtime, and maxretry settings. Confirm that relevant jails (especially SSH) are enabled and configured with correct log paths. Check the ignoreip list for authorized IPs.
II. Magento 2 Backend Security Best Practices
This section focuses on securing the Magento application itself, from file permissions to administrative access and configuration settings.
A. File Permissions and Ownership
Incorrect file permissions are a common vulnerability. Magento requires specific ownership and permissions for its directories and files to operate securely and efficiently.
The web server user (e.g., www-data for Apache/Nginx on Debian/Ubuntu, nginx for Nginx on CentOS/RHEL) should own the Magento files. The Magento application itself should not run as root.
Set ownership (replace www-data:www-data with your web server user and group):
sudo chown -R www-data:www-data /var/www/html/magento2
Set directory permissions (755 for directories):
sudo find /var/www/html/magento2 -type d -exec chmod 755 {} \;
Set file permissions (644 for files):
sudo find /var/www/html/magento2 -type f -exec chmod 644 {} \;
Crucially, set specific permissions for directories that require write access by the web server, such as var/, media/, and app/etc/. These should be writable by the web server user.
sudo chown -R www-data:www-data /var/www/html/magento2/var sudo chown -R www-data:www-data /var/www/html/magento2/media sudo chown -R www-data:www-data /var/www/html/magento2/app/etc
Auditor Check: Verify that the web server user owns all Magento files. Confirm that directories have 755 permissions and files have 644 permissions, with specific exceptions for writable directories (var/, media/, app/etc/) which should be owned by the web server user and have appropriate write permissions (e.g., 775 if group write is needed, but generally 755 for directories and 644 for files is sufficient if the web server user is the owner).
B. Admin URL and Access Control
The default Magento admin URL (/admin) is a prime target. Changing it and implementing strong access controls is vital.
Change the admin URL via the command line:
cd /var/www/html/magento2 sudo php bin/magento setup:config:set --backend-frontname="your_secure_admin_path" sudo php bin/magento cache:flush
Auditor Check: Confirm that the admin URL has been changed from the default. This can be verified by attempting to access /admin and ensuring it redirects or shows an error, while the new path works.
C. Two-Factor Authentication (2FA) for Admin Users
Enforce Two-Factor Authentication for all Magento administrative users. This significantly mitigates the risk of compromised credentials.
Magento 2.4.4 and later include built-in 2FA. Ensure it’s enabled and enforced.
Navigate to Stores > Configuration > Advanced > Admin Security.
Under the “Two-Factor Authentication” section:
- Set “Enable Two-Factor Authentication” to Yes.
- Under “Enable Two-Factor Authentication for Admin Roles”, select the roles for which 2FA should be mandatory.
Save the configuration.
Auditor Check: Verify that 2FA is enabled in the Magento configuration. Check that it is enforced for all administrative roles. Attempt to log in as an admin user to confirm the 2FA prompt appears.
D. Secure Admin User Passwords and Roles
Implement a strong password policy for admin users and adhere to the principle of least privilege when assigning roles.
Password Policy:
- Navigate to Stores > Configuration > Advanced > Admin Security.
- Under “Password Policy”, configure minimum length, required character classes (uppercase, lowercase, numbers, symbols), and lockout thresholds.
Role-Based Access Control:
- Navigate to System > Permissions > Administrator Roles.
- Review existing roles and ensure they grant only the necessary permissions. Create granular roles for specific tasks.
- For example, a user who only needs to manage products should not have permissions to manage users or system configuration.
Auditor Check: Review the password policy settings for strength and lockout mechanisms. Audit all administrator accounts and their assigned roles. Ensure that roles follow the principle of least privilege and that no administrator has excessive permissions.
E. Disabling Debug Mode in Production
Debug mode exposes sensitive information and should never be enabled on a production environment.
Check the app/etc/env.php file. The MAGE_MODE should be set to production.
<?php
return [
'backend' => [
'frontname' => 'your_secure_admin_path'
],
'crypt' => [
'key' => 'your_generated_encryption_key'
],
'db' => [
'table_prefix' => '',
'connection' => [
'default' => [
'host' => 'localhost',
'dbname' => 'magento_db',
'username' => 'magento_user',
'password' => 'db_password',
'model' => 'mysql4',
'initStatements' => 'SET NAMES utf8',
'engine' => 'innodb',
'active' => 1
]
]
],
'resource' => [
'default_setup' => [
'connection' => 'default'
]
],
'x-frame-options' => 'SAMEORIGIN',
'MAGE_MODE' => 'production', // Ensure this is set to 'production'
'session' => [
'save' => 'files'
]
];
If it’s set to developer or default, change it to production and clear the cache.
sudo php bin/magento deploy:mode:set:production sudo php bin/magento cache:flush
Auditor Check: Verify that MAGE_MODE in app/etc/env.php is set to production. Confirm that no developer-specific configurations or debugging tools are active.
III. Web Server and Database Security
Securing the web server (Nginx) and database (MySQL/MariaDB) is critical for protecting the Magento backend and its data.
A. Nginx Configuration for Security
Nginx configuration plays a significant role in preventing common web attacks.
Disable Directory Listing:
location ~* /(app|bin|dev|lib|pub/static/_requirejs|var)/ {
deny all;
}
Prevent Access to Sensitive Files:
location ~* /(composer\.json|composer\.lock|\.htaccess|\.git|\.svn|nginx\.conf|apache\.conf|\.env|\.env\.php|php\.ini|\.user\.ini|README\.md|LICENSE\.txt)$ {
deny all;
return 404;
}
Secure Magento Core Files:
location ~* ^/(app/etc|bin/Magento|lib|var)/ {
deny all;
}
Protect app/etc/env.php:
location ~* ^/app/etc/env\.php$ {
deny all;
return 404;
}
Enable HTTP Strict Transport Security (HSTS):
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
Disable Server Signature:
server_tokens off;
After modifying Nginx configuration files (e.g., /etc/nginx/sites-available/your_magento_site), test the configuration and reload Nginx:
sudo nginx -t sudo systemctl reload nginx
Auditor Check: Review the Nginx virtual host configuration for Magento. Verify that sensitive directories and files are denied access. Ensure HSTS is enabled and server tokens are turned off.
B. MySQL/MariaDB Security
Secure the database by restricting access and using strong credentials.
Use a Dedicated Database User:
Do not use the root MySQL user for Magento. Create a specific user with minimal privileges required for Magento.
CREATE USER 'magento_user'@'localhost' IDENTIFIED BY 'your_strong_password'; GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, INDEX, DROP, EXECUTE, SHOW VIEW ON magento_db.* TO 'magento_user'@'localhost'; FLUSH PRIVILEGES;
Secure MySQL Configuration:
Edit the MySQL configuration file (e.g., /etc/mysql/mysql.conf.d/mysqld.cnf or /etc/my.cnf).
[mysqld] # Bind to localhost only if the web server is on the same machine bind-address = 127.0.0.1 # Disable remote root login skip-networking = false # If you need remote access, ensure bind-address is specific # Or if bind-address is 127.0.0.1, remote access is already restricted. # For enhanced security, consider disabling root login entirely for remote connections. # secure_file_priv = /var/lib/mysql-files # Restrict LOAD DATA INFILE and SELECT ... INTO OUTFILE
Restart MySQL after changes:
sudo systemctl restart mysql
Auditor Check: Verify that Magento uses a dedicated database user with the minimum necessary privileges. Confirm that the MySQL server is configured to bind to localhost or a specific, restricted IP address. Ensure remote root login is disabled.
IV. Magento 2 Specific Security Settings & Maintenance
Beyond server and web server configurations, Magento itself has several security-related settings and maintenance practices that are crucial.
A. Security Scan Tool
Magento provides a command-line tool to scan for known security issues.
Run the security scan tool:
cd /var/www/html/magento2 sudo php bin/magento setup:static-content:deploy -f en_US en_GB # Deploy static content if not already done sudo php bin/magento setup:di:compile sudo php bin/magento setup:upgrade sudo php bin/magento security:scan
Review the output carefully for any reported vulnerabilities or outdated components.
Auditor Check: Confirm that the Magento security scan tool has been run recently and that any reported issues have been addressed.
B. Regular Updates and Patching
Keeping Magento core, extensions, and server software up-to-date is non-negotiable for security.
Magento Core Updates:
# For composer-based installations composer update magento/product-community-edition --with-dependencies # Or for specific versions: composer require magento/product-community-edition:2.4.x --no-update # Then: composer update sudo php bin/magento setup:upgrade sudo php bin/magento setup:static-content:deploy -f en_US en_GB # Deploy static content for relevant locales sudo php bin/magento cache:flush
Extension Updates: Regularly check for updates for all third-party extensions and apply them following the same procedure.
Server Software: Ensure PHP, Nginx, MySQL, and the operating system are patched regularly.
Auditor Check: Verify the current Magento version and compare it against the latest stable release. Check the version history of installed extensions. Confirm a regular patching schedule for all system components.
C. Limiting File Uploads
Restrict the types and sizes of files that can be uploaded through the Magento admin to prevent the upload of malicious scripts.
Navigate to Stores > Configuration > General > Allowed Storage Resources.
Configure the “File extension” and “File size” settings for different media types (Images, Videos, etc.).
Additionally, ensure that PHP’s upload limits are appropriately configured in php.ini and that the web server does not allow execution of scripts from upload directories.
Auditor Check: Review Magento’s allowed storage resource configurations. Verify that only necessary file extensions are permitted and that file size limits are reasonable. Confirm that web server configurations prevent script execution from upload directories.
D. Secure Session Management
Proper session management is crucial to prevent session hijacking.
Ensure sessions are stored securely. The default files save handler is generally acceptable if the session save path is protected. For higher security, consider database or Redis sessions, but ensure these are also configured securely.
Check app/etc/env.php for session configuration:
'session' => [
'save' => 'files', // or 'db', 'redis'
// If 'files', ensure the session save path is secure and not web-accessible.
// Magento typically handles this by default.
],
Auditor Check: Verify the session save handler configuration. If using files, confirm the session save path is not web-accessible. If using database or Redis, ensure those services are also secured.
V. Logging and Monitoring
Effective logging and monitoring are essential for detecting and responding to security incidents.
A. Magento Logs
Ensure Magento’s logging is enabled and configured appropriately.
Logs are typically found in the var/log/ directory.
Key logs include:
system.log: General system messages.exception.log: PHP exceptions.debug.log: Debug messages (should be disabled in production).admin_user.log: Actions performed by admin users.security.log: Security-related events (e.g., failed logins).
Auditor Check: Verify that relevant logs are being generated and retained. Ensure that debug logging is disabled in production. Review log rotation policies to prevent disk space exhaustion.
B. Web Server Logs
Nginx access and error logs provide valuable insights into traffic patterns and potential attacks.
Access logs (e.g., /var/log/nginx/access.log) record all requests. Error logs (e.g., /var/log/nginx/error.log) record server-side errors, which can sometimes indicate attempted exploits.
Auditor Check: Confirm that Nginx access and error logs are enabled and configured for appropriate retention. Ensure these logs are being monitored for suspicious activity (e.g., high rates of 4xx/5xx errors, unusual request patterns).
C. System Logs and Monitoring Tools
Leverage system-level logging and monitoring tools for a comprehensive security posture.
Syslog/Rsyslog: Ensure system logs (e.g., authentication logs in /var/log/auth.log) are being collected and potentially forwarded to a central logging server.
Monitoring Solutions: Consider implementing tools like Prometheus with Alertmanager, ELK stack (Elasticsearch, Logstash, Kibana), or commercial solutions to aggregate, analyze, and alert on security events from all log sources.
Auditor Check: Verify that system logs are being captured and retained. Assess the implementation and effectiveness of any centralized logging or security monitoring solutions. Check for configured alerts for critical security events.