1. 程式人生 > >服務安全與監控二

服務安全與監控二

一 部署audit監控檔案
1 審計的目的是基於事先配置的規則生成日誌,記錄可能發生在系統上的事件(正常或非正常行為的事件),審計不會為系統提供額外的安全保護,但她會發現並記錄違反安全策略的人及其對應的行為。
審計能夠記錄的日誌內容:
a) 日期與事件以及事件的結果
b) 觸發事件的使用者
c) 所有認證機制的使用都可以被記錄,如ssh等
d) 對關鍵資料檔案的修改行為等都可以被記錄

2 配置audit審計系統
1)安裝軟體包,檢視配置檔案(確定審計日誌的位置)

[[email protected] ~]# yum -y  install  audit                //安裝軟體包
[
[email protected]
~]# cat /etc/audit/auditd.conf //檢視配置檔案,確定日誌位置 log_file = /var/log/audit/audit.log //日誌檔案路徑 [[email protected] ~]# systemctl start auditd //啟動服務 [[email protected] ~]# systemctl enable auditd //設定開機自啟

2)配置審計規則
可以使用auditctl命令控制審計系統並設定規則決定哪些行為會被記錄日誌

[[email protected] ~]# auditctl  -s                        //查詢狀態
[[email protected] ~]# auditctl  -l                        //檢視規則
[[email protected] ~]# auditctl  -D                        //刪除所有規則

定義臨時檔案系統規則:
語法格式:auditctl -w path -p permission -k key_name
**path為需要審計的檔案或目錄
**許可權可以是r,w,x,a(檔案或目錄的屬性發生變化)
**Key_name為可選項,方便識別哪些規則生成特定的日誌項

[[email protected] ~]# auditctl  -w  /etc/passwd  -p wa  -k  passwd_change
//設定規則所有對passwd檔案的寫、屬性修改操作都會被記錄審計日誌
 [[email protected] ~]# auditctl  -w  /etc/selinux/  -p wa  -k  selinux_change
//設定規則,監控/etc/selinux目錄
 [[email protected] ~]# auditctl  -w  /usr/sbin/fdisk  -p x  -k  disk_partition
//設定規則,監控fdisk程式
[[email protected] ~]# auditclt  -w  /etc/ssh/sshd_conf  -p warx  -k  sshd_config
//設定規則,監控sshd_conf檔案

如果需要建立永久審計規則,則需要修改規則配置檔案

[[email protected] ~]# vim  /etc/audit/rules.d/audit.rules
-w /etc/passwd -p wa -k passwd_changes
-w /usr/sbin/fdisk -p x -k partition_disks

3 檢視並分析日誌
1)手動檢視日誌
檢視SSH的主配置檔案/etc/ssh/sshd_conf,檢視audit日誌資訊

[[email protected] ~]# tailf  /var/log/audit/audit.log
type=SYSCALL msg=audit(1517557590.644:229228): arch=c000003e 
syscall=2 success=yes exit=3 
a0=7fff71721839 a1=0 a2=1fffffffffff0000 a3=7fff717204c0 
items=1 ppid=7654 pid=7808 auid=0 uid=0 gid=0 euid=0 suid=0 
fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts2 ses=3 comm="cat" 
exe="/usr/bin/cat" 
subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key="sshd_config"
.. ..

#內容分析
# type為型別
# msg為(time_stamp:ID),時間是date +%s(1970-1-1至今的秒數)
# arch=c000003e,代表x86_64(16進位制)
# success=yes/no,事件是否成功
# a0-a3是程式呼叫時前4個引數,16進位制編碼了
# ppid父程序ID,如bash,pid程序ID,如cat命令
# auid是稽核使用者的id,su - test, 依然可以追蹤su前的賬戶
# uid,gid使用者與組
# tty:從哪個終端執行的命令
# comm="cat"            使用者在命令列執行的指令
# exe="/bin/cat"        實際程式的路徑
# key="sshd_config"    管理員定義的策略關鍵字key
# type=CWD        用來記錄當前工作目錄
# cwd="/home/username"
# type=PATH

# ouid(owner's user id)    物件所有者id
# guid(owner's groupid)    物件所有者id

2)通過工具搜尋日誌
系統提供的ausearch命令可以方便的搜尋特定日誌,預設該程式會搜尋/var/log/audit/audit.log,ausearch options -if file_name可以指定檔名

[[email protected] ~]# ausearch -k sshd_config -i  

//根據key搜尋日誌,-i選項表示以互動式方式操作

二 加固常見服務的安全
Nginx安全優化包括:刪除不要的模組、修改版本資訊、限制併發、拒絕非法請求、防止buffer溢位。
MySQL安全優化包括:初始化安全指令碼、密碼安全、備份與還原、資料安全。
Tomcat安全優化包括:隱藏版本資訊、降權啟動、刪除預設測試頁面.
1 優化Nginx服務的安全配置
Nignx是模組化設計的軟體,需要什麼功能與模組以及不需要哪些模組,都可以在編譯安裝軟體時自定義,使用–with引數可以開啟某些模組,使用–without可以禁用某些模組。最小化安裝永遠都是對的方案!

[[email protected] nginx-1.12]# ./configure \
>--without-http_autoindex_module \            //禁用自動索引檔案目錄模組
>--without-http_ssi_module

[[email protected] nginx-1.12.2]# ./configure --help | grep "\-\-without"
  --without-select_module            disable select module
  --without-poll_module              disable poll module
  --without-http_charset_module      disable ngx_http_charset_module
  ………………

2) 修改版本資訊,並隱藏具體的版本號
認Nginx會顯示版本資訊以及具體的版本號,這些資訊給攻擊者帶來了便利性,便於他們找到具體版本的漏洞。
如果需要遮蔽版本號資訊,執行如下操作,可以隱藏版本號。

[[email protected] ~]# vim /usr/local/nginx/conf/nginx.conf
… …
http{
     server_tokens off;                            //在http下面手動新增這麼一行
     … …
}
[[email protected] ~]# nginx -s reload
[[email protected] ~]# curl -I http://192.168.4.5          //檢視伺服器響應的頭部資訊

但伺服器還是顯示了使用的軟體為nginx,通過如下方法可以修改該資訊。隱藏ngninx軟體資訊,顯示為Jacob
[[email protected] nginx-1.12]# vim src/http/ngx_http_header_filter_module.c
//注意:vim這條命令必須在nginx-1.12原始碼包目錄下執行!!!!!!
//該檔案修改前效果如下:

static u_char ngx_http_server_string[] = "Server: nginx" CRLF;
static u_char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF;
static u_char ngx_http_server_build_string[] = "Server: " NGINX_VER_BUILD CRLF;

//下面是我們修改後的效果:

static u_char ngx_http_server_string[] = "Server: Jacob" CRLF;
static u_char ngx_http_server_full_string[] = "Server: Jacob" CRLF;
static u_char ngx_http_server_build_string[] = "Server: Jacob" CRLF;

//修改完成後,再去編譯安裝Nignx,版本資訊將不再顯示為Nginx,而是Jacob

[[email protected] nginx-1.12]# ./configure
[[email protected] nginx-1.12]# make && make install
[[email protected] nginx-1.12]# killall nginx
[[email protected] nginx-1.12]# /usr/local/nginx/sbin/nginx            //啟動服務
[[email protected] nginx-1.12]# curl -I http://192.168.4.5            //檢視版本資訊驗證

3) 限制併發量
DDOS攻擊者會發送大量的併發連線,佔用伺服器資源(包括連線數、頻寬等),這樣會導致正常使用者處於等待或無法訪問伺服器的狀態。
Nginx提供了一個ngx_http_limit_req_module模組,可以有效降低DDOS攻擊的風險,操作方法如下:

[[email protected] ~]# vim /usr/local/nginx/conf/nginx.conf
… …
http{
… …
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
    server {
        listen 80;
        server_name localhost;
        limit_req zone=one burst=5;
            }
}

//備註說明:
//limit_req_zone語法格式如下:
//limit_req_zone key zone=name:size rate=rate;
//上面案例中是將客戶端IP資訊儲存名稱為one的共享記憶體,記憶體空間為10M
//1M可以儲存8千個IP資訊,10M可以儲存8萬個主機連線的狀態,容量可以根據需要任意調整
//每秒中僅接受1個請求,多餘的放入漏斗
//漏斗超過5個,超過的多出來的請求將會被拒絕

[[email protected] ~]# /usr/local/nginx/sbin/nginx -s reload

模仿小型Doos攻擊:
在另一終端訪問nginx伺服器:

[[email protected] ~]# ab -c 100 -n 100 http://192.168.4.33/        

注意用ab壓力測試工具時,IP地址後面需要加斜線/

Document Path:          /
Document Length:        6 bytes

Concurrency Level:      100
Time taken for tests:   0.062 seconds
Complete requests:      100              //100個請求被處理,沒有失敗
Failed requests:        0

修改配置檔案加入以下內容(注意放在http塊下,與server同級)

limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

漏斗中最多每秒5個請求:(注意放在server塊下)

limit_req zone=one burst=5;

再次測試:

[[email protected] ~]# ab -c 100 -n 100 http://192.168.4.33/
Concurrency Level:      100
Time taken for tests:   5.003 seconds
Complete requests:      100
Failed requests:        94                   //94個連線失敗,被拒絕

4)拒絕非法的請求
網站使用的是HTTP協議,該協議中定義了很多方法,可以讓使用者連線伺服器,獲得需要的資源。但實際應用中一般僅需要get和post。
未修改伺服器配置前,客戶端使用不同請求方法測試:

[[email protected] ~]# curl -i -X GET  http://192.168.4.5            //正常
[[email protected] ~]# curl -i -X HEAD http://192.168.4.5            //正常

//curl命令選項說明:
//-i選項:訪問伺服器頁面時,顯示HTTP的頭部資訊
//-X選項:指定請求伺服器的方法

通過如下設定可以讓Nginx拒絕非法的請求方法:

[email protected] ~]# vim /usr/local/nginx/conf/nginx.conf
http{
       server {
                 listen 80;
#這裡,!符號表示對正則取反,~符號是正則匹配符號
#如果使用者使用非GET或POST方法訪問網站,則retrun返回444的錯誤資訊
              if ($request_method !~ ^(GET|POST)$ ) {
                     return 444;
               }    
        }
}

[[email protected] ~]# /usr/local/nginx/sbin/nginx -s reload

修改伺服器配置後,客戶端使用不同請求方法測試:

[[email protected] ~]# curl -i -X GET  http://192.168.4.5            //正常
[[email protected] ~]# curl -i -X HEAD http://192.168.4.5            //報錯
[[email protected] ~]# curl -i -X POST  http://192.168.4.33
HTTP/1.1 405 Not Allowed
Server: aaa
Date: Mon, 10 Dec 2018 06:12:16 GMT
Content-Type: text/html
Content-Length: 166
Connection: keep-alive

<html>
<head><title>405 Not Allowed</title></head>
<body bgcolor="white">
<center><h1>405 Not Allowed</h1></center>
<hr><center>nginx</center>
</body>
</html>

注意:這裡POST方法出現405 狀態碼,原因為 Apache、IIS、Nginx等絕大多數web伺服器,都不允許靜態檔案響應POST請求

5)防止buffer溢位
當客戶端連線伺服器時,伺服器會啟用各種快取,用來存放連線的狀態資訊。
如果攻擊者傳送大量的連線請求,而伺服器不對快取做限制的話,記憶體資料就有可能溢位(空間不足)。
修改Nginx配置檔案,調整各種buffer引數,可以有效降低溢位風險。

[[email protected] ~]# vim /usr/local/nginx/conf/nginx.conf
http{
client_body_buffer_size  1K;               //資料包正文快取大小
client_header_buffer_size 1k;              //資料包頭快取包頭的最小值
client_max_body_size 1k;                  //資料包正文快取最大值
large_client_header_buffers 2 1k;        //資料包頭快取最大值
 … …
}

[[email protected] ~]# /usr/local/nginx/sbin/nginx -s reload

三 資料庫安全:
1)初始化安全指令碼
安裝完MariaDB或MySQL後,預設root沒有密碼,並且提供了一個任何人都可以操作的test測試資料庫。有一個名稱為mysql_secure_installation的指令碼,該指令碼可以幫助我們為root設定密碼,並禁止root從遠端其他主機登陸資料庫,並刪除測試性資料庫test。

[[email protected] ~]# systemctl status mariadb

//確保服務已啟動

[[email protected] ~]# mysql_secure_installation

//執行初始化安全指令碼

2)修改密碼成功,而且密碼在資料庫中是加密的,有什麼問題嗎?問題是你的密碼被明文記錄了,下面來看看明文密碼:

[[email protected] ~]# cat .bash_history
mysqladmin -uroot -pxxx password 'redhat'

//通過命令列修改的密碼,bash會自動記錄歷史,歷史記錄中記錄了明文密碼

[[email protected] ~]# cat .mysql_history 
set password for [email protected]'localhost'=password('redhat');
select user,host,password from mysql.user;
flush privileges;

//通過mysql命令修改的密碼,mysql也會有所有操作指令的記錄,這裡也記錄了明文密碼

刪除歷史記錄:

[[email protected] ~]# >.bash_history
[[email protected] ~]# > .mysql_history

另外資料庫還有一個binlog日誌裡也有明文密碼(5.6版本後修復了)。
怎麼解決?
管理好自己的歷史,不使用明文登入,選擇合適的版本5.6以後的版本,
日誌,行為審計(找到行為人),使用防火牆從TCP層設定ACL(禁止外網接觸資料庫)

3)資料備份與還原
這裡省1萬字

4)資料安全
在伺服器上(192.168.4.5),建立一個數據庫賬戶

[[email protected] ~]# mysql -uroot -predhat

//使用管理員,登陸資料庫

MariaDB [(none)]> grant all on *.* to [email protected]'%' identified by '123';

//建立一個新賬戶tom

使用tcpdump抓包(192.168.4.5)

[[email protected] ~]# tcpdump -w log -i any src or dst port 3306

//抓取源或目標埠是3306的資料包,儲存到log檔案中

客戶端(192.168.4.100)從遠端登陸資料庫伺服器(192.168.4.5)

[[email protected] ~]# mysql -utom -p123 -h 192.168.4.5

//在192.168.4.100這臺主機使用mysql命令登陸遠端資料庫伺服器(192.168.4.5)
//使用者名稱為tom,密碼為123

MariaDB [(none)]> select * from mysql.user;

//登陸資料庫後,任意執行一條查詢語句

回到伺服器檢視抓取的資料包

[[email protected] ~]# tcpdump -A -r log

//使用tcpdump檢視之前抓取的資料包,很多資料庫的資料都明文顯示出來

如何解決?
可以使用SSH遠端連線伺服器後,再從本地登陸資料庫(避免在網路中傳輸資料,因為網路環境中不知道有沒有抓包者)。
或者也可以使用SSL對MySQL伺服器進行加密,類似與HTTP+SSL一樣,MySQL也支援SSL加密(確保網路中傳輸的資料是被加密的)。

四 Tomcat安全性
1 隱藏版本資訊、修改tomcat主配置檔案(隱藏版本資訊) //可以看到伺服器版本號
未修改版本資訊前,使用命令檢視伺服器的版本資訊

[[email protected] ~]# curl -I http://192.168.2.100:8080/xx        
//訪問不存在的頁面檔案,檢視頭部資訊
[[email protected] ~]# curl -I http://192.168.2.100:8080    
//訪問存在的頁面檔案,檢視頭部資訊
[[email protected] ~]# curl http://192.168.2.100:8080/xx
//訪問不存在的頁面檔案,檢視錯誤資訊 (報錯資訊結尾能看到軟體和版本資訊)

2 修改tomcat配置檔案隱藏報錯時顯示的軟體資訊

[[email protected] ~]# yum -y install java-1.8.0-openjdk-devel
[[email protected] ~]# cd /usr/local/tomcat/lib/
[[email protected] lib]# jar -xf catalina.jar
[[email protected] lib]# vim org/apache/catalina/util/ServerInfo.propertie
server.info=wahaha
server.number=0.0.0.0
server.built=Dec 1 2015 22:30:46 UTC

[[email protected] lib]# /usr/local/tomcat/bin/shutdown.sh
[[email protected] lib]# /usr/local/tomcat/bin/startup.sh
注意如果tomcat服務起不來,執行以下操作後再次啟動:
[[email protected] lib]# mv /dev/random{,.bak}
[[email protected] lib]# ln -s /dev/urandom /dev/random

3 修改配置檔案隱藏f12顯示的軟體資訊
在8080埠配置項中加入server=“wahaha”

[[email protected] lib]# vim /usr/local/tomcat/conf/server.xml
69     <Connector port="8080" protocol="HTTP/1.1"
 70                connectionTimeout="20000"
 71                redirectPort="8443" server="wahaha"/>

訪問測試

[[email protected] lib]# curl -I http://192.168.4.33:8080
HTTP/1.1 200 OK
Content-Type: text/html;charset=UTF-8
Transfer-Encoding: chunked
Date: Mon, 10 Dec 2018 08:16:15 GMT
Server: wahaha                  //軟體資訊已經改變

4 降級啟動

預設tomcat使用系統高階管理員賬戶root啟動服務,啟動服務儘量使用普通使用者
[[email protected] ~]# useradd tomcat
[[email protected] ~]# chown -R tomcat:tomcat /usr/local/tomcat/
//修改tomcat目錄的許可權,讓tomcat賬戶對該目錄有操作許可權
[[email protected] ~]# su -c /usr/local/tomcat/bin/startup.sh tomcat
//使用su命令切換為tomcat賬戶,以tomcat賬戶的身份啟動tomcat服務
[[email protected] ~]# chmod +x /etc/rc.local                //該檔案為開機啟動檔案
[[email protected] ~]# vim /etc/rc.local                     //修改檔案,新增如下內容
su -c /usr/local/tomcat/bin/startup.sh tomcat

五 使用diff和patch工具打補丁
優化提升常見網路服務的安全性,主要完成以下任務操作
–使用diff對比檔案差異
–使用diff生成補丁檔案
–使用patch命令為舊版本打補丁
程式是人設計出來的,總是會有這樣那樣的問題與漏洞,目前的主流解決方法就是為有問題的程式打補丁,升級新版本。
在Linux系統中diff命令可以為我們生成補丁檔案,然後使用patch命令為有問題的程式程式碼打補丁
1 編寫兩個版本的指令碼,一個為v1版本,一個為v2版本。

[[email protected] ~]# vim /test1.sh
#!/bin/bash
echo "hello wrld"

[[email protected] ~]# vim /test2.sh
#!/bin/bash
echo "hello the world"
echo "test file

2 使用diff命令檢視不同版本檔案的差異

[[email protected] ~]# diff /test1.sh /test2.sh
1c1,2
< echo "hello wrld"
---
> echo "hello the world"
> echo "test file"

[[email protected] ~]# diff -u /test1.sh /test2.sh           
--- /test1.sh	2018-12-10 16:44:55.141103586 +0800
+++ /test2.sh	2018-12-10 16:45:17.686103586 +0800
@@ -1 +1,2 @@          //怎麼把第一個檔案變成第二個檔案
 #!/bin/bash                     //第一行不變
-echo "hello wrld"           //刪除第二行
+echo "hello the world"      //加入這一行
+echo "test file"                   //再加入這一行

diff製作補丁檔案的原理:告訴我們怎麼修改第一個檔案後能得到第二個檔案。
這樣如果第一個版本的指令碼有漏洞,我們不需要將整個指令碼都替換,僅需要修改有問題的一小部分程式碼即可,diff剛好可以滿足這個需求!
像Linux核心這樣的大塊頭,一旦發現有一個小漏洞,我們不可能把整個核心都重新下載,全部替換一遍,而僅需要更新有問題的那一小部分程式碼即可!
diff命令常用選項:
-u 輸出統一內容的頭部資訊(打補丁使用),計算機知道是哪個檔案需要修改
-r 遞迴對比目錄中的所有資源(可以對比目錄)
-a 所有檔案視為文字(包括二進位制程式)
-N 無檔案視為空檔案(空檔案怎麼變成第二個檔案)
-N選項備註說明:
A目錄下沒有txt檔案,B目錄下有txt檔案
diff比較兩個目錄時,預設會提示txt僅在B目錄有(無法對比差異,修復檔案)
diff比較時使用N選項,則diff會拿B下的txt與A下的空檔案對比,補丁資訊會明確說明如何從空檔案修改後變成txt檔案,打補丁即可成功!

3 使用patch命令對單檔案程式碼打補丁

1)生成補丁檔案
[[email protected] ~]# diff -u /test1.sh /test2.sh > test.patch
[[email protected] ~]# cat test.patch
--- /test1.sh	2018-12-10 16:44:55.141103586 +0800
+++ /test2.sh	2018-12-10 16:45:17.686103586 +0800

@@ -1 +1,2 @@
-echo "hello wrld"
+echo "hello the world"
+echo "test file"

2)安裝軟體,準備測試環境

[[email protected] ~]#  yum -y install patch
[[email protected] ~]# cd /mnt
[[email protected] mnt]# cat test1.sh
#!/bin/bash
echo "hello wrld"
[[email protected] mnt]# cat test2.sh
#!/bin/bash
echo "hello the world"
echo "test file"

3)使用patch命令打補丁
在程式碼相同目錄下為程式碼打補丁

[[email protected] mnt]# patch -p0 < test.patch
//patch -pnum(其中num為數字,指定刪除補丁檔案中多少層路徑字首)
//如原始路徑為/u/howard/src/blurfl/blurfl.c
//-p0則整個路徑不變
//-p1則修改路徑為u/howard/src/blurfl/blurfl.c
//-p4則修改路徑為blurfl/blurfl.c
//-R(reverse)反向修復,-E修復後如果檔案為空,則刪除該檔案

[[email protected] mnt]# cat test1.sh       //打完補丁後文件內容自動同步
#!/bin/bash
echo "hello the world"
echo "test file"
[[email protected] mnt]# patch -RE < test.patch                     //還原舊版本,反向修復

4 對比目錄中所有檔案的差異
1) 準備環境

[[email protected] ~]# echo "hello world" > source1/test.sh
[[email protected] ~]# echo "hello the world" > source2/test.sh
[[email protected] ~]# echo "data" > source2/tmp.txt
[[email protected] ~]# cp /bin/find source1/
[[email protected] ~]# cp /bin/find source2/
[[email protected] ~]# echo "11" >> source2/find 
[[email protected] ~]# tree source1
source1
├── find
└── test.sh

[[email protected] ~]# tree source2
source2
├── find
├── test.sh
└── tmp.txt

2)使用前面建立的source1和source2目錄下的程式碼為素材,生成補丁檔案

[[email protected] ~]# diff -uraN source1 source2 > patch

3)使用patch命令為程式碼打補丁

[[email protected] ~]# cd source1
[[email protected] source1]# patch -p1 < ../patch
patching file find
patching file test.sh
patching file tmp.txt
[[email protected] source1]# ls            //打補丁成功
find  test.sh  tmp.txt
[[email protected] source1]# md5sum find
dae5fe536814ad6dc6108cafc7e2f600  find
[[email protected] source1]# md5sum /root/source2/find
dae5fe536814ad6dc6108cafc7e2f600  /root/source2/find

如果打補丁出錯,用如下命令還原

[[email protected] source1]# patch -R -p1 < ../patch
[[email protected] source1]# ls
find  test.sh

4)在其他目錄打補丁

 [[email protected] source1]# cd /opt
 [[email protected] opt]# diff -ruNa /root/source1 /root/source2 > /root/x.patch
 [[email protected] opt]# cd /root/source1
 [[email protected] source1]# pwd
  /root/source1
 [[email protected] source1]# patch -p3 < /root/x.patch      //刪除前面幾級目錄(針對當前所在目錄)

patching file find
patching file test.sh
patching file tmp.txt

注意:

[[email protected] source1]# cat /root/x.patch
--- /root/source1/find	2018-12-10 17:52:08.185103586 +0800            
+++ /root/source2/find	2018-12-10 17:33:12.567103586 +0800