返回》

在CentOS上使用iptables自动封IP 配合ipset自动封IP教程

之前搬主题有介绍利用系统的自带防火墙手动封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 list2、创建ip集ipset create XXXX hash:ip maxelem 100000 timeout 3600XXXX:ip集的名字hash:ip :为指定类型,还有其他好些类型,比如hash:net,hash:net,net等,具体可以man ipset100000:为最大保存ip的数量 timeout: 为封闭ip的默认时间,这个参数可以不写,这样就永不解封,除非手动解封3、增加ip地址到ip集ipset add xxxx 1.1.1.1增加网段ipset add xxxx 1.1.1.0/244、删除指定的ip或网段ipset del xxxx 1.1.1.1 ipset del xxxx 1.1.1.0/245、保存ip集到文件ipset save xxxx>ipset_list.txt6、还原ip集ipset restore /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 fi4、脚本自动运行在crontab中添加此脚本的自动运行*/1 * * * * bash /path/to/script.sh
THE END