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.ini service php-fpm restart
以上内容的脚本如下:
#!/bin/bash # Author by:Tommy.Gandolf # Acl PowerSetting rpm -qa | grep acl> /dev/null 2>&1 if [ $? -eq 0 ];then echo "Acl is alreadinstalled" else yum install acl libacl libacl-devel -y fi echo "Starttingwill Setting Acl..." sleep 3 chown -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 3 HTDOCS=$(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.txt DEFINE="5" cat /root/black.txt | while read LINE do 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 fi done
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= 100 log_bin= mysql-bin binlog_format= mixed expire_logs_days= 30 replicate-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.cnf server-id= 200 relay-log= mysql-relay-bin replicate-wild-ignore-table=mysql.% replicate-wild-ignore-table=information_schema.% log_bin= mysql-bin binlog_format= mixed expire_logs_days= 30 #service mysqld restart mysql> 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: 0 Master_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: 100 1 row in set (0.00 sec) ERROR: No query specified mysql>
主从同步数据验证,这里就不做验证了,一般是没有问题的。
安全防护优化
portsentry防恶意扫描
安装
下载地址:http://sourceforge.net/projects/sentrytools/
tar zxvfportsentry-1.2.tar.gz cdportsentry_beta/ make linux make &&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 interfaces 172.16.100.100 172.16.100.104 127.0.0.1 chmod 600/usr/local/psionic/portsentry/portsentry.ignore chmod 600/usr/local/psionic/portsentry/portsentry.conf
扫描
/usr/local/psionic/portsentry/portsentry -atcp echo"/usr/local/psionic/portsentry/portsentry" >> /etc/rc.local
启动扫描就会被相应的规则拉黑,这里就不验证了。
fail2ban防止轻量级的DDOS
安装
更新epel源
yum install epel-release yum install fail2ban.noarch yum 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.log vim /etc/fail2ban/jail.conf # Http for Nginx [Nginx-Dos] enabled = true port = http,https filter = nginx-filter action = iptables[name=NGINX,port=http, protocol=tcp] #sendmail-whois[name=NGINX,dest=49849895@qq.com] logpath =/data/weblogs/access_nginx.log maxretry = 300 findtime = 60 bantime = 3600 以上表示每60秒有300次的访问IP被封一小时 创建如下文件: vim/etc/fail2ban/filter.d/nginx-filter.conf [Definition] failregex = <HOST> -.*-.*HTTP/1.* .* .*$ ignoreregex =
防护
使用ab工具进行测试
故障转移&负载均衡
一阶段解决方案
根据线上的WEB环境,重新部署一台同样的服务器,DB采用复制机制同步过去。
当主站出现故障,手动切换DNS解析到从服务器。
二阶段解决方案
一是:使用阿里云的SLB(负载均衡器)调度后端两台WEB,程序方面控制所有上传图片和写数据库的操作都发给Master 处理,健康检查功能实现节点失效剔除。
二是:使用keepalive构建双热备方案。
Keepalive安装
wget http://www.keepalived.org/software/keepalived-1.2.12.tar.gz tar zxvfkeepalived-1.2.12.tar.gz cdkeepalived-1.2.12 ln -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 install cp/usr/local/keepalived/sbin/keepalived /usr/sbin/ chkconfig --add keepalived chkconfig keepalived on cp/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: do NGINX_PID=`ps-C nginx --no-header | wc -l` if [$NGINX_PID -eq 0 ]; then /work/nginx/sbin/nginx sleep5 NGINX_PID=`ps-C nginx --no-header | wc -l` echo$NGINX_PID if [$NGINX_PID -eq 0 ]; then /etc/init.d/keepalived stop fi fi sleep5 done nohup /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,消息队列等技术。
转载于:https://blog.51cto.com/diudiu/1678426