本文目录导读:

- 核心原则:最小权限原则
- 第一步:配置系统防火墙(最基础、最关键)
- 第二步:配置 Web 服务器防火墙(应用层防御)
- 第三步:PHP 环境自身的安全配置
- 第四步:数据库防火墙(限制连接来源)
- 第五步:高级防护(进阶推荐)
- 总结:一个典型 PHP 生产环境的防火墙配置清单
为 PHP 项目配置服务器防火墙是一个多层次的系统工程,需要根据你的服务器环境(Linux/Windows)、项目规模(单机/集群)和安全需求来定制。
以下是一套从基础到进阶的通用配置指南,主要针对最主流的 Linux (CentOS/Ubuntu) 环境。
核心原则:最小权限原则
只开放项目运行所必需的端口,关闭所有其他端口。
第一步:配置系统防火墙(最基础、最关键)
这是保护服务器的第一道大门,主流方案是 iptables(旧)或 firewalld(新)。
场景 A:使用 firewalld(CentOS 7+/RHEL 8+/Fedora)
-
启动并启用防火墙
systemctl start firewalld systemctl enable firewalld
-
开放必要端口 (根据实际需求调整)
# Web 服务端口 (HTTP/HTTPS) firewall-cmd --permanent --add-service=http firewall-cmd --permanent --add-service=https # 如果使用非标准端口,8080 # firewall-cmd --permanent --add-port=8080/tcp # SSH 端口 (务必确认端口号,避免锁在外面) firewall-cmd --permanent --add-service=ssh # 如果修改过SSH端口,改为:firewall-cmd --permanent --add-port=2222/tcp # 数据库端口(**强烈建议仅在内部访问,不对外暴露**) # MySQL/MariaDB (3306): 只在需要远程连接时才开放,且最好绑定IP。 # firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port port="3306" protocol="tcp" accept'
-
重载防火墙规则
firewall-cmd --reload
-
查看最终规则
firewall-cmd --list-all
场景 B:使用 iptables(Ubuntu 16.04 之前或自定义环境)
-
清空默认规则并设置默认策略(拒绝所有)
iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-
允许本地回环
iptables -A INPUT -i lo -j ACCEPT
-
允许特定服务
# SSH iptables -A INPUT -p tcp --dport 22 -j ACCEPT # HTTP/HTTPS iptables -A INPUT -p tcp --dport 80 -j ACCEPT iptables -A INPUT -p tcp --dport 443 -j ACCEPT # 如果你在本地开发环境,允许Ping # iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
-
保存规则(不同系统命令不同)
# CentOS service iptables save # Ubuntu/Debian iptables-save > /etc/iptables/rules.v4
第二步:配置 Web 服务器防火墙(应用层防御)
系统防火墙负责网络层,Web 服务器(如 Nginx / Apache)负责应用层。
Nginx 示例
在 Nginx 配置中(server 块或 http 块),添加规则以限制某些 URL、IP 或请求方式。
# 1. 限制访问敏感目录(如 .git, .env, 后台)
location ~ /\.(git|svn|env) {
deny all;
return 403;
}
# 2. 限制特定IP访问后台(/admin)
location /admin {
# 只允许公司IP访问
allow 192.168.1.100;
allow 203.0.113.0/24;
deny all;
}
# 3. 限制请求方法(只允许 GET, POST, HEAD)
if ($request_method !~ ^(GET|POST|HEAD)$ ) {
return 405;
}
# 4. 防止 SQL 注入 / XSS(基础防护,应配合WAF)
# 在 http 块中
# 对常见扫描工具的User-Agent进行拦截
if ($http_user_agent ~* (sqlmap|nikto|acunetix|nmap) ) {
return 403;
}
Apache 示例
使用 .htaccess 或 <Directory> 配置。
# 1. 拒绝访问 .env 文件
<Files .env>
Order allow,deny
Deny from all
</Files>
# 2. 限制特定IP访问后台
<Directory /var/www/html/admin>
Order deny,allow
Deny from all
Allow from 192.168.1.0/24
Allow from x.x.x.x # 你的IP
</Directory>
第三步:PHP 环境自身的安全配置
防火墙不仅防外人,也要防 PHP 程序自身(如文件包含、命令执行)。
修改 php.ini
; 关闭危险函数 disable_functions = exec, system, passthru, shell_exec, popen, proc_open, phpinfo, eval, assert ; 禁用文件包含远程文件 allow_url_fopen = Off allow_url_include = Off ; 隐藏PHP版本信息 expose_php = Off ; 设置会话安全 session.cookie_httponly = 1 session.cookie_secure = 1 ; 如果启用HTTPS session.use_strict_mode = 1
文件权限设置(防止PHP写马)
设定严格的文件系统权限。
# 1. 所有PHP文件属于特定用户(如 www-data 或 nginx)
# 2. 文件权限为 644(所有者可写,其他只读)
# 3. 目录权限为 755
# 4. 上传目录(如 /uploads)权限需谨慎:
# - 设置为 755 或 750,禁止PHP执行权限(非常重要!)
# 方法:在 Nginx 中对该目录禁止解析PHP
location /uploads {
location ~ \.php$ {
deny all;
}
}
第四步:数据库防火墙(限制连接来源)
永远不要让数据库监听在 0.0.0(所有网络接口)。
修改数据库绑定地址
编辑 /etc/mysql/mysql.conf.d/mysqld.cnf 或 /etc/my.cnf:
# 只允许本机访问 bind-address = 127.0.0.1 # 如果有主从复制,改为内网IP: bind-address = 192.168.1.10
数据库用户权限限制
避免使用 root 连接,创建一个仅访问特定数据库的用户。
-- 仅允许从本机连接 CREATE USER 'myapp'@'localhost' IDENTIFIED BY 'strong_password'; GRANT ALL PRIVILEGES ON myapp_db.* TO 'myapp'@'localhost'; -- 如果必须远程访问,指定IP -- CREATE USER 'myapp'@'192.168.1.%' IDENTIFIED BY '...';
第五步:高级防护(进阶推荐)
安装 ModSecurity (WAF - Web应用防火墙)
这是一个开源的 Web 应用防火墙,可以作为 Nginx/Apache 模块运行。 它能有效拦截 SQL 注入、XSS、文件包含等常见攻击。
# 以 Ubuntu + Nginx 为例 sudo apt install libnginx-mod-http-modsecurity
启用后结合 OWASP CRS(核心规则集) 效果最佳。
使用 Fail2Ban(暴力破解防御)
自动扫描日志,当某个 IP 多次尝试失败(如 SSH 登录、登录后台、爆破 PHPMyAdmin)时,自动将该 IP 加入防火墙黑名单。
# 安装 sudo apt install fail2ban # 创建针对 Nginx/Apache 的 jail 配置 sudo vim /etc/fail2ban/jail.local # 例如保护 WordPress 登录 [wordpress] enabled = true filter = wordpress logpath = /var/log/auth.log maxretry = 5 bantime = 3600
云服务商的安全组
如果你的服务器在阿里云、腾讯云、AWS 等云平台:
- 登录云控制台 → 安全组 或 防火墙。
- 这是最外层的防线,在安全组中,只放开
22 (SSH),80 (HTTP),443 (HTTPS),以及管理用的端口。 - 禁止 在安全组中开放
3306,6379,27017等数据库/缓存端口(除非你有完全必要且知道风险)。
一个典型 PHP 生产环境的防火墙配置清单
| 端口/服务 | 系统防火墙 (firewalld/iptables) | Web服务器 (Nginx/Apache) | 云安全组 | 备注 |
|---|---|---|---|---|
| 22 (SSH) | ✅ 开放 | 无 | ✅ 开放(仅限你公司的IP) | 必须,加 Fail2Ban |
| 80 (HTTP) | ✅ 开放 | ✅ 处理请求 | ✅ 开放 | 用于重定向到HTTPS或直接服务 |
| 443 (HTTPS) | ✅ 开放 | ✅ 处理请求 | ✅ 开放 | 必须,全站HTTPS |
| 3306 (MySQL) | ❌ 拒绝 | 无 | ❌ 拒绝 | 只允许本地回环 0.0.1 |
| 6379 (Redis) | ❌ 拒绝 | 无 | ❌ 拒绝 | 同上 |
| 9000 (PHP-FPM) | ✅ 仅允许 0.0.1 |
✅ Nginx 通过 unix socket 或 0.0.1 连接 |
❌ 拒绝 | 不对外暴露 |
| 8888/8080 (其他服务) | 视情况 | 视情况 | 视情况 | 通常用 Nginx 反向代理,不直接暴露 |
| ICMP (Ping) | 可选关闭 | 无 | 可关闭 | 防扫描 |
最后的核心建议:
- 不要依赖单一防线:防火墙 + Web服务器配置 + PHP安全设置 + 数据库最小权限 + 文件权限,缺一不可。
- 定期审计:用
nmap扫描你的服务器外部端口,看哪些端口对公网开放,查漏补缺。 - 日志监控:配置好
auditd或系统日志,监控/var/log/中的异常登录和错误。