转载Linux下使用 ipset 封大量IP及ipset参数说明

Linux使用iptables封IP,是常用的应对网络攻击的方法,但要封禁成千上万个IP,如果添加成千上万条规则,对机器性能影响较大,使用ipset能解决这个问题。

iptables 包含几个表,每个表由链组成。默认的是 filter 表,最常用的也是 filter 表,另一个比较常用的是nat表,封IP就是在 filter 表的 INPUT 链添加规则。
在进行规则匹配时,是从规则列表中从头到尾一条一条进行匹配。
这像是在链表中搜索指定节点费力。ipset 提供了把这个 O(n) 的操作变成 O(1) 的方法:就是把要处理的 IP 放进一个集合,对这个集合设置一条 iptables 规则。像 iptable 一样,IP sets 是 Linux 内核中的东西,ipset 这个命令是对它进行操作的一个工具。

简单的流程
可以用这几条命令概括使用 ipset 和 iptables 进行 IP 封禁的流程

ipset create vader hash:ip
iptables -I INPUT -m set --match-set vader src -j DROP
ipset add vader 4.5.6.7
ipset add vader 1.2.3.4
ipset add vader ...
ipset list vader # 查看 vader 集合的内容

下面分别对各条命令进行描述。
创建一个集合
ipset create vader hash:ip
这条命令创建了名为 vader 的集合,以 hash 方式存储,存储内容是 IP 地址。

添加 iptables 规则
iptables -I INPUT -m set --match-set vader src -j DROP
如果源地址(src)属于 vader 这个集合,就进行 DROP 操作。这条命令中,vader 是作为黑名单的,如果要把某个集合作为白名单,添加一个 ‘!’ 符号就可以。

iptables -I INPUT -m set ! --match-set yoda src -j DROP
到现在虽然创建了集合,添加了过滤规则,但是现在集合还是空的,需要往集合里加内容。

找出“坏” IP
找出要封禁的 IP,这是封禁过程中重要的步骤,不过不是这里的重点。简要说明一下两种方法思路。

netstat -ntu | tail -n +3 | awk '{print $5}' | sort | uniq -c | sort -nr
直接通过 netstat 的信息,把与本地相关的各种状态的 IP 都计数,排序列出来。

或者从 nginx 或者其他 web server 的日志里找请求数太多的 IP

awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr
后半部分,排序,去重,再按次数进行逆向排序的操作,跟上面命令是一样的。

找出“坏” IP,往之前创建的集合里添加就可以了。

ipset add vader 4.5.6.7
有多少“坏” IP,就添加多少 IP,因为针对这些封禁的 IP 只需要一条 iptables 规则,而这些 IP 是以 hash 方式存储,所以封禁大量的 IP 也不会影响性能,这也是 ipset 存在的最大目的。

You shall not pass!

ipset 更多的用法
存储类型
前面例子中的 vader 这个集合是以 hash 方式存储 IP 地址,也就是以 IP 地址为 hash 的键。除了 IP 地址,还可以是网络段,端口号(支持指定 TCP/UDP 协议),mac 地址,网络接口名称,或者上述各种类型的组合。

比如指定 hash:ip,port就是 IP 地址和端口号共同作为 hash 的键。查看 ipset 的帮助文档可以看到它支持的所有类型。

下面以两个例子说明。

HASH:NET
ipset create r2d2 hash:net
ipset add r2d2 1.2.3.0/24
ipset add r2d2 1.2.3.0/30 nomatch
ipset add r2d2 6.7.8.9
ipset test r2d2 1.2.3.2
hash:net 指定了可以往 r2d2 这个集合里添加 IP 段或 IP 地址。

第三条命令里的 nomatch 的作用简单来说是把 1.2.3.0/30 从 1.2.3.0/24 这一范围相对更大的段里“剥离”了出来,也就是说执行完 ipset add r2d2 1.2.3.0/24 只后1.2.3.0/24 这一段 IP 是属于 r2d2 集合的,执行了 ipset add r2d2 1.2.3.0/30 nomatch 之后,1.2.3.0/24 里 1.2.3.0/30 这部分,就不属于 r2d2 集合了。执行 ipset test r2d2 1.2.3.2 就会得到结果 1.2.3.2 is NOT in set r2d2.

HASH:IP,PORT
ipset create c-3po hash:ip,port
ipset add c-3po 3.4.5.6,80
ipset add c-3po 5.6.7.8,udp:53
ipset add c-3po 1.2.3.4,80-86
第二条命令添加的是 IP 地址为 3.4.5.6,端口号是 80 的项。没有注明协议,默认就是 TCP,下面一条命令则是指明了是 UDP 的 53 端口。最后一条命令指明了一个 IP 地址和一个端口号范围,这也是合法的命令。

自动过期,解封
ipset 支持 timeout 参数,这就意味着,如果一个集合是作为黑名单使用,通过 timeout 参数,就可以到期自动从黑名单里删除内容。

ipset create obiwan hash:ip timeout 300
ipset add obiwan 1.2.3.4
ipset add obiwan 6.6.6.6 timeout 60
上面第一条命令创建了名为 obiwan 的集合,后面多加了 timeout 参数,值为 300,往集合里添加条目的默认 timeout 时间就是 300。第三条命令在向集合添加 IP 时指定了一个不同于默认值的 timeout 值 60,那么这一条就会在 60 秒后自动删除。

隔几秒执行一次 ipset list obiwan 可以看到这个集合里条目的 timeout 一直在随着时间变化,标志着它们在多少秒之后会被删除。

如果要重新为某个条目指定 timeout 参数,要使用 -exit 这一选项。

ipset -exist add obiwan 1.2.3.4 timeout 100
这样 1.2.3.4 这一条数据的 timeout 值就变成了 100,如果这里设置 300,那么它的 timeout,也就是存活时间又重新变成 300。

如果在创建集合是没有指定 timeout,那么之后添加条目也就不支持 timeout 参数,执行 add 会收到报错。想要默认条目不会过期(自动删除),又需要添加某些条目时加上 timeout 参数,可以在创建集合时指定 timeout 为 0。

ipset create luke hash:ip
ipset add luke 5.5.5.5 timeout 100
得到报错信息 kernel error received: Unknown error -1

hashsize, maxelem 这两个参数分别指定了创建集合时初始的 hash 大小,和最大存储的条目数量。

ipset create yoda hash:ip,port hashsize 4096 maxelem 1000000
ipset add yoda 3.4.5.6,3306
这样创建了名为 yoda 的集合,初始 hash 大小是 4096,如果满了,这个 hash 会自动扩容为之前的两倍。最大能存储的数量是 100000 个。

如果没有指定,hashsize 的默认值是 1024,maxelem 的默认值是 65536。

另外几条常用命令
ipset del yoda x.x.x.x # 从 yoda 集合中删除内容
ipset list yoda # 查看 yoda 集合内容
ipset list # 查看所有集合的内容
ipset flush yoda # 清空 yoda 集合
ipset flush # 清空所有集合
ipset destroy yoda # 销毁 yoda 集合
ipset destroy # 销毁所有集合
ipset save yoda # 输出 yoda 集合内容到标准输出
ipset save # 输出所有集合内容到标准输出
ipset restore # 根据输入内容恢复集合内容
还有……

如果创建集合是指定的存储内容包含 ip, 例如 hash:ip 或 hash:ip,port ,在添加条目时,可以填 IP 段,但是仍然是以单独一个个 IP 的方式来存。
上面所有的例子都是用 hash 的方式进行存储,实际上 ipset 还可以以 bitmap 或者 link 方式存储,用这两种方式创建的集合大小,是固定的。
ipset参数如下:
命令
这些选项明确地指定了执行的活动。只有一个命令可以在命令行中规定除非其他的命令在下面。对于所有的长版本命令和选项名称,必须使用足够大的空间以确保ipset可以把他们和其他的选项区分开。
-N, --创建 集合名称 类型 类型具体选项
创建一个用集合名称命名并且指定类型的集合。类型具体选项必须是系统规定的。
-X, --删除 [集合名称]
删除指定的集合,如果没有指定或者指定all就删除全部集合。在删除集合之前,所有基于集合的绑定和默认绑定都会被移除。
如果集合已经被使用,则什么都不做。
-F, --清空 [集合名称]
删除指定集合中的所有规则, 如果没有指定或者指定了all就清空所有的集合。绑定不会受到清空操作的影响。
-E, --重命名 旧集合名 新集合名
重命名集合,新集合名的标识必须是目前不存在。
-W, --交换 源集合名 目的集合名
交换两个集合的内容,或者说交换两个集合的名称。这两个集合必须是存在的而且是具有相同的类型才能交换。
-L, --列出 [集合名名称]
列出指定集合的规则和绑定,如果没有指定或者指定为all就列出所有的集合。-n选项,数字选项可以用来限定名称查找和生产数字输出,当-s ,分类选项已经使用,规则将分类排列(如果给出的集合类型支持这个选项)。
-S, --保存 [集合名称]
保存指定名称的集合,如果没有指定或者指定为all,则保持所有集合:指定恢复可以读取的标准输出格式。
-R, --复原
复原已保存的会话.已被保存的会话可以是标准输入提供的。
当产生一个会话文件的时候请注意支持的命令(创建集合,添加元素,绑定)必须遵循严格的规范:首先创建集合添加所有属于它的集合等等,最后你可以列出所有的绑定命令.此外,这是一个复原选项,所以复原的集合必须是不存在的。
-A, --添加 集合名称 IP
往集合中添加一个ip。
-D, --删除 集合名称IP
从集合中删除一个ip
-T, --测试 集合名称 IP
测试一个ip是不是在集合中,要是ip在集合中返回0,如果ip不在集合中则返回非0.
-T, --测试 集合名称 IP 绑定的目的集合
测试ip是否附属指定集合的绑定点。如果成功返回0,否则返回非0.关键字default可以用来测试集合的默认绑定。
-B, --绑定 集合名称 IP 绑定的目的集合
绑定集合里的ip和目的集合
-U, --解除绑定 集合名称 IP
删除集合中指定ip的绑定。
-H, --帮助 [设置类型]
找出指定设置类型的帮助信息。
在-B –U和-T命令,你可以使用默认的:default,去绑定,解除绑定或者测试默认绑定去代替ip.在-U命令中你可以使用默认的:all去删除绑定集合的所有元素。
其他选项
接下来的选项可以被指定
-b, --binding setname
这个选择为-B绑定选项指定值。这是一个强制性的命令. 你在-T中可以用来测试绑定。
-s, --分类
分类标准输出.当监听集合,规则列表分类的时候。
-n, --数字
数字输出。当监听集合,绑定,ip地址和端口好需要输出的时候使用数字格式. 默认的系统试着去显示这些信息用主机名,网络名和服务,这会引起dns查找。
-q, --安静
禁止在标准输出和标准错误上有认可输出但是ipset还是会返回可能的错误。

Linux下使用 ipset 封大量IP及ipset参数说明的更多相关文章

  1. Linux 下获取LAN中指定IP的网卡的MAC(物理地址)

    // all.h// 2005/06/20,a.m. wenxy #ifndef _ALL_H#define _ALL_H #include <memory.h>#include < ...

  2. 虚拟机Linux下一直获取不到ip怎么办

    虚拟机Linux下一直获取不到ip怎么办 Ifconfig -a 只显示了本地的ip127.0.0.1 和另一个eth1 但是找不到ip地址. 需要做的是: 申请ipdhclient eth1 另外释 ...

  3. 如何在linux下检测(自身)IP冲突

    最近遇到一个需求,或者说是一个用户现场问题. 我们设备先安装,设置dhcp模式获取ip进行联网,后来又安装了其他设备,但该设备是手动设置的静态ip地址,正好与我们设备冲突,造成网络故障. 那我们就需要 ...

  4. Linux下新的网络管理工具ip替代ifconfig零压力

    如果你使用 Linux 足够久,那么你自然知道一些工具的来与去.2009年 Debian 开发者邮件列表宣布放弃使用缺乏维护的 net-tools 工具包正是如此.到今天 net-tools 仍然被部 ...

  5. Linux下查看access访问日志IP统计命令

    查看 access.Log 文件ip统计 cat access.log |awk '{print $1}'|uniq -c |sort -k1,1nr 去掉r则从高到低 cat access.log ...

  6. Linux下network提示Determining if ip address

    转自:https://blog.csdn.net/ranran0224/article/details/73323925 Centos系统重启网络服务network 会提示Determining if ...

  7. linux下测试某网址或IP端口能否访问

    参考这篇 Linux系统下怎么测试端口的连通性 测试端口连通 nc -v -w 1 183.xx.oo.ee -z 82 1linux主机centos操作系统,项目里面需要访问一个URL路径的接口ht ...

  8. linux下使用shell查看apache IP访问量

    1.查看TCP连接状态 netstat -nat |awk '{print $6}'|sort|uniq -c|sort -rn netstat -n | awk '/^tcp/ {++S[$NF]} ...

  9. Linux下搭建Oracle11g RAC(1)----IP分配与配置IP

    首先需要说明的,我的RAC搭建不是在虚拟机上完成的,而是在实际部署中,二者之间有些许差异,本人水平有限,请见谅. 其中,每台机器至少需要配置3个IP地址,在安装操作系统的过程中,我们需要配置公网IP和 ...

随机推荐

  1. P1969积木大赛

    这是2018与2013提高组的真题,可怕,,原题出了两年,是个纯模拟. 读完题后就想写一个朴素的模拟,先遍历层数,再把达到层数的宽度#存起来,再判断是否连续,如果不连续ans++,然后每一次循环都要初 ...

  2. qt 部分控件 setStyleSheet 使用总结

    刚用Qt不久,但是已经感受到Qt ui设计的便捷. 总结一下最近使用的控件,把它们setStyleSheet的使用方法记录下来. 主要使用到的工具有:QToolBar,QToolBox,QPushBu ...

  3. ubuntu或linux下找不到apache服务器配置文件httpd.conf

    原因是ubuntu中是apache2,没有httpd.conf文件,所有找不到. 我的是ubuntu14.04系统,apache2配置文件在/etc/apache2/apache2.conf中, 如果 ...

  4. 客户端通过url向后端传递参数

    在前端我们不仅可以通过get请求携带参数的方式向服务端传数据: https://127.0.0.1/index/?id=1&name=alex Django也允许通过,path路径的方式向se ...

  5. vue生命周期简单总结

    生命周期(钩子函数):一个组件从创建到销毁的过程就是生命周期     beforeCreate: 创建前     1.当前vue实例化的时候会做一个初始化的操作,在这个生命周期函数中我们可以做初始化的 ...

  6. 吴恩达深度学习:2.9逻辑回归梯度下降法(Logistic Regression Gradient descent)

    1.回顾logistic回归,下式中a是逻辑回归的输出,y是样本的真值标签值 . (1)现在写出该样本的偏导数流程图.假设这个样本只有两个特征x1和x2, 为了计算z,我们需要输入参数w1.w2和b还 ...

  7. 同步锁 synchronized

    package ba; public class Tongbu implements Runnable{ int i=100; public void run(){ while(true){ sell ...

  8. Vue 变量,成员,属性监听

    Vue变量 <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF ...

  9. 以当前时间作为GUID的方法

    在C#中,系统提供了GUID类,用户可以通过该类来获得128位的唯一标识,但是该标识不具有可读性,很难把该GUID显示在界面上,以当前时间精确到毫秒来作为GUID是一个比较不错的做法,但是DateTi ...

  10. 面试编程题拾遗(06) --- 打印n对括号的全部有效组合

    如题所述,当n=3时,可能的组合有:(()()), ((())), ()(()), (())(), ()()() 代码如下(有注释): import java.util.ArrayList; impo ...