涉及知識點
- wrappers是一個工作在傳輸層的安全工具,凡是調用了libwrap.so庫文件的應用都受wrappers的訪問控制。wrappers依賴/etc/hosts.allow和/etc/hosts.deny兩個文件,wrappers會先檢查/etc/hosts.allow白名單,然後檢查/etc/hosts.deny黑名單。
- 查看應用程序是否受wrappers控制方法(以sshd應用程序爲例子)
- 方法一:strings
[root@localhost ~/test]$strings /usr/sbin/sshd | grep hosts_access hosts_access
- 方法二:ldd
[root@localhost ~/test]$ldd /usr/sbin/sshd | grep libwrap libwrap.so.0 => /lib64/libwrap.so.0 (0x00007f59aac26000)
腳本如下
#!/bin/bash
#
#
#===================================================================
#
# author: 9528
# mail: [email protected]
# date: 2019-08-02
#
#-------------------------------------------------------------------
#
# 簡述:
# 實現檢測$Check_interval_time時間內ssh登陸密碼輸入錯誤次數達到
# $Allow_num次上限值的ip,視其爲有攻擊性,將ip加入/etc/hosts.deny黑
# 名單中,拒絕訪問。可把此腳本加入定時任務crontab中,實現定時檢測。
#
#
# 注意:
# 此腳本只針對ssh訪問,在centos7.6上測試,telnet並不受
# /etc/hosts.deny黑名單控制。telnet是明文傳輸,一般已棄用,若你開啓
# 了telnet服務,則需要考慮telnet訪問。
#
#===================================================================
#檢測時間間隔爲30分鐘,推薦和crontab定時任務時間設置一致
Check_interval_time=30
#登錄失敗次數超過10次即加入黑名單
Allow_num=10
#存放臨時文件的目錄
Dir="checkip"
#臨時文件
Deny_ip_file="$Dir/deny.file"
#系統文件
System_deny_file="/etc/hosts.deny"
System_login_log_file="/var/log/secure"
#月份
Month=`date +"%b"`
#日期,注意這裏Day_tmp的值是兩個字符(個位數時會包含一個空格)
Day_tmp=`date +"%e"`
#把Day_tmp中的空格去除,便於後面awk語句中比對$2
Day=`echo $Day_tmp |tr -d " "`
#上一次檢測時間,用當前時間減去$Check_interval_time
Last_check_time=`date +"%H:%M:%S" -d"-$Check_interval_time min"`
if [ ! -d $Dir ];then
mkdir $Dir
if [ $? -ne 0 ];then
echo "Error: mdkir $Dir failed."
exit 1
fi
fi
#
#清空臨時文件
> $Deny_ip_file
#
#/var/log/secure系統登陸日誌不存在時報錯退出
if [ ! -f $System_login_log_file ];then
echo "Error: cat $System_login_log_file failed. No such file."
exit 2
fi
#
#
#分步驟取出符合條件的ip:
# 1.取出今天內的登陸日誌
# 2.取出今天內ssh登陸密碼錯誤的日誌
# 3.取出$Check_interval_time時間內ssh登陸密碼錯誤的日誌
# 4.統計每個ip個數
# 5.取出輸入密碼次數超過允許上限次數的ip
# 6.若黑名單中沒有此ip,則強制加入黑名單,拒絕訪問
#
# 注意變量引用時使用的單引號和雙引號
awk -v last_time=$Last_check_time -v num=$Allow_num '$1=="'"$Month"'" \
&& $2=="'"$Day"'" && /Failed password/{if($3 > last_time){count[$11]++}} \
END{for(ip in count){if(count[ip] > num){print ip}}}' $System_login_log_file > $Deny_ip_file
while read line;do
fgrep sshd:$line $System_deny_file > /dev/null
if [ $? -ne 0 ];then
echo sshd:$line:deny >> $System_deny_file
fi
done < $Deny_ip_file