CentOS 搭建 PHP7.0 + Nginx + MariaDB 与安全优化

0x0 前言

其实还是挺讨厌快餐式文化,但是随着时间推移遗漏的会更多,所以还是决定记下来,需要时再做修改补充。

0x1 安装

  1. 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

  1. 安装 Nginx 和 MariaDB

官方文档已经很详细,不打算敖述。

安装完 MariaDB 后启动 MySQL 服务,运行 mysql_secure_installation 对数据库服务进行初始配置。

0x2 初始化配置

  1. 配置 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
  1. 配置 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 容器,服务端脚本解析程序 和 后端数据库。

  1. 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\";

参考:减少 MIME 类型的安全风险

同样在该配置文件中(或者被包含),位于 Server 标签的安全配置:

# 启用网站访问日志
access_log  /var/log/nginx/log/blog.access.log  main;
# 假设上传目录位于 usr/uploads, 则禁用 PHP 脚本执行
location ~ /usr/uploads/.+?\\.(php)/i {
    deny  all;
}
  1. 服务端脚本解析程序

配置文件位于 /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

参考:OWASP:PHP Configuration Cheat Sheet

  1. 后端数据库

配置文件位于 /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

ops

280 Words

2016-04-18 11:23 +0800