小型企業網站的架構 & 安全配置與防護

WEB架構    

    正常狀態

    wKioL1W0Qurzjm3TAACZEnvf0Jc491.jpg

    故障切換

    wKiom1W0QTvx4eA6AACSYhtk3mY038.jpg

    Lnmp環境配置

    採用一鍵安裝包

wKioL1W0Q4byWt24AAJP56z8_Qo872.jpg

wKiom1W0QZ6Tc-LbAATAQGEXQ14236.jpg

系統安裝優化

    web版本泄露

        對404頁面進行處理,或者說針對不存在的文件或目錄進行404錯誤返回,避免出現nginx版本泄露信息(nginx源碼編譯,隱藏版本信息)

    /tmp目錄權限

    這裏假設目標服務器已經被上傳***,【那麼我們就把目標堵死在這裏】。首先,因爲/tmp目錄是1777的粘滯位權限,因此會在此目錄上傳exp進行root提權  

yum install acl libacl libacl-devel –y

 查看/tmp目錄權限

wKiom1W0Qn_A6I8SAAEpMiqkzjc009.jpg

因爲運行WEB的賬戶是www 或者其他賬戶,因此需要對WEB賬戶進行權限控制。在爲設置權限之前,如下:

wKiom1W0QtKgp0ZOAAYKVGVGjwQ206.jpg

wKioL1W0RLyTuotBAAGJX8Wmg8A747.jpg

因爲mysq.sock在此目錄下,因此我給了www賬戶的執行權限,如果不在可以直接給r權限即可,現在我們嘗試傳文件試試

wKioL1W0RSviFSfxAAWhcs0LTTc561.jpg

大部分webshell帶有反彈窗口的選項一般都在tmp下創建,現在就會失敗。下面針對命令作下限制,在爲做限制之前如下:    wKioL1W0Ravjt43IAAT77uawOas490.jpg    

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

wKioL1W0Ri7B0TTvAADiOwcH1Pw922.jpg

wKiom1W0REXCNl4EAAD2XRugQ68840.jpg

wKioL1W0RjDyW8lXAAGG1dfGw6w890.jpg

防旁註,很多時候,***人員對主站無法下手,就會採用同一服務器的其他網站進行着手,然後webshell會獲取你的主站信息。


wKioL1W0Rq2xaX-SAAVzYq0OYOI837.jpg

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

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

wKiom1W0RRODumgaAAGxDYIzGZI774.jpg 


以上內容的腳本如下:

#!/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  

wKiom1W0RfKzNOTfAAKy1TltsYU399.jpg

wKioL1W0R97Rv2CHAAbOV7xJ6tM226.jpg

wKiom1W0RfXRAfdSAAI0dcWNfcc538.jpg

 接下來正式進行主從同步的操作:

創建同步賬戶:(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行爲一行進行編譯

wKiom1W0SHnxAZn2AAFk45Hqwj4136.jpg

        配置

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工具進行測試

wKiom1W0SnnwRmpCAAIWX7WIQz4485.jpg

wKioL1W0TGTDn5SpAANbirJzjyw112.jpg

故障轉移&負載均衡

    一階段解決方案

    根據線上的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

wKiom1W0S9bRXQwcAAND92uEON4225.jpg

wKioL1W0TcCSMK6fAABztLRjMYY435.jpg

完成以上,你任意停掉任何一臺nginx是不會自動切換的

wKioL1W0TsaAW7O-AAEeQ85Q9vQ017.jpg

因此需要監控主備的腳本:

#!/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配置文件,讓其不能正常啓動(模擬故障),發現網站已經切換過去

wKiom1W0THfSFNW9AAM7xoLZYoc564.jpg

wKioL1W0TmLyenBrAACS2etcMTc470.jpg

    三階段解決方案

前端WEB和後端DB分離,WEB採用集羣方案,DB採用主從,讀操作採用集羣方案,外加緩存nosql,消息隊列等技術。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章