CentOS 7 安装 Nginx + PHP + MySQL

0: 设置时区
读取时间
timedatectl
列出所有时区
timedatectl list-timezones
设置时区
timedatectl set-timezone Asia/Shanghai
安装NTP
yum install ntp
同步时间
ntpdate pool.ntp.org
是否NTP服务器同步
timedatectl set-ntp yes //yes或者no

1: Add EPEL Repository
sudo yum install epel-release

2:安装Nginx,以下方法三选一
2.1 使用 Nginx 官方源(推荐):
添加 Nginx 源:
vi /etc/yum.repos.d/nginx.repo
写入:
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1
安装 Nginx :
yum install nginx
2.2 使用 EPEL 官方源:
sudo yum install nginx
2.3 使用 Remi 源:
添加 Remi 源:
wget http://rpms.remirepo.net/enterprise/remi-release-7.rpm
rpm -Uvh remi-release-7.rpm
yum --enablerepo=remi update remi-release
安装 Nginx :
yum --enablerepo=remi install nginx

安装7zip:
yum install p7zip
使用方法:7za a xxx.7z dirxxx/

3:
sudo systemctl start nginx

4: 添加防火墙规则
sudo firewall-cmd --permanent --zone=public --add-service=http 
sudo firewall-cmd --permanent --zone=public --add-service=https
sudo firewall-cmd --reload

5: 打开浏览器,测试页面

6:
sudo systemctl enable nginx

7:
全局配置文件 /etc/nginx/nginx.conf
默认配置文件 /etc/nginx/conf.d/default.conf
默认 webdoc 为 /usr/share/nginx/html

8: 安装 PHP
8.1 使用 CentOS SCL(Software Collections) 软件库(推荐):
yum install centos-release-scl-rh
yum search rh-php
yum install rh-php72
yum install rh-php72-php-fpm rh-php72-php-devel
yum install rh-php72-php-bcmath rh-php72-php-gd libjpeg* rh-php72-php-intl rh-php72-php-ldap rh-php72-php-mbstring rh-php72-php-mysqlnd rh-php72-php-odbc rh-php72-php-pdo rh-php72-php-pear rh-php72-php-opcache rh-php72-php-soap rh-php72-php-xml rh-php72-php-xmlrpc rh-php72-php-zip
scl enable rh-php72 bash
echo "source /opt/rh/rh-php72/enable" >>/etc/profile
echo "source /opt/rh/rh-php72/enable" >>~/.bashrc
pecl channel-update pecl.php.net

#pecl-mcrypt
yum install libmcrypt libmcrypt-devel
pecl install mcrypt
#/opt/rh/rh-php72/root/usr/lib64/php/modules/mcrypt.so
vi /etc/opt/rh/rh-php72/php.d/mcrypt.ini
Add:
extension=mcrypt

php -m | grep mcrypt

#mhash

#pecl-memcache
#pecl-memcached
yum install zlib zlib-devel
yum install libmemcached libmemcached-devel
pecl install memcached
vi /etc/opt/rh/rh-php72/php.d/memcached.ini
Add:
extension=memcached

#redis
pecl install redis
vi /etc/opt/rh/rh-php72/php.d/redis.ini
Add:
extension=redis

#sudo systemctl start rh-php72-php-fpm
#sudo systemctl enable rh-php72-php-fpm
ln -s /usr/lib/systemd/system/rh-php72-php-fpm.service /usr/lib/systemd/system/php-fpm.service
mkdir /var/run/php-fpm/

ln -s /etc/opt/rh/rh-php72/php.ini /etc/php.ini
mkdir /etc/php-fpm.d/
ln -s /etc/opt/rh/rh-php72/php-fpm.d/www.conf /etc/php-fpm.d/www.conf
8.2 使用官方源:(可参考上一篇文章 CentOS 7.0 安装Apache + MySQL + PHP + php-mcrypt + ZendOpcache + Fail2ban)
8.3 使用 Remi 源:
安装 PHP 7:
设置默认启用 Remi 源:
vi /etc/yum.repos.d/remi.repo
将 [remi]节点修改为:
enabled=1
vi /etc/yum.repos.d/remi-php72.repo
将 [remi-php72] 节点修改为:
enabled=1
之后执行:
yum --enablerepo=remi-php72 install php72
yum --enablerepo=remi-php72 install php-fpm php-devel
yum --enablerepo=remi-php72 install php-bcmath php-gd libjpeg* php-intl php-ldap php-mbstring php-pecl-mcrypt php-mhash php-mysqlnd php-odbc php-pdo php-pear php-pecl-memcache php-pecl-memcached php-opcache php-redis php-soap php-xml php-xmlrpc php-zip php-pecl-mongodb

or 安装 PHP 5.6:
执行2.3中的添加 Remi 源操作
设置默认启用 Remi 源:
vi /etc/yum.repos.d/remi.repo
将 [remi] 和 [remi-php56] 节点修改为:
enabled=1
之后执行:
yum --enablerepo=remi install php-fpm php-devel
yum --enablerepo=remi install php-bcmath php-gd libjpeg* php-intl php-ldap php-mbstring php-mcrypt php-mhash php-mysqlnd php-odbc php-pdo php-pear php-pecl-memcache php-pecl-memcached php-pecl-mongo php-pecl-mongodb php-pecl-zendopcache php-redis php-soap php-xml php-xmlrpc

9: 
sudo vi /etc/php.ini
改为:
cgi.fix_pathinfo=0
注意:
此项设为 0 会导致 Phalcon 框架某些版本报错,需要修改为 1
在修改为 1 之后务必测试是否存在解析漏洞,保存一段 php 代码为 fake.jpg,访问 fake.jpg/foo.php ,检查 fake.jpg 是否被执行

session.cookie_httponly = 1

10: 使用 socket 方式连接 Nginx 优化 php-fpm 性能
sudo vi /etc/php-fpm.d/www.conf
改为:
listen = /var/run/php-fpm/php-fpm.sock
修改 nginx 及 php-fpm 的运行账户及组为 nobody:
sudo vi /etc/nginx/nginx.conf
修改:
user nobody;
sudo vi /etc/php-fpm.d/www.conf
改为:
listen.owner = nobody
listen.group = nobody
...
user = nobody
group = nobody

11:
设置最大上传文件大小:
sudo vi /etc/php.ini
post_max_size = 8M
upload_max_filesize = 8M
vi /etc/nginx/nginx.conf
在 http 区段中添加:
client_max_body_size 8M;
client_body_buffer_size 10M;
Nginx log中如果出现大量的:an upstream response is buffered to a temporary file,则在 http 区段中添加:
fastcgi_buffer_size 512k;
fastcgi_buffers 6 512k;
fastcgi_busy_buffers_size 512k;
fastcgi_temp_file_write_size 512k;

设置PHP最大执行时间:
sudo vi /etc/php.ini
max_execution_time=60
Nginx连接超时时间:
vi /etc/nginx/nginx.conf
keepalive_timeout  65;

sudo systemctl start php-fpm
sudo systemctl enable php-fpm

12: 让 Nginx 处理 PHP 文件
sudo vi /etc/nginx/conf.d/default.conf
添加:
server {
    listen       80;
    server_name  server_domain_name_or_IP;

    # note that these lines are originally from the "location /" block
    root   /usr/share/nginx/html;
    index  index.php index.html index.htm;

    location / {
        try_files $uri $uri/ =404;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    location ~ \.php$ {
        try_files $uri =404;
        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;
    }
}

sudo vi /usr/share/nginx/html/info.php
添加:
<?php phpinfo(); ?>

sudo systemctl restart php-fpm
sudo systemctl restart nginx

在浏览器中打开:
http://your_server_IP_address/info.php

报错:
open() "/var/lib/nginx/tmp/fastcgi/5/01/0000000015" failed (13: Permission denied)
解决方法:
chown -R nobody /var/lib/nginx/

sudo rm /usr/share/nginx/html/info.php

13: 禁止显示 Nginx 版本信息:
sudo vi /etc/nginx/nginx.conf
在 http 区段中加入:
server_tokens  off;
proxy_hide_header        X-Powered-By;
X-Frame限制同源:
add_header X-Frame-Options SAMEORIGIN;
保存
检查配置文件是否有错误:
/usr/sbin/nginx -t
重启 Nginx :
systemctl reload nginx
or:
sudo systemctl restart nginx

14:
vi /etc/php.ini
date.timezone = PRC
禁止显示php版本的信息:
expose_php = Off
禁止显示错误信息:
display_errors = Off
display_startup_errors = Off
error_reporting = E_ALL
log_errors = On
vi /etc/php-fpm.d/www.conf
catch_workers_output = yes
重启 php-fpm:
sudo systemctl restart php-fpm
log会输出到:/var/log/php-fpm/

15: 开启 Gzip:
vi /etc/nginx/nginx.conf
在 http 区段里加入:
gzip on;
gzip_min_length 1k;
gzip_comp_level 6;
gzip_buffers 32 4k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
gzip_vary on;

16: 开启客户端缓存:
vi /etc/nginx/conf.d/default.conf
修改:
location ~*^.+.(jpg|jpeg|gif|png)$ {
   expires 30d;
   add_header  Cache-Control private;
}

17: 安装最新稳定版 Redis
sudo yum --enablerepo=epel install redis
#sudo yum --enablerepo=remi install redis
设置占用内存上限:
vi /etc/redis.conf
maxmemory 100MB
sudo systemctl enable redis
sudo systemctl start redis

18: 安装最新稳定版 Memcached
sudo yum --enablerepo=epel install memcached
#sudo yum --enablerepo=remi install memcached
设置占用内存上限,默认64MB:
vi /etc/sysconfig/memcached
CACHESIZE="64"
sudo systemctl enable memcached
sudo systemctl start memcached

19: 安装MongoDB 3.2.8
vi /etc/yum.repos.d/mongodb-org.repo
[mongodb-org]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/stable/$basearch/
gpgcheck=0
enabled=1

yum install mongodb-org
systemctl start mongod

添加账户:
systemctl stop mongod
vi /etc/mongod.conf
dbPath: /var/lib/mongo
mongod --dbpath=/var/lib/mongo
启动另一个终端:
mongo
db.createUser({user: "sa", pwd: "sa", roles: [{role: "userAdminAnyDatabase", db: "admin"}]});
杀掉第一个终端进程,然后:
systemctl start mongod
如果出现无法启动情况:
vi /var/log/mongodb/mongod.log
WiredTiger (13) [1468490525:829304][5817:0x7fc8c7d79dc0], txn-recover: /var/lib/mongo/journal/WiredTigerLog.0000000002: handle-open: open: Permission denied
WiredTiger (13) [1468490712:206477][6058:0x7fb6164f1dc0], file:collection-2-3710649115002191292.wt, WT_SESSION.open_cursor: /var/lib/mongo/collection-2-3710649115002191292.wt: handle-open: open: Permission denied
chown -R mongod:mongod /var/lib/mongo/
systemctl start mongod

20: 更新git
yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel perl-devel
yum install gcc asciidoc perl-ExtUtils-MakeMaker
yum remove git
https://github.com/git/git
wget https://github.com/git/git/archive/版本号.tar.gz
如:
wget https://github.com/git/git/archive/v2.10.2.tar.gz
tar -zxvf git-2.10.2.tar.gz
cd git-2.10.2
make configure
./configure --prefix=/usr/local/git
make all
make install
ln -s /usr/local/git/bin/* /usr/bin/
git --version
安全设置:
1:修改网站目录所有者为非 php-fpm 和 nginx 的运行账户,这里修改为root:
sudo chown -R root:root /usr/share/nginx/html/

2:
添加 nobody 对网站目录的读取权限(每次yum升级php之后可能导致权限变化,需重新设置):
sudo chmod o+r -R /usr/share/nginx/html/
或者:
find /usr/share/nginx/html/ -type d -exec chmod 755 {} \;
find /usr/share/nginx/html/ -type f -exec chmod 644 {} \;

php session 目录权限:
#mkdir /var/lib/php
#ln -s /var/opt/rh/rh-php72/lib/php/session /var/lib/php/session
chown nobody /var/lib/php/session/
chmod -R 777 /var/lib/php/session/

4:确认网站目录对于 nobody 的权限为可读可执行,网站文件对于 nobody 的权限为可读

5:对于上传目录或者需要写文件的目录添加 nobody 的写入权限

6:配置 nginx.conf 对于上传目录无 php 的执行权限,配置 nginx.conf 禁止访问的文件夹
vi /etc/nginx/conf.d/default.conf
禁止访问所有目录(包括子目录)下的隐藏文件 
location ~ /\. {
    deny  all;
}
禁止访问 path 目录:
 location ^~ /path/ {
     deny all;
 }
/path/ 为除域名之后剩余的 URL 路径,带"/"只禁止访问目录,不带"/"禁止访问目录中的文件

去掉单个目录的 PHP 执行权限:
 location ~ /attach/.*\.(php|php5)?$ {
     deny all; 
 }

去掉多个目录的 PHP 执行权限:
 location ~ ^/(attach|upload)/.*\.(php|php5)$ {
     deny all; 
 }
这几条要放在 fastcgi 配置之前

7:禁止IP直接访问,防止恶意解析:
vi /etc/nginx/nginx.conf
在 listen       [::]:80 default_server; 之后添加:
return    403;
如果 /etc/nginx/nginx.conf 文件中没有,则在 /etc/nginx/conf.d/default.conf 文件顶部添加:
server {
    listen       80;
    listen       [::]:80 default_server;
    return     403;
}

8: 强制使用 www 二级域名访问:
vi /etc/nginx/conf.d/default.conf
# FORCE WWW
server {
    server_name  site.com;
    rewrite ^/(.*)$ http://www.site.com$1 permanent;
}

9:限制 PHP 脚本的文件访问范围,防止一个站点被攻陷后殃及整个服务器(重要!!!):
vi /etc/nginx/conf.d/default.conf
增加:
fastcgi_param  PHP_VALUE  "open_basedir=$document_root:/tmp/";
or:{
vi /etc/php.ini
在末尾加入:
[HOST=testdomain.com]
open_basedir=/usr/share/nginx/html/:/tmp/
}
注意用open_basedir指定的限制实际上是前缀,而不是目录名。所以如果要将访问限制在仅为指定的目录,请用斜线结束路径名。

10:禁用某些 PHP 内置函数:
vi /etc/php.ini
disable_functions = pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,phpinfo,exec,passthru,chroot,shell_exec,system,chgrp,chown,chmod,dl,set_time_limit,show_source,highlight_file,gzinflate,str_rot13,pfsockopen,syslog,readlink,symlink,stream_socket_server,leak,popepassthru,escapeshellcmd,escapeshellarg,max_execution_time,getcwd,ini_alter,ini_set,ini_restore,putenv,popen,pclose,proc_open,proc_close,proc_get_status,rename,assert,mkdir,copy,delete,rmdir,chdir,dir
;,file,fopen,fwrite,unlink,file_get_contents,fputs,opendir,readdir,scandir
注:
如果是生产环境可考虑禁用;之后的函数
禁用 proc_open,proc_close,proc_get_status,ini_set,putenv,pcntl_signal,pcntl_signal_dispatch,pcntl_alarm 会影响 Laravel 框架某些功能
禁用 chmod,ini_set 会影响 Yii 2 框架某些功能
禁用mkdir,copy,delete,rmdir会影响wordpress的自动升级功能
禁用opendir,readdir,scandir,file会影响wordpress的WP Security的正常使用

11:禁用远程url文件处理功能(打开它容易引起性能的问题,建议禁止,禁用之后 file_get_contents 函数将无法读取远程文件,可以用curl代替):
vi /etc/php.ini
# 容易造成任意文件读取和包含问题,注意,此项默认就是开启的
allow_url_fopen = Off
# 容易造成远程包含,强烈建议关闭此项		
allow_url_include = Off

12:禁用 eval 语句(会导致 phpMyAdmin 某些功能异常):
yum install php-suhosin
vi /etc/php.d/40-suhosin.ini
修改:
suhosin.executor.disable_eval = On
注:suhosin 默认参数会导致 composer 无法使用,需要执行以下操作:
vi /etc/php.d/suhosin.ini
suhosin.executor.include.whitelist = phar

13:禁止加载动态连接库
vi /etc/php.ini
enable_dl = Off

sudo systemctl restart php-fpm

14:关闭 SELinux
vi /etc/sysconfig/selinux
SELINUX=disabled
WordPress Rewrite 设置:
vi /etc/nginx/conf.d/default.conf
location / {
    try_files $uri $uri/ /index.php?$args;
}

15: 设置chroot(禁用chroot和chdir函数可以不用设置)
vi /etc/php-fpm.d/www.conf
chroot = /var/www
chdir = /var/www
这样当用户试图通过chdir跳转到/var/www以外的目录时,将被拒绝


创建 uploads 目录:
mkdir wp-content/uploads
chmod -R 777 wp-content/uploads
取消 upload 目录 PHP 执行权限:
location ~ ^/(wp-content/uploads)/.*\.(php|php5)$ {
    deny all;
}
安装安全插件:
1、安装 All In One WP Security, 删除 xmlrpc.php(重要)
or
1、安装 Limit Login Attempts 和 Disable XML-RPC 插件
2、安装 Disable XML-RPC Pingback 插件
   设置 - 讨论 - 禁止pingback和trackback,防止被利用作为DDOS攻击源

安装 WP Super Cache、Disable Google Fonts、Google XML Sitemaps、Advanced Excerpt

需要在线安装插件时:
chown -R nobody wordpress/
安装完毕再修改回 root

WP Super Cache 所需权限:
chmod -R 777 wp-content/cache/
chmod 666 wp-content/wp-cache-config.php
location ~ ^/(wp-content/cache)/.*\.(php|php5)$ {
    deny all; 
}
OpenCart 设置:
Rewrite :
vi /etc/nginx/conf.d/default.conf
location / {
    try_files $uri @opencart;
}
location @opencart {
    rewrite ^/(.+)$ /index.php?_route_=$1 last;
}
location ~* (.(tpl|ini|log))$ {
    deny all;
}

权限:
1.x版本:
以下目录给予 PHP 写权限,去除 PHP 执行权限:
chmod 777 -R system/cache/
chmod 777 -R system/logs/
chmod 777 -R image/
chmod 777 -R download/

location ~ /(system/cache|system/logs|image|download)/.*\.(php|php5)?$ {
    deny all; 
}

2.x版本
chmod -R 777 image/
chmod -R 777 system/storage/

location ~ /(image|system/storage)/.*\.(php|php5)?$ {
    deny all; 
}

3.x版本
chmod -R 777 storage/
chmod -R 777 upload/image/cache/
chmod -R 777 upload/admin/view/

不显示页面错误信息:
系统设置 - 网店设置 - 编辑 - 服务器 - 显示错误:否
Nginx log添加host和请求时长
Nginx + php-fpm 性能优化
MySQL 5.7/8.0 优化
CentOS 7.0 添加 SWAP
CentOS 7 配置入侵检测系统(IDS)
PHP 使用 Redis 保存 Session

根据修改时间搜索文件(10天):
find ./ -name “*.php” -mtime -10