#!/bin/bash
# 小绿叶技术博客扫段攻击拦截系统
#抓包监控tcp攻击ip进行拦截。
adminuser=ddoss.cn
hostname=homeVPN
catipToken=0
iptablesDir=/etc/init.d/shell
iptablesDirFile=iptablesConfig.txt
iptablesFile=$iptablesDir/$iptablesDirFile
submitDate=$(date +%s)
sqlQuery(){
local datauser="enchantment" # local 局部变量: 当前函数有效
local database="enchantment"
local passwd="eisc.cn"
local serverIp="10.1.1.3"
local sqlCMD=$1
local sqlcmd="use $database; $sqlCMD " # 获取执行函数 传入的 第一个参数
mysql -h $serverIp -u$datauser -p$passwd -e "$sqlcmd" | grep -v ip
}
zhuabao(){
echo "eisc 安防系统启动扫描,时间 :" `date +%Y-%m-%d-%H:%M:%y` >> /$HOME/eisc-anfang.txt
# 将firewalld 防火墙加入开机启动
folder="/datadisk/eisc/anfang/ip"
sudo mkdir -p $folder ; sudo chmod 777 -R $folder
# 抓包等待30s 杀掉进程,符号 & 并列执行
totalCount=1000
timetcp=10
sudo tcpdump -nn > $folder/ipfwyuan.txt & sleep $timetcp
sudo killall -9 tcpdump
echo "访问限制tcp连接数;$totalCount 抓包时长为 $timetcp"
sudo rm -rf $folder/ipfw.txt
cat $folder/ipfwyuan.txt | grep S | awk -F" " '{print $3}' | awk -F"." '{print $1 "." $2 "." $3 "." $4}' |sort | uniq -c > $folder/ipfw.txt
sed -i "/^$/d" $folder/ipfw.txt
cat $folder/ipfw.txt
#-------------------------------- 防火墙 ------------------------------------------#
}
ipFlag() {
local ip=$1
if [[ "$ip" =~ ^([0-9]{
1,3}\.){
3}[0-9]{
1,3}$ ]]; then # =~ 正则表达式匹配; 0-9 长度3个,\ 转译结束是 . 符号 有3段,最后末尾是 0-9 长度3个
IFS='.' read -r a b c d <<< "$ip" # 内部字段分隔符 . 将 ip使用符号 <<< 重定向到read 命令; 有. 就分割
if [ $a -lt 256 ] && [ $b -lt 255 ] && [ $c -lt 255 ] && [ $d -lt 255 ]; then
echo "yes" # 有效 IP
else
echo "no"
fi
else
echo "no" # 无效 IP
fi
}
sqlbmd(){
local ip=$1
local table="pk_submit_ip"
local sql="SELECT ip FROM $table WHERE approve='pass' AND ip='$ip';"
sqlQuery "$sql" # 调用函数,并且传入一个参数
}
iptablesInit(){
local ip=$1
local bmdIPFlag=$2
local iptablesStr="*filter
# 允许本地回环
-A INPUT -i lo -j ACCEPT
# 允许已建立的连接
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 拒绝所有其他流量
-A INPUT -j DROP
COMMIT"
sudo mkdir -p $iptablesDir ; sudo chmod 777 -R $iptablesDir ; touch $iptablesFile
local iptablesFileStr=$(cat $iptablesFile)
if [ -z "$iptablesFileStr" ];then
sudo echo -e "$iptablesStr" > $iptablesFile
echo "正在写文件"
else
echo "文件已经初始化"
fi
local NR=$( cat -n $iptablesFile | grep -w COMMIT | awk -F" " '{print $1}' )
local ipNR=$( cat -n $iptablesFile | grep -w $ip | awk -F" " '{print $1}' )
ipFlag=$( ipFlag $ip )
if [ -z "$ipNR" ]; then
if [ "$ipFlag" == "yes" ] && [ "$bmdIPFlag" != "yes" ];then
sed -i "$NR i -A INPUT -s $ip -j DROP" "$iptablesFile"
echo "[running] 正在写入文件字符串 $ip"
else
echo "[fail] 非ip: $ip 或者有白名单"
fi
elif [ "$bmdIPFlag" == "yes" ]; then
sed -i "$ipNR d" "$iptablesFile"
echo "[running] 正在解除封停,删除匹配字符串 $ip"
fi
}
# 安全防火墙拦截规则执行firewalld
firewalldjz() {
local ip=$1
local CountIP=$2
local Myexplain=$3
local updateFlag=0
local sql="select ip from pk_firewall_ip WHERE ip='$ip' LIMIT 1 OFFSET 0 "
local sqlFirewallIp=$( sqlQuery "$sql" ) ;
catIPurl=$(curl -s https://api.ip138.com/ipdata/\?ip=$ip\&datatype=jsonp\&token=$catipToken | jq -r '.data[]')
catIPstr=$( echo $catIPurl )
# jq 命令是json 字符串处理读取内容; curl -s 隐藏进度条; local 关键字不能用于命令替换的赋值
# sudo snap install jq
echo ; echo "获取到 api : $catIPstr" ; echo
local sqlbmdip=$(sqlbmd "$ip" )
if [ "$sqlbmdip" == $ip ];then
local bmdIPFlag="yes"
local ipstatus="ACCEPT"
local Myexplain="[pass] 白名单,当前并发: $CountIP "
submitIP=$(iptablesInit $ip $bmdIPFlag)
echo "存在白名单 $ip 正在解封"
else
local bmdIPFlag="no"
local ipstatus="DROP"
submitIP=$(iptablesInit $ip $bmdIPFlag)
echo " `date +%Y-%m-%d-%H:%M:%y` $ip 连接数为: $CountIP 超过法制:$totalCount 连接数 没有白名单 被禁止访问"
fi
if [ "$sqlFirewallIp" == "$ip" ]; then
sql="update pk_firewall_ip set adminuser='$adminuser', port='80', frequency='$CountIP',ipstatus='$ipstatus',Myexplain='$Myexplain', ipArea='$catIPstr', date='$submitDate' WHERE ip='$ip'"
updateFlag=1
echo ""; echo "执行的命令:$sql"; echo "";
sqlQuery "$sql"
else
sql="INSERT INTO pk_firewall_ip(adminuser, ip, port, frequency, ipstatus, Myexplain, ipArea, date) VALUES('$adminuser', '$ip', 80, '$CountIP', '$ipstatus', '$Myexplain', '$catIPstr', '$submitDate')"
echo ""; echo "执行的命令:$sql"; echo "";
sqlQuery "$sql"
fi
}
#--------- 安防监控异常 ip ---------#
anfangip(){
local NR=$(cat $folder/ipfw.txt | wc -l); echo $NR
local ipfw=(`cat $folder/ipfw.txt | awk -F" " '{print $2}'`) ; echo $ipfw
for((i=0;i<$NR;i++))
do
local ip=${
ipfw[$i]}
local ipd=$( echo $ip | awk -F"." '{print $1 "." $2 "." $3}' )
local CountIP=` cat $folder/ipfw.txt | grep $ip | awk -F" " '{print $1}'` ; echo "${ipfw[$i]} 连接数 CountIP=$CountIP"
local CountIPD=`cat $folder/ipfw.txt | grep $ipd | awk -F" " '{print $1}'` ; echo "${ipfw[$i]} 连接数 CountIPD=$CountIPD"
if [ $CountIPD -gt $totalCount ]
then
local ipdWallFlag=1
local Myexplain="ip 连接数: $CountIP 所属网段 $ipd.1/24 连接数 $CountIPD 超过规定: $totalCount "
else
local ipdWallFlag=0
local Myexplain="该 ip=$ip 连接数 $CountIP 超过:$totalCount"
fi
if [ $CountIP -gt $totalCount ] || [ $ipdWallFlag == 1 ] # 当前ip 或者 ip 所属网段超过连接数,都进行拦截
then
firewalldjz "$ip" "$CountIP" "$Myexplain" ;
echo " `date +%Y-%m-%d-%H:%M:%y` $ip 连接数为: $CountIP 超过法制:$totalCount 连接数 被禁止访问" >> $folder/jinzhiip.txt
fi
done
}
tokenConnectIP(){
# url=192.168.122.80:62013
url=enchantment.ddoss.cn
username=VPNhome
token=0
ip=$( curl -s https://www.ddoss.cn/file/ip.php ) # curl -s 静态获取数值
urlapi="http://$url/enchantment/index.php?api=vpnClientIP"
curl -X POST $urlapi -H "Content-Type: application/json" -d '{ "action": "pass","ids": ["'$username'","'$ip'","'$token'"] }' -v
}
function main(){
while :
do
zhuabao ; anfangip ;
sudo iptables-restore < $iptablesFile # 防火墙逻辑
# tokenConnectIP # ip 白名单逻辑
sleep 5
done
}
main