CentOS 搭建 PHP7.0 + Nginx + MariaDB 与安全优化
0x0 前言
其实还是挺讨厌快餐式文化,但是随着时间推移遗漏的会更多,所以还是决定记下来,需要时再做修改补充。
0x1 安装
- PHP-FPM 安装
先添加源(CentOS/RHEL 6.x):
rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm
rpm -Uvh https://mirror.webtatic.com/yum/el6/latest.rpm
开始安装,根据需求增删依赖:
yum install php70w-fpm php70w-opcache php70w-cli php70w-common php70w-gd php70w-mbstring php70w-mcrypt php70w-mysql php70w-pdo php70w-pear php70w-xml php70w-xmlrpc
具体各个组件信息参考:https://webtatic.com/packages/php70
- 安装 Nginx 和 MariaDB
官方文档已经很详细,不打算敖述。
- Nginx 安装:http://nginx.org/en/linux_packages.html
- MariaDB 安装:https://downloads.mariadb.org/mariadb/repositories
安装完 MariaDB 后启动 MySQL 服务,运行 mysql_secure_installation 对数据库服务进行初始配置。
0x2 初始化配置
- 配置 PHP-FPM,配置文件位于 /etc/php-fpm.d/www.conf:
; 将默认 TCP socket 通信方式改为 UINX socket 方式
listen = /var/run/php-fpm/php-fpm.sock
; 取消以下设置注释,使 WEB 容器有正确的权限读写 socket
listen.owner = nginx
listen.group = nginx
listen.mode = 0660
- 配置 Nginx 与 PHP-FPM 通信,配置文件位于 /etc/nginx/conf.d/default.conf(注意此处为某个网站的配置):
location ~ \\.php$ {
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
0x3 安全优化
安全优化分为三部分:Web 容器,服务端脚本解析程序 和 后端数据库。
- Web 容器
配置文件位于 /etc/nginx/nginx.conf,以下配置在 HTTP 标签中:
禁止显示 Nginx 版本号:
server_tokens off;
其他安全设置:
# 禁止在 frame 或 iframe 显示服务器网页,避免点击劫持等
add_header X-Frame-Options SAMEORIGIN;
# 拒绝错误的 MIME 类型的资源加载
add_header X-Content-Type-Options nosniff;
# 启用浏览器的 XSS 过滤保护
add_header X-XSS-Protection \"1; mode=block\";
同样在该配置文件中(或者被包含),位于 Server 标签的安全配置:
# 启用网站访问日志
access_log /var/log/nginx/log/blog.access.log main;
# 假设上传目录位于 usr/uploads, 则禁用 PHP 脚本执行
location ~ /usr/uploads/.+?\\.(php)/i {
deny all;
}
- 服务端脚本解析程序
配置文件位于 /etc/php.ini:
禁止显示 PHP 版本号:
expose_php = Off
禁止显示错误信息并将错误信息记录:
error_reporting = E_ALL
display_errors = Off
display_startup_errors = Off
log_errors = On
error_log = /var/log/php/errors.log
ignore_repeated_errors = Off
文件访问:
# 限制 PHP 进程可读写的目录范围
open_basedir = \'/var/www/html\'
# 禁止远程文件打开和包含
allow_url_fopen = Off
allow_url_include = Off
# 文件路径自动纠正
cgi.fix_pathinfo = 0
危险函数禁用,根据需求调整:
disable_functions = system, exec, shell_exec, passthru, phpinfo, show_source, popen, proc_open, fopen_with_path, escapeshellcmd, dl, get_cfg_var, chmod, putenv
Session 安全:
session.auto_start = Off
session.hash_function = 1
session.hash_bits_per_character = 6
session.cookie_secure = On
# HttpOnly Cookies
session.cookie_httponly = 1
session.use_only_cookies= 1
session.cache_expire = 30
- 后端数据库
配置文件位于 /etc/my.cnf
禁止远程登录:
[mysqld]
bind-address=127.0.0.1
禁止本地文件读写:
local-infile=0
PS:为每个网站分配分离的数据库和单一本地用户,不直接使用 root 用户。
与 MySQL 终端交互时会产生历史文件,其位于 ~/.mysql_history,类似于 .bash_history,可能会导致信息泄露。所以将其丢置黑洞:
rm ~/.mysql_history
ln -s /dev/null ~/.mysql_history