PHP Security Configuration
1. Ensure PHP runs under a non-privileged user account (e.g., www or nginx), never as root.
2. Key php.ini parameter recommendations:
disable_functions = passthru,exec,system,chroot,chgrp,chown,shell_exec,proc_open,proc_get_status,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,stream_socket_server,fsocket,phpinfo
expose_php = off
display_errors = off
enable_dl = off
allow_url_include = off
session.cookie_httponly = 1
upload_tmp_dir = /tmp
open_basedir = /home/wwwroot/example.com:/tmp
Parameter explanations:
disable_functions: Disables potentially dangerous system functions.expose_php = off: Prevents PHP version disclosure in HTTP headers.display_errors = off: Hides error messages in production to avoid information leaks.open_basedir: Restricts PHP file access to specified directories, a crucial isolation measure.
Additional Notes on open_basedir
The open_basedir directive limits PHP file operations to the specified directory prefix. For example, open_basedir = /home/wwwroot allows access to /home/wwwroot and all its subdirectories. To restrict strictly to a single directory, end the path with a slash (e.g., /home/wwwroot/).
Note: Setting open_basedir may impact I/O performance due to path validation. Balance security and performance based on your needs. Multiple directories can be specified, separated by colons (:) on Linux/Unix or semicolons (;) on Windows.
MySQL Security Settings
1. Version Selection: Use a supported, stable version like MySQL 5.7+ or MariaDB 10.x, and apply security patches promptly.
2. Network Configuration: If the database only needs local access, add skip-networking or bind to 127.0.0.1 in the configuration to block remote connections.
3. Service User: Ensure MySQL runs under a dedicated non-root user (e.g., mysql), with data directory permissions owned by that user.
# /etc/my.cnf or /etc/mysql/my.cnf
[mysqld]
user = mysql
4. Enable Binary Logging: Facilitates data recovery and auditing.
[mysqld]
log_bin = mysql-bin
expire_logs_days = 7
5. Authentication and Authorization:
- Restrict root login to localhost only.
- Remove anonymous users and accounts with empty passwords.
-- Execute after logging into MySQL
DELETE FROM mysql.user WHERE User='';
DELETE FROM mysql.user WHERE Host NOT IN ('localhost', '127.0.0.1', '::1') AND User='root';
FLUSH PRIVILEGES;
Web Server Security
Ensure Nginx or Apache runs as a non-privileged user (e.g., www-data, nginx, www). Apply the principle of least privilege to web root and upload directory permissions.
SQL Injection Prevention
In Nginx configuration, you can block common injection patterns with rules like:
if ($query_string ~* "b(union|select|insert|update|delete|drop|exec|chr|mid|master|truncate|declare)b") {
return 403;
}
# Note: This is a supplementary measure. Primary defense should be application-level parameterized queries.
Disable PHP Execution in Sensitive Directories
Nginx Example: Prevent PHP script execution in uploads or data directories.
location ~* ^/(uploads|data|attachments)/.*.(php|php5)$ {
deny all;
}
Apache Example: In .htaccess or virtual host configuration for a specific directory:
Order Deny,Allow
Deny from all
Malware Detection and Prevention
Finding Suspicious PHP Files
Use grep to search for common webshell signatures:
grep -r --include="*.php" 'eval($_POST' /home/wwwroot/
grep -r --include="*.php" 'base64_decode' /home/wwwroot/
# Note: Attackers obfuscate code, so this may not detect all variants.
Find recently modified PHP files:
find /home/wwwroot -type f -name "*.php" -mtime -2
Preventive Measures
- Implement the security configurations mentioned earlier (e.g., disable dangerous functions, set
open_basedir). - Set correct file and directory permissions:
find /home/wwwroot -type f -name "*.php" -exec chmod 644 {} ; find /home/wwwroot -type d -exec chmod 755 {} ; chown -R www:www /home/wwwroot/example.com - Virtual Host Directory Isolation (Critical): Configure separate
open_basedirpaths for each website to prevent cross-site attacks.- Nginx + PHP-FPM: Typically set in the PHP-FPM pool configuration file (
www.conf):php_admin_value[open_basedir] = /home/wwwroot/example.com:/tmp - Apache + mod_php: Set in the virtual host configuration:
ServerName example.com DocumentRoot /home/wwwroot/example.com php_admin_value open_basedir "/home/wwwroot/example.com:/tmp"
- Nginx + PHP-FPM: Typically set in the PHP-FPM pool configuration file (
These combined measures significantly raise the security baseline of a Linux web server. Security is an ongoing process; complement it with regular updates, log auditing, and intrusion detection.