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):

  1. raw 用于配置数据包,raw 中的数据包不会被系统跟踪。
  2. filter 是用于存放所有与防火墙相关操作的默认表。
  3. nat 用于网络地址转换(例如:端口转发)。
  4. mangle 用于对特定数据包的修改。
  5. security 用于强制访问控制网络规则(例如: SELinux -- 详细信息参考 该文章)。

大部分情况仅需要使用 filternat。其他表用于更复杂的情况——包括多路由和路由判定——已经超出了本文介绍的范围。

链 (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 表包含 INPUTOUTPUTFORWARD 3条内建的链,这3条链作用于数据包过滤过程中的不同时间点,如该流程图所示。

image-20210531162801258

默认情况下,任何链中都没有规则。可以向链中添加自己想用的规则。链的默认规则通常设置为 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 动作,包含ACCEPTECNMARKMIRRORREDIRECTRETURNTCPMSSULOG、 DNATDSCPLOGMASQUERADEQUEUEREJECTSNATTOS
    • -g, –goto chain指定跳转用户自定义的链
    • [!] -i, –in-interface name 指定数据进来的网络接口
    • [!] -o, –out-interface name 指定数据出去的网络接口
    • [!] -f, –fragment 只能是ipv4起作用,类似于模糊匹配,通过数据包片段来匹配
    • -c, –set-counters packets bytes 允许root初始化链的数据

删除规则

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地址:-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:用于指定日期范围的结束时间,不可取反
  • 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报文的描述名称,名称中的"空格"需要替换为"-"
  • 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

  1. 从一个CHAIN里可以jump到另一个CHAIN, jump到的那个CHAIN是子CHAIN
  2. 从子CHAIN return后,回到触发jump的那条规则,从那条规则的下一条继续匹配
  3. 如果return不是在子CHAIN里,而是在main CHAIN,那么就以默认规则进行

Reference