CentOS 7.0 安装Apache + MySQL + PHP + php-mcrypt + ZendOpcache + Fail2ban

设置启动菜单等待时间:
vi /boot/grub2/grub.cfg
set timeout=0
设置 root 账户下 vi 高亮:
vim显示代码高亮
设置自动启动网络服务:
vi /etc/sysconfig/network-scripts/ifcfg-enp0s3
ONBOOT=yes
service network restart
查看IP地址:
ip addr
安装编译工具:
yum update
yum install gcc gcc-c++ make
安装Apache:
yum install httpd httpd-devel
systemctl start httpd.service
systemctl status httpd.service
#设置apache开机启动
systemctl enable httpd.service
添加Firewall规则:
vi /etc/firewalld/zones/public.xml
<zone>
...
  <port protocol="tcp" port="80"/>
  <port protocol="udp" port="80"/>
...
</zone>
yum 源里的 MySQL 被替换为了 MariaDB:

安装 MariaDB:
yum install mariadb mariadb-server
#拷贝配置文件
cp /usr/share/mysql/my-huge.cnf /etc/my.cnf
systemctl start mariadb.service
#设置开机启动
systemctl enable mariadb.service

安装原版 MySQL:
MySQL 5.6:
rpm -ivh http://repo.mysql.com/mysql-community-release-el7-7.noarch.rpm
MySQL 5.7:
rpm -ivh http://repo.mysql.com//mysql57-community-release-el7-9.noarch.rpm
#上面的地址来自 http://dev.mysql.com/downloads/repo/yum/ ,可能会有变动,请自行修改
如果在线安装下载速度太慢,可以去 http://repo.mysql.com/yum/mysql-5.7-community/ 用下载工具直接下载rpm文件并拷贝到服务器上进行安装,例如 http://repo.mysql.com/yum/mysql-8.0-community/el/7/x86_64/mysql-community-server-8.0.18-1.el7.x86_64.rpm
yum install mysql mysql-server
systemctl start mysqld.service
#设置开机启动
systemctl enable mysqld.service
设置时区:
vi /etc/my.cnf 在 [mysqld] 节点添加:
default-time_zone = '+8:00'
character-set-server = utf8mb4
[client]
default-character-set=utf8mb4

mysql_secure_installation
5.7版本执行上面的操作时如果提示输入密码,则可以通过以下方法查看临时密码:
grep 'temporary password' /var/log/mysqld.log
新建MySQL普通用户,不要在业务中使用root账户直接连接数据库:
mysql -uroot -p
mysql> create user 'dba'@'localhost' identified by 'password';
mysql> grant all privileges on database.* to 'dba'@'localhost';
mysql> select user,host,password from mysql.user;
mysql> flush privileges;
mysql> exit;

mysql 8 ssh连接配置:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'youpassword';
ALTER USER 'yourusername'@'localhost' IDENTIFIED WITH mysql_native_password BY 'youpassword';
[mysqld]
default-authentication-plugin=mysql_native_password
启用MySQL Query Cache:(如果数据更新较频繁的话不建议开启,具体原因请参考 MySQL 开启 QueryCache 之后所带来的负面影响)
vi /etc/my.cnf 在 [mysqld] 节点添加:
query_cache_limit=1048576
query_cache_type=1
query_cache_size=32M

查看设置:
mysql -uroot -p
mysql> SHOW VARIABLES LIKE '%query_cache%';
+------------------------------+----------+
| Variable_name                | Value    |
+------------------------------+----------+
| have_query_cache             | YES      |
| query_cache_limit            | 1048576  |
| query_cache_min_res_unit     | 4096     |
| query_cache_size             | 33554432 |
| query_cache_type             | ON       |
| query_cache_wlock_invalidate | OFF      |
+------------------------------+----------+

其中各项的含义为:
have_query_cache
是否支持查询缓存区 “YES”表是支持查询缓存区

query_cache_limit 
可缓存的Select查询结果的最大值 1048576 byte /1024 = 1024kB 即最大可缓存的select查询结果必须小于 1024KB

query_cache_min_res_unit 
每次给query cache结果分配内存的大小 默认是 4096 byte 也即 4kB

query_cache_size 
QC占用的总空间大小,如果你希望禁用查询缓存,设置 query_cache_size=0。禁用了查询缓存,将没有明显的开销

query_cache_type 
查询缓存的方式(默认是 ON),0表示关闭QC;1表示正常缓存;2表示SQL_CACHE才缓存

Qcache_lowmem_prunes
这是一个状态变量(show status),当缓存空间不够需要释放旧的缓存时,该值会自增。
安装PHP:
yum install php php-devel
yum install php-bcmath php-gd libjpeg* php-intl php-ldap php-mbstring php-mhash php-mysqlnd php-odbc php-pdo php-pear php-pecl-memcache php-soap php-xml php-xmlrpc
安装ZendOpcache 或 APC(推荐ZendOpcache):
ZendOpcache:
yum install php-pecl-zendopcache
或
pecl install channel://pecl.php.net/zendopcache-7.0.5
vi /etc/php.ini
添加:
[ZendOpcache]
zend_extension=/usr/lib64/php/modules/opcache.so

APC:
pecl install apc
vi /etc/php.ini
添加:extension=apc.so
安装 php-mcrypt:
yum install php-mcrypt

或
安装libmcrypt:
wget http://sourceforge.net/projects/mcrypt/files/Libmcrypt/2.5.8/libmcrypt-2.5.8.tar.gz
tar -xvzf libmcrypt-2.5.8.tar.gz
cd libmcrypt-2.5.8
./configure
make && make install

安装mhash:
wget http://sourceforge.net/projects/mhash/files/mhash/0.9.9.9/mhash-0.9.9.9.tar.gz
tar -xvzf mhash-0.9.9.9.tar.gz
cd mhash-0.9.9.9
./configure
make && make install

安装mcrypt:
wget http://sourceforge.net/projects/mcrypt/files/MCrypt/2.6.8/mcrypt-2.6.8.tar.gz
tar -xvzf mcrypt-2.6.8.tar.gz
cd mcrypt-2.6.8
LD_LIBRARY_PATH=/usr/local/lib ./configure
make && make install

安装php-mcrypt:
wget http://museum.php.net/php5/php-5.4.16.tar.gz
tar -xvzf php-5.4.16.tar.gz
cd php-5.4.16/ext/mcrypt
phpize
php-config
./configure
make && make install
vi /etc/php.ini
添加:extension=mcrypt.so
配置Apache:
vi /etc/httpd/conf/httpd.conf
去除 Indexes
修改:
AllowOverride All
DirectoryIndex index.php index.html
#禁止显示版本,修改或添加:
ServerTokens Prod
设置gzip压缩传输和客户端缓存时间:
vi /etc/httpd/conf.d/xxx.conf
添加:
<VirtualHost *:80>
...
    <IfModule mod_deflate.c>
        AddOutputFilterByType DEFLATE text/plain text/css application/xml application/rss+xml application/atom_xml application/javascript application/x-javascript text/x-component application/x-httpd-php text/html
        AddOutputFilter DEFLATE js css
    </IfModule>
    <IfModule mod_expires.c>
        <FilesMatch ".(jpg|jpeg|png|gif|js|css)$">
            ExpiresActive On
            ExpiresDefault "accesss plus 60 seconds"
            FileETag None
            Header unset ETag
        </FilesMatch>
    </IfModule>
</VirtualHost>
vi /etc/php.ini
date.timezone = PRC
#禁止显示php版本的信息
expose_php = Off
禁用某些函数:
disable_functions = phpinfo,exec,passthru,chroot,shell_exec,system,chgrp,chown,chmod,proc_open,proc_close,proc_get_status,popen,pclose,dl,set_time_limit,show_source,highlight_file,gzinflate,ini_alter,ini_set,ini_restore,pfsockopen,syslog,readlink,symlink,stream_socket_server,putenv

禁用 ini_set,putenv 会导致Laravel 5.1 无法运行
yum install memcached
systemctl start memcached.service
systemctl enable memcached.service
设置VirtualHost:
vi /etc/httpd/conf.d/xxx.conf
<VirtualHost *:80>
    ServerName xxx.com
    DocumentRoot /var/www/html/xxx.com
    ErrorLog /var/log/xxx.com-error_log
    CustomLog /var/log/xxx.com-access_log common
</VirtualHost>
将上一步中的 DocumentRoot /var/www/html/xxx.com 目录所有者改为 apache:
chown apache /var/www/html/xxx.com
禁止IP直接访问,防止恶意解析:
vi /etc/httpd/conf.d/default.conf
<VirtualHost *:80>
    <Location />
        Order Allow,Deny
        Deny from all
    </Location>
</VirtualHost>
如果出现访问虚拟目录时报告403错误,可能是SELinux导致,须执行:
chcon -R -t httpd_sys_content_t /var/www/html/xxx
执行后可通过 ls -Z 查看目录属性
限制 PHP 脚本的文件访问范围,防止一个站点被攻陷后殃及整个服务器:
vi /etc/httpd/conf.d/xxx.conf
<VirtualHost *:80>
    ServerName xxx.com
    DocumentRoot /var/www/html/xxx.com
    php_admin_value open_basedir "/var/www/html/xxx.com/:/tmp/"
</VirtualHost>
使用 Fail2ban 防止 ssh 穷举破解:
#因为centos使用了新的防火墙firewalld,所以要重新配置iptables
#先停了firewalld
systemctl stop firewalld
systemctl mask firewalld
 
#再配置iptables
yum install iptables-services
systemctl enable iptables
service iptables start
/sbin/iptables -I INPUT -p tcp --dport 80 -j ACCEPT
/sbin/iptables -I INPUT -p tcp --dport 22 -j ACCEPT
service iptables save
service iptables restart

安装Fail2ban:
yum install fail2ban

创建本地的fail2ban 规则文件,最简单的办法是把 /etc/fail2ban/jail.conf 复制一份
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

vi /etc/fail2ban/jail.local
找到[sshd],修改为:
[sshd]
enabled=true

systemctl enable fail2ban
systemctl start fail2ban

#检查日志文件位置
grep logtarget /etc/fail2ban/fail2ban.conf |grep -v "#"
logtarget = /var/log/fail2ban.log

检查状态:
fail2ban-client status sshd

手动解除fail2ban的封锁:
fail2ban-client set sshd unbanip you.wantto.unban.ip
限制403、404请求,防止恶意扫描:
vi /etc/fail2ban/filter.d/nginx-403.conf
add:
[Definition]
failregex = ^<HOST> -.*"(GET|POST|HEAD).*HTTP.*" 403
ignoreregex =
vi /etc/fail2ban/filter.d/nginx-404.conf
add:
[Definition]
failregex = ^<HOST> -.*"(GET|POST|HEAD).*HTTP.*" 404
ignoreregex =

vi /etc/fail2ban/jail.local
Add:
[nginx-403]
enabled = true
port    = http,https
filter  = nginx-403
logpath = /var/log/nginx/access.log
maxretry = 5
findtime = 300
[nginx-404]
enabled = true
port    = http,https
filter  = nginx-404
logpath = /var/log/nginx/access.log
maxretry = 10
findtime = 300

systemctl restart fail2ban
对于在iptables规则中没有匹配到规则的请求则使用默认规则进行处理:
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P FORWARD DROP

防止拦截yum:
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

允许 ping:
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT

# enable UDP traceroute rejections to get sent out
iptables -A INPUT -p udp --dport 33434:33523 -j REJECT

service iptables save
service iptables restart
禁止 SSH 直接登录 root 账户:
添加新用户:
adduser username
passwd username
禁止 root 直接登录:
vi /etc/ssh/sshd_config
将
#PermitRootLogin yes
改为
PermitRootLogin no
修改sshd端口:
/sbin/iptables -I INPUT -p tcp --dport 10022 -j ACCEPT
service iptables save
service iptables restart

vi /etc/fail2ban/jail.local
修改
[sshd]
port    = ssh
为
port    = 10022

vi /etc/ssh/sshd_config
修改
#Port 22
为
Port 10022

systemctl restart fail2ban
systemctl restart sshd

在终端中登录:
ssh user@IP地址 -p port
每天自动更新(生产环境请慎重考虑是否开启自动更新):
yum install cronie yum-cron
vi /etc/yum/yum-cron.conf
修改
apply_updates = no
为
apply_updates = yes
自动启动:
systemctl start crond
systemctl start yum-cron

systemctl enable crond
systemctl enable yum-cron