之前搬主题有介绍利用系统的自带防火墙手动封IP的教程,有的人觉得很麻烦,这里搬主题再分享一下在CentOS上使用iptables自动封IP及配合ipset自动封IP教程。如果利用好的话,实际是功能很强大的。
Linux上用iptables自动封ip的bash脚本,这个还是有一定效果的。CentOS 内置了一个非常强劲的防火墙,统称为 iptables,但更正确的名称是 iptables/netfilter。iptables 是一个用户空间的模块。作为用户,你在命令行就是通过它将防火墙规则放进缺省的表里。netfilter 是一个核心模块,它内置于内核中,进行实际的过滤。iptables 有很多前端图像界面可以让用户新增或定义规则,但它们很多时不及使用命令行般有灵活性,而且限制用户了解实际发生的事情。
1. 安先装iptables
这里搬主题就不多描述了,如果是CentOS 6的话,自带iptables防火墙,如果是CentOS 7的话,那还需要卸掉原有防火墙,然后安装iptables防火墙。
2. 下面的脚本保存为drop_ips.sh
#!/bin/bash
###########################################
# 封锁ip 用iptables
# usage:
#
# create date 2010-11-11
# update date 2010-11-12
###########################################
# 定义端口
CHK_PORT="80 25"
# 定义输出文件
IPTABLE_OUTPUT=/tmp/ip_drop_tables
# 定义输出文件备份
IPTABLE_OUTPUT_BAK=/tmp/ip_drop_tables.bak
# 扫描ip的 间隔时间
SCAN_HTTP_IP_TIMEOUT=20
# 处理ip的间隔时间
HANDLE_IP_TIMEOUT=120
# 连接数量最大限制
MAX_CONNECT_IP_NUM=100
# 排除在外的ip
ACCEPT_IP="203.95.110.2"
# 已经封锁的ip
DROP_IP_RECORD_FILE=/tmp/drop_ip_record
#################################################################
#定义方法
#################################################################
# 输出ip到文件
output_ip_table()
{
# 拿到端口号
port_num=$1
# 查此端口上的连接ip 输出到指定的目录
#echo "start scan ......"
netstat -na --tcp| grep ESTABLISHED | awk '{ if ( index($4,":"'"$port_num"'"") ) print $5}' | awk -F ':' '{print $1}' | sort >> $IPTABLE_OUTPUT
#echo "scan end ......"
}
# 把需要观测端口列出
check_port()
{
for port_td in $CHK_PORT
do
# echo "port : "$port_td
# 扫描此端口
output_ip_table $port_td
done
}
# 封杀ip
drop_ip_from_table()
{
iptables -I INPUT -s "$1" -j DROP
}
# 排除ip
accept_ip()
{
for access_ip in $ACCEPT_IP
do
iptables -I INPUT -s "$access_ip" -j ACCEPT
done
}
# 提取需要的ip
get_iptable()
{
# 如果已经存在就删除
if [ -e $IPTABLE_OUTPUT_BAK ] ; then
rm -rf $IPTABLE_OUTPUT_BAK
fi
# copy 一份出去
cp $IPTABLE_OUTPUT $IPTABLE_OUTPUT_BAK
# 排序 数组
declare -a ip_array_org=($(cat ${IPTABLE_OUTPUT_BAK} | sort))
# 循环
# 比对用的ip 初始化
tmp_ip=0.0.0.0
let "tmp_ip_count=1"
for tmp_element in "${ip_array_org[@]}"
do
# 初始化 没有特殊设置为排除ip
is_not_set_accept="true"
# 初始化 是否已封杀了
is_not_drop="true"
# 如果相等
if [ "$tmp_ip" = "$tmp_element" ] ; then
let "tmp_ip_count+=1"
else
# 打印
echo "ip: $tmp_ip count: $tmp_ip_count"
# 如果大于某个数字 就封杀
if (( $tmp_ip_count >= $MAX_CONNECT_IP_NUM )) ; then
# 如果没有记录就封杀
if cat /tmp/drop_ip_record | grep "$tmp_ip" > /dev/null ; then
echo "this ip $tmp_ip has been mask !"
is_not_drop="false"
else
# 循环 需要排除ip
for tmp_access_ip in $ACCEPT_IP
do
# 如果排除ip里有 就去封锁此ip
if [ "$tmp_access_ip" = "$tmp_ip" ] ; then
echo "this ip $tmp_ip was mark to accept !"
is_not_set_accept="false"
fi
done
fi
if [ $is_not_set_accept = "true" ] && [ $is_not_drop = "true"] ; then
echo "add a new ip to drop : $tmp_ip"
drop_ip_from_table $tmp_ip
# 记录ip
echo "$tmp_ip" >> $DROP_IP_RECORD_FILE
fi
fi
# 归零
let "tmp_ip_count=1"
tmp_ip=$tmp_element
fi
done
# 全部处理完了 删除原件
rm -rf $IPTABLE_OUTPUT
# 排除ip
# accept_ip
}
# 扫描ip
scan_http_access_ip()
{
# 获取当前时间作为开始时间
start_time=`date +%s`
# 循环开始
while true
do
# 开始检查 扫描ip
check_port
# 线程停止
sleep $SCAN_HTTP_IP_TIMEOUT
# 获取当前时间
cur_time=`date +%s`
# 时间差
let "time_out=$cur_time-$start_time"
echo "time_out : "$time_out
# 超过2分钟
if (( $time_out >= $HANDLE_IP_TIMEOUT )) ; then
# 整理一次ip表
echo " times up"
get_iptable
# 重置开始时间
start_time=`date +%s`
fi
done
}
# 程序执行入口
main_app()
{
# 定时扫描ip
scan_http_access_ip
}
main_app
然后执行下面的脚本,让其自动在后台运行。
sh ~/scripts/drop_ips.sh &
以上是封少量的IP的教程,但是大家知道,iptables封掉少量ip处理是没什么问题的,但是当有大量ip攻击的时候性能就跟不上了,iptables是O(N)的性能。而ipset就像一个集合,把需要封闭的ip地址放入这个集合中,ipset 是O(1)的性能,用的hash方式所以特别快。之前搬主题也介绍了【WordPress设置CDN被CC攻击设置防火墙封IP防护图文教程】
一、软件及安装
1、iptables(一般Linux都已经安装好的)
2、ipset:
ubuntu:apt-get install ipset
二、ipset的使用
1、查看ip集的列表信息
ipset list
2、创建ip集
ipset create XXXX hash:ip maxelem 100000 timeout 3600
XXXX:ip集的名字
hash:ip :为指定类型,还有其他好些类型,比如hash:net,hash:net,net等,具体可以man ipset
100000:为最大保存ip的数量
timeout: 为封闭ip的默认时间,这个参数可以不写,这样就永不解封,除非手动解封
3、增加ip地址到ip集
ipset add xxxx 1.1.1.1
增加网段
ipset add xxxx 1.1.1.0/24
4、删除指定的ip或网段
ipset del xxxx 1.1.1.1
ipset del xxxx 1.1.1.0/24
5、保存ip集到文件
ipset save xxxx>ipset_list.txt
6、还原ip集
ipset restore <ipset_list.txt
三、自动封禁和解封
1、创建ip集
ipset create forbidip hash:ip timeout 172800
2、创建iptables条目
iptables -A INPUT -p tcp -m set --match-set forbidip src -m multiport --dports 443,80 -j DROP
或者
iptables -A INPUT -p tcp -m set --match-set forbidip src -m multiport -j DROP
3、根据条件判断需要封闭的ip
条件:在上一分钟的nginx的请求中,单一ip请求数超过1000及request_uri中包含passwd字符串的ip都直接封禁,1小时后自动解禁。脚本如下
#!/bin/bash
FILES="/data/nginx_log/xxxxx/access.log"
DATE=`date -d '1 minutes ago' +%Y:%H:%M`
grep ${DATE} ${FILES}|awk -F'|' '{print $3}'|sort -n|uniq -c |sort -nr|head -1>/tmp/ips
grep ${DATE} ${FILES}|grep -i passwd|awk -F'|' '{print $3}'|sort -n|uniq>/tmp/ippwd
NUM=`awk '{print $1}' /tmp/ips`
IP=`awk '{print $2}' /tmp/ips`
IP2=`cat /tmp/ippwd`
threshold=1000
if [[ $NUM -gt $threshold ]];then
/sbin/ipset -! add forbidip $IP timeout 3600
fi
if [ -s /tmp/ippwd ];then
for i in $IP2
do
/sbin/ipset -! add forbidip $i
done
fi
4、脚本自动运行
在crontab中添加此脚本的自动运行
*/1 * * * * bash /path/to/script.sh
1.本站内容仅供参考,不作为任何法律依据。用户在使用本站内容时,应自行判断其真实性、准确性和完整性,并承担相应风险。
2.本站部分内容来源于互联网,仅用于交流学习研究知识,若侵犯了您的合法权益,请及时邮件或站内私信与本站联系,我们将尽快予以处理。
3.本文采用知识共享 署名4.0国际许可协议 [BY-NC-SA] 进行授权
4.根据《计算机软件保护条例》第十七条规定“为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬。”您需知晓本站所有内容资源均来源于网络,仅供用户交流学习与研究使用,版权归属原版权方所有,版权争议与本站无关,用户本人下载后不能用作商业或非法用途,需在24个小时之内从您的电脑中彻底删除上述内容,否则后果均由用户承担责任;如果您访问和下载此文件,表示您同意只将此文件用于参考、学习而非其他用途,否则一切后果请您自行承担,如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。
5.本站是非经营性个人站点,所有软件信息均来自网络,所有资源仅供学习参考研究目的,并不贩卖软件,不存在任何商业目的及用途
暂无评论内容