基于ipset对大量IP进行封禁(Iptables)

iptables可以有效的对特定的IP进行封禁,但若需要处理大量ip时,需要添加同等数量的规则,这会导致性能严重下降,并且管理也不够方便和优雅

ipset则很好的解决了这个问题。ipset是iptables的扩展,它允许你创建和匹配整个地址集合的规则。在iptables规则中仅一条规则,就可以匹配到整个集合中的ip,并且,可以对这个集合动态修改,而不需要再修改iptables规则,甚至,你可以为特定ip设置过期时间,这样,对该ip的封禁在指定的时间后,会自动过期,从而自动解封
安装 ipset

yum -y install ipset
ipset 常用命令

集合类型:分为三大类,即hash、bitmap、list
其中bitmap最大容量为65536;hash默认容量是65536,可通过maxelem指定更大的容量;而list类型的元素为hash或bitmap集合,其容量则更大
hash方式有:
hash:net,iface hash:net,port hash:net hash:ip,port,net hash:ip,port,ip hash:ip,port hash:ip
bitmap方式有:
bitmap:port bitmap:ip,mac bitmap:ip

# 创建集合
ipset create xxx hash:net
ipset create xxx hash:net maxelem 1000000 #指定最大容量
ipset create xxx hash:net hashsize 4096 maxelem 1000000 #指定hashsize和最大容量 hashsize默认为1024,必须为2的倍数
ipset create xxx hash:ip timeout 300 #创建带默认超时时间的集合,注,单个添加的条目时间可超过该值,过期后,条目会自动删除
ipset create xxx hash:ip family inet hashsize 1024 maxelem 65536 timeout 300 #完整的命令

# 查看集合
ipset list #会输出详细信息,包括条目及每个条目的剩余时间
ipset list xxx
ipset list -n #仅输出集合名称
ipset list -t #不输出元素

# 添加条目
ipset add xxx 192.168.1.1
ipset add xxx 192.168.1.1 timeout 60
ipset -exist add xxx 192.168.1.1 timeout 60 #添加条目,若存在,则更新timeout时间 说明,不使用 -exist 则条目已存在时会报错

# 针对不同集合类型的示例
ipset add foo 192.168.1/24
ipset add foo 192.168.1.1,12:34:56:78:9A:BC
ipset add foo 80
ipset add foo 192.168.1.0/24,80-82
ipset add foo 192.168.1.1,udp:53
ipset add foo 10.1.0.0/16,80
ipset add foo 192.168.1.1,80,10.0.0.1
ipset add foo 192.168.2,25,10.1.0.0/16
ipset add foo 192.168.0/24,eth0

# 删除条目
ipset del xxx 192.168.1.1 #注,删除一个不存在的条目会报错
ipset -exist del xxx 192.168.1.1

# 查询条目
ipset test xxx 192.168.1.1

# 清空集合
ipset flush #清空所有集合
ipset flush xxx #清空指定的集合

# 将规则保存到文件
ipset save xxx -f xxx.txt #导出文件甚至包含集合创建命令
ipset save xxx #输出到屏幕# 从文件还原
ipset restore -f xxx.txt #注意,集合名称在文件中已存在,若存在该集合,则导入失败

# 删除集合
ipset destroy #删除所有集合
ipset destroy xxx #删除指定的集合

# 集合重命名
ipset rename xxx yyy #改名为yyy
在iptables中使用集合
# 添加
iptables -I INPUT -m set –match-set xxx src -p tcp -j DROP
iptables -I INPUT -m set –match-set xxx src -p udp -j DROP
# 删除
iptables -D INPUT -m set –match-set xxx src -p tcp -j DROP
iptables -D INPUT -m set –match-set xxx src -p udp -j DROP
# 查看
iptables -L | grep match-set
# 保存
service iptables save
扩展

屏蔽指定国家地区的IP访问
wget https://raw.githubusercontent.com/iiiiiii1/Block-IPs-from-countries/master/block-ips.sh
sh block-ips.sh
# 不同国家对应的网段数据 http://www.ipdeny.com/ipblocks/data/countries/

使用IPIP数据库进行流量屏蔽
https://github.com/17mon/china_ip_list/blob/master/china_ip_list.txt

#!/bin/bash
#判断是否具有root权限
root_need() {
    if [[ $EUID -ne 0 ]]; then
        echo "Error:This script must be run as root!" 1>&2
        exit 1
    fi
}
 
#检查系统分支及版本(主要是:分支->>版本>>决定命令格式)
check_release() {
    if uname -a | grep el7  ; then
        release="centos7"
    elif uname -a | grep el6 ; then
        release="centos6"
        yum install ipset -y
    elif cat /etc/issue |grep -i ubuntu ; then
        release="ubuntu"
        apt install ipset -y
    fi
}
 
#安装必要的软件(wget),并下载中国IP网段文件(最后将局域网地址也放进去)
get_china_ip() {
    #安装必要的软件(wget)
    rpm --help >/dev/null 2>&1 && rpm -qa |grep wget >/dev/null 2>&1 ||yum install -y wget ipset >/dev/null 2>&1 
    dpkg --help >/dev/null 2>&1 && dpkg -l |grep wget >/dev/null 2>&1 ||apt-get install wget ipset -y >/dev/null 2>&1
 
    #该文件由IPIP维护更新,大约一月一次更新
    [ -f china_ip_list.txt ] && mv china_ip_list.txt china_ip_list.txt.old
    #wget https://github.com/17mon/china_ip_list/blob/master/china_ip_list.txt
    #cat china_ip_list.txt |grep 'js-file-line">' |awk -F'js-file-line">' '{print $2}' |awk -F'<' '{print $1}' >> china_ip.txt
    wget https://raw.githubusercontent.com/17mon/china_ip_list/master/china_ip_list.txt
    rm -rf china_ip_list.txt
    #wget https://qiniu.wsfnk.com/china_ip.txt
 
    #放行局域网地址
    echo "192.168.0.0/18" >> china_ip.txt
    echo "10.0.0.0/8" >> china_ip.txt
    echo "172.16.0.0/12" >> china_ip.txt
}
 
#只允许国内IP访问
ipset_only_china() {
    echo "ipset create whitelist-china hash:net hashsize 10000 maxelem 1000000" > /etc/ip-black.sh
    for i in $( cat china_ip.txt )
    do
            echo "ipset add whitelist-china $i" >> /etc/ip-black.sh
    done
    echo "iptables -I INPUT -m set --match-set whitelist-china src -j ACCEPT" >> /etc/ip-black.sh
    #拒绝非国内和内网地址发起的tcp连接请求(tcp syn 包)(注意,只是屏蔽了入向的tcp syn包,该主机主动访问国外资源不用影响)
    echo "iptables  -A INPUT -p tcp --syn -m connlimit --connlimit-above 0 -j DROP" >> /etc/ip-black.sh
    #拒绝非国内和内网发起的ping探测(不影响本机ping外部主机)
    echo "iptables  -A INPUT -p icmp -m icmp --icmp-type 8 -j DROP" >> /etc/ip-black.sh
    #echo "iptables -A INPUT -j DROP" >> /etc/ip-black.sh
    rm -rf china_ip.txt
}
 
run_setup() {
    chmod +x /etc/rc.local
    sh /etc/ip-black.sh
    rm -rf /etc/ip-black.sh
    #下面这句主要是兼容centos6不能使用"-f"参数
    ipset save whitelist-china -f /etc/ipset.conf || ipset save whitelist-china > /etc/ipset.conf
    [ $release = centos7 ] && echo "ipset restore -f /etc/ipset.conf" >> /etc/rc.local
    [ $release = centos6 ] && echo "ipset restore < /etc/ipset.conf" >> /etc/rc.local
    echo "iptables -I INPUT -m set --match-set whitelist-china src -j ACCEPT" >> /etc/rc.local
    echo "iptables  -A INPUT -p tcp --syn -m connlimit --connlimit-above 0 -j DROP" >> /etc/rc.local
    echo "iptables  -A INPUT -p icmp -m icmp --icmp-type 8 -j DROP" >> /etc/rc.local
    #echo "iptables -A INPUT -j DROP" >> /etc/rc.local
}
 
main() {
    check_release
    get_china_ip
    ipset_only_china
 
case "$release" in
centos6)
    run_setup
    ;;
centos7)
    chmod +x /etc/rc.d/rc.local
    run_setup
    ;;
ubuntu)
    sed -i '/exit 0/d' /etc/rc.local
    run_setup
    echo "exit 0" >> /etc/rc.local
    ;;
esac
}
main
posted @ 2021-04-24 01:14  ~*一生所爱*~  阅读(636)  评论(0编辑  收藏  举报
在国际交往中,实力 永远是维护正义的基础;国防 才是外交真正的后盾;尊严 只在剑峰之上;真理 只在大炮射程之内。