WEB架构    

    正常状态

    

    故障切换

    

    Lnmp环境配置

    采用一键安装包

系统安装优化

    web版本泄露

        对404页面进行处理,或者说针对不存在的文件或目录进行404错误返回,避免出现nginx版本泄露信息(nginx源码编译,隐藏版本信息)

    /tmp目录权限

    这里假设目标服务器已经被上传***,【那么我们就把目标堵死在这里】。首先,因为/tmp目录是1777的粘滞位权限,因此会在此目录上传exp进行root提权  

yum install acl libacl libacl-devel –y

 查看/tmp目录权限

因为运行WEB的账户是www 或者其他账户,因此需要对WEB账户进行权限控制。在为设置权限之前,如下:

因为mysq.sock在此目录下,因此我给了www账户的执行权限,如果不在可以直接给r权限即可,现在我们尝试传文件试试

大部分webshell带有反弹窗口的选项一般都在tmp下创建,现在就会失败。下面针对命令作下限制,在为做限制之前如下:        

setfacl  -m u:www:rw /usr/bin/setfacl  -m u:www:rw /bin/

防旁注,很多时候,***人员对主站无法下手,就会采用同一服务器的其他网站进行着手,然后webshell会获取你的主站信息。

需要处理下PHP的主配置文件

sed -i"s@;open_basedir =@open_basedir = /data/wwwroot/htdocs:/tmp@"/usr/local/php/etc/php.iniservice php-fpm restart

 

以上内容的脚本如下:

#!/bin/bash# Author by:Tommy.Gandolf# Acl PowerSettingrpm -qa | grep acl> /dev/null 2>&1if [ $? -eq 0 ];then        echo "Acl is alreadinstalled"else        yum install acl libacl libacl-devel -yfiecho "Starttingwill Setting Acl..."sleep 3chown  -R root:root /tmp/WEB_USER=$(ps -ef| grep nginx | grep -v "^root" | awk '{print $1}' | uniq)setfacl  -m u:$WEB_USER:rx /tmp/setfacl  -m u:$WEB_USER:rw /usr/bin/setfacl  -m u:$WEB_USER:rw /bin/echo "Starttingwill Setting PHP.ini For open_basedir..."sleep 3HTDOCS=$(cat/usr/local/nginx/conf/nginx.conf | grep 'root' | head  -n1 | awk '{print $2}'| cut -d ";"-f1)sed -i"s@;open_basedir =@open_basedir = $HTDOCS:/tmp@"/usr/local/php/etc/php.ini echo " "

    防暴力破解

        采用分析日志文件获取非法尝试登录主机的IP地址,根据设定的阈值,将地址加入本地hosts.deny文件,限制主机访问,脚本放到crontab计划任务

脚本内容如下:

#!/bin/bash#awk'{for(i=1;i<=NF;i++){if($i ~ /rhost/)print substr($i,7)}}' /var/log/secure |sort | uniq    -c    >/root/black.txtDEFINE="5"cat     /root/black.txt |    while read LINEdo                NUM=`echo $LINE |awk '{print$1}'`                host=`echo $LINE    |awk '{print $2}'`                if [ $NUM -gt $DEFINE ];                then                 grep $host    /etc/hosts.deny > /dev/null                    if [ $? -gt 0 ];                    then                    echo"sshd:$host"     >>/etc/hosts.deny                    echo"vsftpd:$host" >> /etc/hosts.deny                    fi                fidone

MySQL

    使用一键安装包,选择5,安装MySQL  

 接下来正式进行主从同步的操作:

创建同步账户:(Master上操作)

mysql> GRANT REPLICATION SLAVE ON *.* TO 'leerw_repl'@'172.16.100.105'IDENTIFIED BY '123456';mysql> FLUSH PRIVILEGES;

修改Master的server-id 并且开启二进制日志

server-id= 100log_bin= mysql-binbinlog_format= mixedexpire_logs_days= 30replicate-wild-ignore-table=mysql.%replicate-wild-ignore-table=information_schema.%service mysqld restart

重新登录master数据库进行所标操作,备份数据库到从服务器:

mysql> FLUSH TABLES WITH READ LOCK;

当前这个窗口不要关闭,重新打开一个终端导出数据库脚本到从数据库

导出SQL文件的脚本如下:

tar zcvf /tmp/dbname.tar.gz dbname mysql>UNLOCK TABLES;show master status\G;

从数据库操作:

tarzxvf dbname.tar.gz  -C /data/mydata/vim /etc/my.cnfserver-id= 200relay-log= mysql-relay-binreplicate-wild-ignore-table=mysql.%replicate-wild-ignore-table=information_schema.%log_bin= mysql-binbinlog_format= mixedexpire_logs_days= 30#service mysqld restartmysql> CHANGE MASTER TO\    -> master_host='172.16.100.106',    -> master_user='repl_user',    -> master_password='123456',    -> master_log_file='mysql-bin.000003',    -> master_log_pos=107;Query OK, 0 rows affected (0.03 sec)mysql> start slave;Query OK, 0 rows affected (0.00 sec)mysql> show slave status\G;*************************** 1. row***************************               Slave_IO_State: Waiting formaster to send event                  Master_Host: 172.16.100.106                  Master_User: repl_user                  Master_Port: 3306                Connect_Retry: 60              Master_Log_File: mysql-bin.000003         Read_Master_Log_Pos: 107               Relay_Log_File:mysql-relay-bin.000002                Relay_Log_Pos: 253       Relay_Master_Log_File: mysql-bin.000003            Slave_IO_Running: Yes            Slave_SQL_Running: Yes              Replicate_Do_DB:         Replicate_Ignore_DB:          Replicate_Do_Table:      Replicate_Ignore_Table:     Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: mysql.%,information_schema.%                   Last_Errno: 0                   Last_Error:                 Skip_Counter: 0          Exec_Master_Log_Pos: 107              Relay_Log_Space: 409              Until_Condition: None               Until_Log_File:                Until_Log_Pos: 0          Master_SSL_Allowed: No          Master_SSL_CA_File:          Master_SSL_CA_Path:              Master_SSL_Cert:           Master_SSL_Cipher:               Master_SSL_Key:       Seconds_Behind_Master: 0Master_SSL_Verify_Server_Cert: No                Last_IO_Errno: 0                Last_IO_Error:               Last_SQL_Errno: 0               Last_SQL_Error: Replicate_Ignore_Server_Ids:            Master_Server_Id: 1001 row in set (0.00 sec) ERROR:No query specified mysql>

主从同步数据验证,这里就不做验证了,一般是没有问题的。

安全防护优化

    portsentry防恶意扫描

        安装

    下载地址:

tar zxvfportsentry-1.2.tar.gzcdportsentry_beta/make linuxmake &&make install

如果报错,修改1584行为一行进行编译

        配置

vim/usr/local/psionic/portsentry/portsentry.conf

#此文件记录允许合法扫描服务器的主机地址

IGNORE_FILE="/usr/local/psionic/portsentry/portsentry.ignore"

#此文件中保留了以往所有***主机的IP历史记录

HISTROY_FILE="/usr/lcal/psionic/portsentry/portsentry.history"

#此文件中是已经被阻止连接的主机IP记录

BLOCKED_FILE="/usr/local/psionic/portsentry/portsentry.blocked"

TCP 选项如下配置:

TCP_PORTS="21,3306,22,65535,1723,3389,5666,161,1521,1433,53,23,1,11,15,79,111,119,143,540,635,1080,1524,2000,5742,6667,12345,12346,20034,27665,31337,32771,32772,32773,32774,40421,49724,54320"

路由重定向

KILL_ROUTE="/sbin/routeadd -host $TARGET$ gw 333.444.555.666"

添加白名单:

vim/usr/local/psionic/portsentry/portsentry.ignore# Exclude alllocal interfaces172.16.100.100172.16.100.104127.0.0.1chmod  600/usr/local/psionic/portsentry/portsentry.ignorechmod  600/usr/local/psionic/portsentry/portsentry.conf

        扫描

/usr/local/psionic/portsentry/portsentry  -atcpecho"/usr/local/psionic/portsentry/portsentry" >> /etc/rc.local

启动扫描就会被相应的规则拉黑,这里就不验证了。

    fail2ban防止轻量级的DDOS

        安装

        更新epel

yum install epel-releaseyum install fail2ban.noarchyum install shorewall gamin-python shorewall-shellshorewall-perl shorewall-common python-inotify python-ctypes fail2ban

        配置

安装完成后,服务配置目录为:/etc/fail2ban

/etc/fail2ban/action.d                #动作文件夹,内含默认文件。iptables以及mail等动作配置
/etc/fail2ban/fail2ban.conf           #定义了fai2ban日志级别、日志位置及sock文件位置/etc/fail2ban/filter.d                #条件文件夹,内含默认文件。过滤日志关键内容设置/etc/fail2ban/jail.conf               #主要配置文件,模块化。主要设置启用ban动作的服务及动作阀值/etc/rc.d/init.d/fail2ban             #启动脚本文件

修改默认的日志文件定义:

vim /etc/fail2ban/fail2ban.conf末尾加入以下内容:logtarget = /var/log/fail2ban.logvim /etc/fail2ban/jail.conf# Http for Nginx[Nginx-Dos]enabled = trueport = http,httpsfilter = nginx-filteraction = iptables[name=NGINX,port=http, protocol=tcp]#sendmail-whois[name=NGINX,dest=49849895@qq.com]logpath =/data/weblogs/access_nginx.logmaxretry = 300findtime = 60bantime = 3600以上表示每60秒有300次的访问IP被封一小时创建如下文件:vim/etc/fail2ban/filter.d/nginx-filter.conf[Definition]failregex = 
 -.*-.*HTTP/1.* .* .*$ignoreregex =

        防护

        使用ab工具进行测试

故障转移&负载均衡

    一阶段解决方案

    根据线上的WEB环境,重新部署一台同样的服务器,DB采用复制机制同步过去。

    当主站出现故障,手动切换DNS解析到从服务器。

    二阶段解决方案

    一是:使用阿里云的SLB(负载均衡器)调度后端两台WEB,程序方面控制所有上传图片和写数据库的操作都发给Master 处理,健康检查功能实现节点失效剔除。

 二是:使用keepalive构建双热备方案。

    Keepalive安装   

wget http://www.keepalived.org/software/keepalived-1.2.12.tar.gztar zxvfkeepalived-1.2.12.tar.gzcdkeepalived-1.2.12ln -s/lib/modules/2.6.32-504.16.2.el6.x86_64/ /usr/src/kernels/./configure   --sysconf=/etc/--prefix=/usr/local/keepalived--with-kernel-dir=/usr/src/kernels/2.6.32-504.16.2.el6.x86_64/make &&make installcp/usr/local/keepalived/sbin/keepalived /usr/sbin/chkconfig  --add keepalivedchkconfig  keepalived oncp/etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak:>/etc/keepalived/keepalived.conf!Configuration File for keepalived global_defs {   notification_email {     zhangsan@gmail.com   }   notification_email_fromAlexandre.Cassen@firewall.loc   smtp_server 127.0.0.1   smtp_connect_timeout 30   router_id LVS_DEVEL} vrrp_instance VI_1 {    stateMASTER    interface eth0    virtual_router_id51    mcast_src_ip 172.16.100.105(此地址为master的主机地址)    priority 100    advert_int 1    authentication {        auth_type PASS        auth_pass 1q2w3e4r5t    }    virtual_ipaddress {        172.16.100.200    }}

备机上安装同上,唯一不同如下:

! ConfigurationFile for keepalived global_defs {   notification_email {     zhangsan@gmail.com   }   notification_email_fromAlexandre.Cassen@firewall.loc   smtp_server 127.0.0.1   smtp_connect_timeout 30   router_id LVS_DEVEL} vrrp_instance VI_1{    stateMASTER    interface eth0    virtual_router_id51    mcast_src_ip 172.16.100.106(此地址是slave的主机地址)    priority 99    advert_int 1    authentication {        auth_type PASS        auth_pass 1q2w3e4r5t    }    virtual_ipaddress {        172.16.100.200    }}

分别启动nginx

为了区别页面的转移,我这里简单修改主页面

Master master.com

Slave slave.cn

分别启动keepalive

servicekeepalived start

完成以上,你任意停掉任何一台nginx是不会自动切换的

因此需要监控主备的脚本:

#!/bin/bash#while:doNGINX_PID=`ps-C  nginx --no-header | wc -l`if [$NGINX_PID -eq 0 ]; then/work/nginx/sbin/nginxsleep5NGINX_PID=`ps-C  nginx --no-header | wc -l`echo$NGINX_PIDif [$NGINX_PID -eq 0 ]; then         /etc/init.d/keepalived stopfifisleep5donenohup  /root/check_nginx.sh &

这是一个无限循环的脚本,放在主Nginx机器上(因为目前主要是由它提供服务),每隔5秒执行一次,用ps -C 命令来收集nginx的PID值到底是否为0,如果是0的话(即Nginx进程死掉了),尝试启动nginx进程;如果继续为0,即nginx启动失改,则关闭本机的Keeplaived进程,VIP地址则会由备机接管,当然了,整个网站就会由备机的Nginx来提供服务了,这样保证Nginx进程的高可用。

修改nginx配置文件,让其不能正常启动(模拟故障),发现网站已经切换过去

    三阶段解决方案

前端WEB和后端DB分离,WEB采用集群方案,DB采用主从,读操作采用集群方案,外加缓存nosql,消息队列等技术。