小型企业网站的架构 & 安全配置与防护

小型企业网站的架构 & 安全配置与防护,第1张

小型企业网站的架构 & 安全配置与防护

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带有反d窗口的选项一般都在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 }' | 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 }'| 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}'`
                host=`echo $LINE    |awk '{print }'`
                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,[email protected]]
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 {
     [email protected]
   }
   [email protected]
   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 {
     [email protected]
   }
   [email protected]
   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://outofmemory.cn/zz/779988.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-04
下一篇 2022-05-04

发表评论

登录后才能评论

评论列表(0条)

保存