iptables
Part 1 基础内容
iptables 可以检测、修改、转发、重定向和丢弃 IPv4 数据包。
过滤 IPv4 数据包的代码已经内置于内核中,并且按照不同的目的被组织成 表 的集合。表 由一组预先定义的 链 组成,链 包含遍历顺序规则。iptables 是用户工具,允许用户使用 链 和 规则。
表、链、规则理解:
链充当报文关卡,对报文进行检查,符合条件后才能放行;规则就是预定的条件;而表则是将相似的规则放在一起。
下图简要描述了网络数据包通过 iptables 的过程:
XXXXXXXXXXXXXXXXXX
XXX Network XXX
XXXXXXXXXXXXXXXXXX
+
|
v
+-------------+ +------------------+
|table: filter| <---+ | table: nat |
|chain: INPUT | | | chain: PREROUTING|
+-----+-------+ | +--------+---------+
| | |
v | v
[local process] | **************** +--------------+
| +---------+ Routing decision +------> |table: filter |
v **************** |chain: FORWARD|
**************** +------+-------+
Routing decision |
**************** |
| |
v **************** |
+-------------+ +------> Routing decision <---------------+
|table: nat | | ****************
|chain: OUTPUT| | +
+-----+-------+ | |
| | v
v | +-------------------+
+--------------+ | | table: nat |
|table: filter | +----+ | chain: POSTROUTING|
|chain: OUTPUT | +--------+----------+
+--------------+ |
v
XXXXXXXXXXXXXXXXXX
XXX Network XXX
XXXXXXXXXXXXXXXXXX
从任何网络端口 进来的每一个 IP 数据包都要从上到下的穿过这张图。iptabales 对从任何端口进入的数据包都会采取相同的处理方式。
表(Tables)
iptables 包含 5 张表(tables):
raw
用于配置数据包,raw
中的数据包不会被系统跟踪。filter
是用于存放所有与防火墙相关操作的默认表。nat
用于网络地址转换(例如:端口转发)。mangle
用于对特定数据包的修改。security
用于强制访问控制网络规则(例如: SELinux -- 详细信息参考 该文章)。
大部分情况仅需要使用 filter 和 nat。其他表用于更复杂的情况——包括多路由和路由判定——已经超出了本文介绍的范围。
链 (Chains)
表由链组成,链是一些按顺序排列的规则的列表。
规则链共有五种:prerouting
,input
,forward
,output
,postrouting
表中存放着许多规则,我们把这些规则分个类,这些类就是链。而每张表的功能又不一样,所以每张表中的链也就不一样:
- nat表:
prerouting,input,output,postrouting
- filter表:
input,forward,output
- mangle:
prerouting,iniput,forward,output,postrouting
- raw表:
prerouting,output
- security表:
input,forward,output
默认的 filter
表包含 INPUT
, OUTPUT
和 FORWARD
3条内建的链,这3条链作用于数据包过滤过程中的不同时间点,如该流程图所示。
默认情况下,任何链中都没有规则。可以向链中添加自己想用的规则。链的默认规则通常设置为 ACCEPT
,如果想确保任何包都不能通过规则集,那么可以重置为 DROP
。默认的规则总是在一条链的最后生效,所以在默认规则生效前数据包需要通过所有存在的规则。
用户可以加入自己定义的链,从而使规则集更有效并且易于修改。
规则 (Rules)
数据包的过滤基于 规则。规则由一个目标(数据包包匹配所有条件后的动作)和很多匹配(导致该规则可以应用的数据包所满足的条件)指定。
iptables的规则书写是有大小写区别的
iptables -t [表名] -增加/删除/修改 [链名] (数字) -p 协议 -s 目标地址 -j 丢弃/接收
简单示例:
增加规则:iptables -t filter -I INPUT -p tcp -j DROP
删除规则:iptables -t filter -D INPUT 1
Part 2 规则
新增规则
iptables [-t table] -A chain rule-specification
iptables [-t table] -I chain rulenum rule-specification
iptables [-t table] -N chain
[-t table]
指定表,不写默认为filter表-A
表示append/add,新增或在已有规则后面添加-I
表示insert,插入到指定位置,可以将规则写入到表中的任意位置,这个位置就是后面的rulenum决定的-N
表示添加用户自定义的链rule-specification表示指定规则,比如说指定ip、协议、行为
rule-specification = [matches...] [target]
- match =
-m matchname [per-match-options]
举个例子:match为-p tcp 或者 -s 192.168.0.12 - target =
-j targetname [per-target-options]
举个例子:target为-j DROP 或者 -j ACCEPT- targetname表示对规则的处理,有accept接收/drop丢弃/return暂存
rule-specification是用来指定符合条件的规则,包含了对这个规则的处理
有些参数是支持取反的,写规则时可通过tab补全帮助
- -4, –ipv4 指定使用ipv4
- -6, –ipv6 指定使用ipv6
- [!] -p, –protocol protocol 指定使用的协议,这个参数就支持取反,如果我想写除tcp之外的协议:
! -p tcp
例如我写这个的时候不知道有那些协议啊?tab一下就出来了 [!] -s, –source address[/mask][,…] 指定源主机地址,包含a network name, a hostname, a network IP address - [!] -d, –destination address[/mask][,…]与上面的参数一样,指定目标主机地址
- -m, –match match 匹配模块,可以调用模块的扩展功能. 举个例子:使用 -p tcp参数的时候,就是指定匹配tcp协议.而使用-m tcp参数的时候,是调用tcp模块.不过我真不知道这有啥用,恕我孤陋寡闻了
- -j, –jump target 动作,包含
ACCEPT
、ECN
、MARK
、MIRROR
、REDIRECT
、RETURN
、TCPMSS
、ULOG、
DNAT
、DSCP
、LOG
、MASQUERADE
、QUEUE
、REJECT
、SNAT
、TOS
- -g, –goto chain指定跳转用户自定义的链
- [!] -i, –in-interface name 指定数据进来的网络接口
- [!] -o, –out-interface name 指定数据出去的网络接口
- [!] -f, –fragment 只能是ipv4起作用,类似于模糊匹配,通过数据包片段来匹配
- -c, –set-counters packets bytes 允许root初始化链的数据
- match =
删除规则
iptables [-t table] -D chain rulenum
iptables [-t table] -F
iptables [-t table] -X
-D
删除rulenum所指的规则-F
删除指定的整个表的规则-X
删除用户自定义的表
查看规则
iptables [-t table] -C chain rule-specification
iptables [-t table] -L [chain [rulenum]]
iptables [-t table] -S [chain [rulenum]]
-C
:表示check,检查是否存在规则,存在不给提示,不存在给出提示-L
:显示详细信息-S
:显示简略信息
常用的查看规则(显示排序数字): sudo iptables -nvL --line-numbers
-v
:查看更多、更详细的信息-n
:不对IP地址进行名称反解,直接显示IP地址--line-numbers
:显示规则的编号-x
:显示计数器的精确值,"计数器"只会在使用-v
选项时,才会显示出来- packets表示当前链(上例为INPUT链)默认策略匹配到的包的数量,0 packets表示默认策略匹配到0个包。
- bytes表示当前链默认策略匹配到的所有包的大小总和。
修改规则
iptables [-t table] -R chain rulenum rule-specification
iptables [-t table] -E old-chain-name new-chain-name
iptables [-t table] -P chain target
-R
:replace替代rulenum指定的规则-E
:rename修改用户自定义链的名字-P
:policy修改iptables默认链的规则,target只有drop和accept这两种情况
举个例子:我们的个人电脑一般是不会用来做路由的吧,路由转发这种事是服务器和路由器做的,所以forward这条链对我们的作用几乎为零,那我们就可以将链的规则修改为丢弃
sudo iptables -P FORWARD -j DROP
清除所有链/指定链/指定规则的数据包统计
iptables [-t table] -Z [chain [rulenum]]
Part2.5 规则编写
指定表,指定链后,便书写规则。
当一条规则中存在多个匹配条件时,报文必须同时满足这些条件,才算做被规则匹配
基本匹配条件
- 源IP地址:
-s
- 指定单个IP:
-s 192.168.1.2
- 指定多个IP,逗号隔开,逗号两边无空格:
-s 192.168.1.2,192.168.1.3
- 指定某个网段:
-s 192.168.1.0/24
- 匹配条件取反:
! -s 192.168.1.2
,取反后的规则只指定除了该IP地址对应的操作,并未指定该IP地址的操作(即使用默认操作)
- 指定单个IP:
- 目标IP地址:
-d
- 使用与源IP地址类似
- 协议类型:
-p
- 支持类型:tcp, udp, udplite, icmp, icmpv6,esp, ah, sctp, mh
- all关键字:指定所有类型
- 不使用-p指定协议类型时,默认表示所有类型的协议都会被匹配到,与使用
-p all
的效果相同
- 网卡接口
- 数据流入:
-i
,匹配报文是通过哪块网卡流入本机- 只能用于PREROUTING链、INPUT链、FORWARD链
- 数据流出:
-o
,匹配报文是通过哪块网卡流出本机- 只能用于FORWARD链、OUTPUT链、POSTROUTING链
- FORWARD链属于"中立国",它能同时使用-i选项与-o选项
- 数据流入:
拓展匹配条件
基本匹配条件可以直接使用,而如果想要使用扩展匹配条件,则需要依赖一些扩展模块,或者说,在使用扩展匹配条件之前,需要指定相应的扩展模块才行。
tcp拓展模块:
-m tcp
- 端口匹配
- 使用--dport可以匹配报文的目标端口,--dport意为destination-port,即表示目标端口
- 使用--sport可以匹配报文的源端口,--sport表示source-port,即表示源端口
- 使用--dport选项时,必须事先指定了使用哪种协议,即必须先使用-p选项
- "隐式"指定扩展模块:当使用-p选项指定了报文的协议时,如果在没有使用-m指定对应的扩展模块名称的情况下,使用了扩展匹配条件,iptables默认会调用与-p选项对应的协议名称相同的模块
- 扩展匹配条件取反:同样是使用
!
进行取反 - 指定端口范围:
--dport 22:26
- 指定端口起始:
--dport :22
--dport 80:
--tcp-flags
:匹配tcp报文的头部的标识位,然后根据标识位的实际情况实现访问控制的功能- 使用示例:
-m tcp --tcp-flags SYN,ACK,FIN,RST,URG,PSH SYN
- 上例中的"SYN,ACK,FIN,RST,URG,PSH SYN"表示,需要匹配报文tcp头中的"SYN、ACK、FIN、RST、URG、PSH"这些标志位,其中SYN标志位必须为1,其他的5个标志位必须为0
- 可以用ALL表示"SYN,ACK,FIN,RST,URG,PSH"
- tcp扩展模块还为我们专门提供了一个选项,可以匹配上文中提到的"第一次握手",那就是--syn选项。使用"--syn"选项相当于使用"--tcp-flags SYN,RST,ACK,FIN SYN",也就是说,可以使用"--syn"选项去匹配tcp新建连接的请求报文。
- 使用示例:
- 端口匹配
multiport拓展模块:同时指定多个离散的端口,逗号分隔
- 使用multiport模块的--sports扩展条件同时指定多个离散的源端口
- 使用multiport模块的--dports扩展条件同时指定多个离散的目标端口
- multiport模块的--sports与--dpors时,也可以指定连续的端口范围,并且能够在指定连续的端口范围的同时,指定离散的端口号:
--dports 22,80:88
- multiport扩展只能用于tcp协议与udp协议,即配合-p tcp或者-p udp使用
iprange扩展模块:可以指定"一段连续的IP地址范围",用于匹配报文的源地址或者目标地址
- --src-range:指定连续的源地址范围
- --dst-range:指定连续的目标地址范围
- IP段的始末IP使用"横杠"连接
-m iprange --src-range 192.168.1.12-192.168.1.25
string扩展模块:可以指定要匹配的字符串,如果报文中包含对应的字符串,则符合匹配条件
- --algo:用于指定匹配算法,可选的算法有bm与kmp,此选项为必须选项
- --string:用于指定需要匹配的字符串
time扩展模块:可以根据时间段区匹配报文,如果报文到达的时间在指定的时间范围以内,则符合匹配条件
- --timestart:用于指定时间范围的开始时间,不可取反
--timestart 09:00:00
- --timestop:用于指定时间范围的结束时间,不可取反
- --weekdays:用于指定"星期几",可取反
- 可以同时指定多个,用逗号隔开
- 能够数字表示"星期几",还能用缩写表示,例如:Mon, Tue, Wed, Thu, Fri, Sat, Sun
- --monthdays:用于指定"几号",可取反
- --datestart:用于指定日期范围的开始日期,不可取反
--datestart 2017-12-1
- --datestop:用于指定日期范围的结束时间,不可取反
- --timestart:用于指定时间范围的开始时间,不可取反
connlimit扩展模块:限制每个IP地址同时链接到server端的链接数量
- --connlimit-above:单独使用此选项时,表示限制每个IP的链接数量
- --connlimit-mask:此选项不能单独使用,在使用--connlimit-above选项时,配合此选项,则可以针对"某类IP段内的一定数量的IP"进行连接数量的限制
limit模块:限制单位时间内流入的包的数量
- --limit-burst:类比"令牌桶"算法,此选项用于指定令牌桶中令牌的最大数量
- --limit:类比"令牌桶"算法,此选项用于指定令牌桶中生成新令牌的频率,可用时间单位有second、minute 、hour、day
令牌桶算法
我们可以这样想象,有一个木桶,木桶里面放了5块令牌,而且这个木桶最多也只能放下5块令牌,所有报文如果想要出关入关,都必须要持有木桶中的令牌才行,这个木桶有一个神奇的功能,就是每隔6秒钟会生成一块新的令牌,如果此时,木桶中的令牌不足5块,那么新生成的令牌就存放在木桶中,如果木桶中已经存在5块令牌,新生成的令牌就无处安放了,只能溢出木桶(令牌被丢弃),如果此时有5个报文想要入关,那么这5个报文就去木桶里找令牌,正好一人一个,于是他们5个手持令牌,快乐的入关了,此时木桶空了,再有报文想要入关,已经没有对应的令牌可以使用了,但是,过了6秒钟,新的令牌生成了,此刻,正好来了一个报文想要入关,于是,这个报文拿起这个令牌,就入关了,在这个报文之后,如果很长一段时间内没有新的报文想要入关,木桶中的令牌又会慢慢的积攒了起来,直到达到5个令牌,并且一直保持着5个令牌,直到有人需要使用这些令牌,这就是令牌桶算法的大致逻辑。
udp扩展模块
- --sport:匹配udp报文的源地址
- --dport:匹配udp报文的目标地址
- 支持指定一个连续的端口范围
- 不能一次性指定多个离散的端口,可以使用multiport扩展模块
icmp扩展模块
- --icmp-type:匹配icmp报文的具体类型
- 使用icmp报文对应的
type/code
- 使用icmp报文的描述名称,名称中的"空格"需要替换为"-"
- 使用icmp报文对应的
- --icmp-type:匹配icmp报文的具体类型
state扩展模块:可以让iptables实现"连接追踪"机制
对于state而言,报文状态可以为
NEW:连接中的第一个包,状态就是NEW,我们可以理解为新连接的第一个包的状态为NEW。
ESTABLISHED:我们可以把NEW状态包后面的包的状态理解为ESTABLISHED,表示连接已建立。
RELATED:相关报文,最常用,表示这个封包是与我们主机发送出去的封包有关,可能是响应封包或者是联机成功之后的传送封包,这个状态很常被设定,因为设定了他之后,只要未来由本机发送出去的封包,即使我们没有设定封包的 INPUT 规则,该有关的封包还是可以进入我们主机,可以简化相当多的设定规则。
比如FTP服务,FTP服务端会建立两个进程,一个命令进程,一个数据进程。命令进程负责服务端与客户端之间的命令传输(我们可以把这个传输过程理解成state中所谓的一个"连接",暂称为"命令连接")。
数据进程负责服务端与客户端之间的数据传输 ( 我们把这个过程暂称为"数据连接" )。
但是具体传输哪些数据,是由命令去控制的,所以,"数据连接"中的报文与"命令连接"是有"关系"的。
那么,"数据连接"中的报文可能就是RELATED状态,因为这些报文与"命令连接"中的报文有关系。
INVALID:无效的封包,例如数据破损的封包状态。如果一个包没有办法被识别,或者这个包没有任何状态,那么这个包的状态就是INVALID,我们可以主动屏蔽状态为INVALID的报文。
UNTRACKED:报文的状态为untracked时,表示报文未被追踪,当报文的状态为Untracked时通常表示无法找到相关的连接。
可以将状态为RELATED或ESTABLISHED的报文都放行,这样,就表示只有回应我们的报文能够通过防火墙,如果是别人主动发送过来的新的报文,则无法通过防火墙
-m state --state RELATED,ESTABLISHED
允许 ICMP 封包与允许已建立的联机通过 filter表中INPUT链为DROP,OUTPUT链为ACCEPT, 此时本机ping其他主机不通,在INPUT链中添加规则: iptables -AINPUT -m state --state ESTABLISHED,RELATED -j ACCEPT 本机可以ping其他主机,但是其他主机无法ping本机
动作
"动作"与"匹配条件"一样,也有"基础"与"扩展"之分。同样,使用扩展动作也需要借助扩展模块,但是,扩展动作可以直接使用,不用像使用"扩展匹配条件"那样指定特定的模块。
ACCEPT与DROP都属于基础动作。而REJECT则属于扩展动作。
"动作"也有自己的选项,我们可以在使用动作时,设置对应的选项。
动作REJECT
REJECT动作的常用选项为--reject-with
使用--reject-with选项,可以设置提示信息,当对方被拒绝时,会提示对方为什么被拒绝。
可用值如下
icmp-net-unreachable
icmp-host-unreachable
icmp-port-unreachable,
icmp-proto-unreachable
icmp-net-prohibited
icmp-host-pro-hibited
icmp-admin-prohibited
当不设置任何值时,默认值为icmp-port-unreachable。
动作LOG
使用LOG动作,可以将符合条件的报文的相关信息记录到日志中,但当前报文具体是被"接受",还是被"拒绝",都由后面的规则控制,换句话说,LOG动作只负责记录匹配到的报文的相关信息,不负责对报文的其他处理,如果想要对报文进行进一步的处理,可以在之后设置具体规则,进行进一步的处理。
在使用LOG动作时,匹配条件应该尽量写的精确一些,匹配到的报文数量也会大幅度的减少,这样冗余的日志信息就会变少,同时日后分析日志时,日志中的信息可用程度更高。
LOG动作会将报文的相关信息记录在/var/log/message文件中,当然,我们也可以将相关信息记录在指定的文件中,以防止iptables的相关信息与其他日志信息相混淆,修改/etc/rsyslog.conf文件(或者/etc/syslog.conf),在rsyslog配置文件中添加如下配置即可。
#vim /etc/rsyslog.conf
kern.warning /var/log/iptables.log
加入上述配置后,报文的相关信息将会被记录到/var/log/iptables.log文件中。
完成上述配置后,重启rsyslog服务(或者syslogd),服务重启后,配置即可生效,匹配到的报文的相关信息将被记录到指定的文件中。
LOG动作也有自己的选项,常用选项如下
--log-level选项可以指定记录日志的日志级别,可用级别有emerg,alert,crit,error,warning,notice,info,debug。
--log-prefix选项可以给记录到的相关信息添加"标签"之类的信息,以便区分各种记录到的报文信息,方便在分析时进行过滤。
注:--log-prefix对应的值不能超过29个字符。
动作SNAT
网络内部的主机可以借助SNAT隐藏自己的IP地址,同时还能够共享合法的公网IP,让局域网内的多台主机共享公网IP访问互联网。
iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -j SNAT --to-source 公网IP
SNAT规则只能存在于POSTROUTING链与INPUT链中
动作DNAT
通过公网IP访问局域网内的服务。
理论上来说,只要配置DNAT规则,不需要对应的SNAT规则即可达到DNAT效果。但是在测试DNAT时,对应SNAT规则也需要配置,才能正常DNAT,可以先尝试只配置DNAT规则,如果无法正常DNAT,再尝试添加对应的SNAT规则,SNAT规则配置一条即可,DNAT规则需要根据实际情况配置不同的DNAT规则。
iptables -t nat -I PREROUTING -d 公网IP -p tcp --dport 公网端口 -j DNAT --to-destination 私网IP:端口号
iptables -t nat -I PREROUTING -d 公网IP -p tcp --dport 8080 -j DNAT --to-destination 10.1.0.1:80
iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -j SNAT --to-source 公网IP
DNAT规则只配置在PREROUTING链与OUTPUT链中
动作MASQUERADE
如果公网IP是动态获取的,不是固定的,则可以使用MASQUERADE进行动态的SNAT操作,如下命令表示将10.1网段的报文的源IP修改为eth0网卡中可用的地址。
iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -o eth0 -j MASQUERADE
可以把MASQUERADE理解为动态的、自动化的SNAT,如果没有动态SNAT的需求,没有必要使用MASQUERADE,因为SNAT更加高效。
动作REDIRECT
使用REDIRECT动作可以在本机上进行端口映射
比如,将本机的80端口映射到本机的8080端口上
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
经过上述规则映射后,当别的机器访问本机的80端口时,报文会被重定向到本机的8080端口上。
REDIRECT规则只能定义在PREROUTING链或者OUTPUT链中。
规则套路
1、规则的顺序非常重要。
如果报文已经被前面的规则匹配到,IPTABLES则会对报文执行对应的动作,通常是ACCEPT或者REJECT,报文被放行或拒绝以后,即使后面的规则也能匹配到刚才放行或拒绝的报文,也没有机会再对报文执行相应的动作了(前面规则的动作为LOG时除外),所以,针对相同服务的规则,更严格的规则应该放在前面。
2、当规则中有多个匹配条件时,条件之间默认存在"与"的关系。
如果一条规则中包含了多个匹配条件,那么报文必须同时满足这个规则中的所有匹配条件,报文才能被这条规则匹配到。
3、在不考虑1的情况下,应该将更容易被匹配到的规则放置在前面。
比如,你写了两条规则,一条针对sshd服务,一条针对web服务。
假设,一天之内,有20000个请求访问web服务,有200个请求访问sshd服务,
那么,应该将针对web服务的规则放在前面,针对sshd的规则放在后面,因为访问web服务的请求频率更高。
如果将sshd的规则放在前面,当报文是访问web服务时,sshd的规则也要白白的验证一遍,由于访问web服务的频率更高,白白耗费的资源就更多。
如果web服务的规则放在前面,由于访问web服务的频率更高,所以无用功会比较少。
换句话说就是,在没有顺序要求的情况下,不同类别的规则,被匹配次数多的、匹配频率高的规则应该放在前面。
4、当IPTABLES所在主机作为网络防火 墙时,在配置规则时,应着重考虑方向性,双向都要考虑,从外到内,从内到外。
5、在配置IPTABLES白名单时,往往会将链的默认策略设置为ACCEPT,通过在链的最后设置REJECT规则实现白名单机制,而不是将链的默认策略设置为DROP,如果将链的默认策略设置为DROP,当链中的规则被清空时,管理员的请求也将会被DROP掉。
Part3 配置内容
filter表:
# 清除所有链中的规则
iptables -F
# 清除所有用户自定义链
iptables -X
# 修改链的默认规则
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptalbes -P FORWARD DROP
# 添加规则,接受相应状态的封包
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
# 添加规则,丢弃无效封包
iptables -A INPUT -m state --state INVALID -j DROP
iptables -A OUTPUT -m state --state INVALID -j DROP
iptables -A FORWARD -m state --state INVALID -j DROP
# 接受loop网口的输入和输出
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# 防止SYN洪泛攻击
## 新建SYNFLOOD链
iptables -N SYNFLOOD
## 在INPUT上检查tcp封包,跳转到子链执行,两种写法
iptables -A INPUT -p tcp --tcp-flags ACK,RST,SYN,FIN SYN -j SYNFLOOD
iptables -A INPUT -p tcp --syn -j SYNFLOOD
## 在子链中设置访问速度,最后跳转回INPUT链
iptables -A SYNFLOOD -p tcp -m limit --limit 25/second --limit-burst 50 -j RETURN
## 不符合要求的封包一律丢弃
iptables -A SYNFLOOD -j DROP
### REJECT –reject-with tcp-reset 比 DROP 好,干脆利落,节约时间,节约带宽
### REJECT表示拒绝,DROP表示丢弃,丢弃会导致对方重传,拒绝后则不会
iptables -A SYNFLOOD -j REJECT
# 为ssh server设置相关规则
iptables -N SSHSRV
iptables -A INPUT -p tcp --dport 22 -m state --state NE
## --set表示将匹配到的报文记录下来,--name给用来记录报文的列表起名称,--resource表示记录源ip地址
iptables -A SSHSRV -m recent --set --name SSHSRV --resource
## --update 是指每次建立连接都更新列表,--seconds 必须与--rcheck或者--update同时使用,--hitcount必须与--rcheck或者--update同时使用
## 利用recent限制单IP在60s内只能与本机建立4个新连接。被限制5分钟后即可恢复访问。
iptables -A SSHSRV -m recent --update --name SSHSRV --seconds 60 --hitcount 4 --rsource -j REJECT
iptables -A SSHSRV -j ACCEPT
Part4 其他内容
防止SYN Flood攻击
SYN泛洪攻击(SYN Flood)是指使用不完善的TCP/IP三次握手,恶意发送大量只包含SYN握手序列的数据包的攻击方法。这种攻击方法可能会导致被攻击的计算机拒绝服务甚至崩溃,从而使潜在的连接占用大量的系统资源,无法完成三次手。
措施:
减少SYN-Timeout时间: 由于SYN Flood攻击的效果取决于服务器上保持的SYN半连接数,这个值=SYN攻击的频度 x SYN Timeout,所以通过缩短从接收到SYN报文到确定这个报文无效并丢弃改连接的时间。缺点是仅在对方攻击频度不高的情况下生效
iptables -A FORWARD -p tcp –syn -m limit –limit 1/s -j ACCEPT
iptables -A INPUT -i eth0 -m limit –limit 1/sec –limit-burst 5 -j ACCEPT
限制syn的请求速度:需要调节一个合理的速度值,不然会影响正常用户的请求
iptables -N syn-flood
iptables -A INPUT -p tcp –syn -j syn-flood
iptables -A syn-flood -p tcp –syn -m limit –limit 1/s –limit-burst 50 -j RETURN
iptables -A syn-flood -j REJECT
设置SYN Cookie:给每一个请求连接的IP地址分配一个Cookie,如果短时间内连续受到某个IP的重复SYN报文,就认定是受到了攻击,以后从这个IP地址来的包会被丢弃。不足之处是依赖于对方使用真实的IP地址。
sysctl -w net.ipv4.tcp_syncookies=1
sysctl -w net.ipv4.tcp_max_syn_backlog=3072
sysctl -w net.ipv4.tcp_synack_retries=0
sysctl -w net.ipv4.tcp_syn_retries=0
sysctl -w net.ipv4.conf.all.send_redirects=0
sysctl -w net.ipv4.conf.all.accept_redirects=0
sysctl -w net.ipv4.conf.all.forwarding=0
sysctl -w net.ipv4.icmp_echo_ignore_broadcasts=1
防止ping命令
sysctl -w net.ipv4.icmp_echo_ignore_all=1
阻止特定的IP范围
iptables -A INPUT -s 192.168.5.1/8 -i eth0 -j Drop
iptabes 其他限制规则:
防御太多DOS攻击连接,可以允许外网每个IP最多15个初始连接,超过的丢弃,第二条是在第一条的基础上允许已经建立的连接和子连接允许
iptables -A INPUT -i eth0 -p tcp --syn -m connlimit --connlimit-above 15 --connlimit-mask 32 -j DROP (--connlimit-mask 32为主机掩码,32即为一个主机ip,也可以是网段)
iptables -A INPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
抵御DDOS ,允许外网最多24个初始连接,然后服务器每秒新增12个,访问太多超过的丢弃,第二条是允许服务器内部每秒1个初始连接进行转发
iptables -A INPUT -p tcp --syn -m limit --limit 12/s --limit-burst 24 -j ACCEPT
iptables -A FORWARD -p tcp --syn -m limit --limit 1/s -j ACCEPT
允许单个IP访问服务器的80端口的最大连接数为 20
iptables -I INPUT -p tcp --dport 80 -m connlimit --connlimit-above 20 -j REJECT
对访问本机的22端口进行限制,每个ip每小时只能连接5次,超过的拒接,1小时候重新计算次数
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --name SSHPOOL --rcheck --seconds 3600 --hitcount 5 -j DROP
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --name SSHPOOL --set -j ACCEPT
(上面recent规则只适用于默认规则为DROP中,如果要适用默认ACCEPT的规则,需要--set放前面 并且无-j ACCEPT)
iptables中的return
- 从一个CHAIN里可以jump到另一个CHAIN, jump到的那个CHAIN是子CHAIN
- 从子CHAIN return后,回到触发jump的那条规则,从那条规则的下一条继续匹配
- 如果return不是在子CHAIN里,而是在main CHAIN,那么就以默认规则进行
Reference
- [iptables防火墙设置](https://ulomo.github.io/2019-04-25
- iptables (简体中文)
- 浅谈iptables防SYN Flood攻击和CC攻击
- iptables 之 REJECT 与 DROP 对比
- iptables详解