OpenWrt开发:44---防火墙之iptables工具

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_41453285/article/details/102734347

一、防火墙简介

  • “防火墙”(Firewall)术语来自建筑设计领域,是指用来起分割作用的墙,当某一部分 着火时可以减缓或保护其他部分免受火灾影响。在计算机网络中,防火墙是在两个或多个 网络之间用于设置安全策略的一个或多个系统的组合。防火墙起到隔离异常访问的作用, 仅允许可靠的流量通过,从而保护了家庭和企业内部网络信息的安全
  • 下图是一 个典型的防火墙部署结构

Linux防火墙通常包含两部分,分别为:

  • iptables
  • netfilter

二、iptables防火墙工具简介

  • iptables是用C语言实现的,最新版本是1.4.21,并以GNU许可协议发布。它实际上包含两部分:内核netfilter和用户空间工具 iptables
  • 管理员通过iptables工具集和内核打交道,将防火墙规则写入内核中。内核netfilter执行报文过滤规则
  • iptables是Linux管理防火墙规则的命令行工具,处于用户空间。netfilter执行报文过滤,处于Linux内核空间。有时候也会用 iptables 来统称Linux防火墙
  • iptables 是一个报文状态检测防火墙,这意味着防火墙内部存储每一个连接的信息,并且可以将每一个报文关联到它所属的连接。这个信息非常有用,它用于自动打开响应报文的传输路径,因此在创建防火墙规则时,通常没有必要创建相反方向的防火墙规则,防火 墙将自动计算出这个规则

三、iptables中的表

  • iptables根据功能划分不同的表来处理不同的功能逻辑,当前包含5个表,分别为filter、nat、mangle、raw和security

filter(过滤表)

  • filter是iptables的默认表,主要用于报文过滤,在这里根据报文的内容对报文进行丢 弃或者接收
  • 它包含有 3 个内置规则链:
    • ①INPUT输入链:处理目标地址为本机 IP 地址的报文
    • ②OUTPUT输出链:处理本机 IP 地址产生的报文
    • ③FORWARD转发链:处理经过本机路由的报文
  • 这样每一个IP报文只经过这3个内置链中的一个,便于进行数据报文匹配和处理。 这里是真正实现防火墙处理的地方
  • 注意:
    • ①经过本机转发的报文经过 FORWARD 链,不经过 IPPUT 链和 OUTPUT 链
    • ②本机产生的报文经过 OUTPUT 链,其他的链不经过
    • ③去往主机的报文经过该主机的 INPUT 链,其他的链不经过

nat(网络地址转换表)

  • nat用来完成源/目的地址和端口的转换,当一个报文在创建一个新的连接时进入该表
  • 它也有3个内置规则链:
    • ①PREROUTING:用于修改到来的报文,只用来做网络地址转换
    • ②OUTPUT:用于修改本机产生的并且在路由处理之前的报文
    • ③POSTROUTING:用于修改准备出去的报文的地方
  • 通过目的地址转换,你可以将服务器放在防火墙后面,并使用私有 IP 地址。一些协 议通过 nat 转换有困难(例如 FTP 或 SIP),连接跟踪将打开这些协议的数据/媒体流路径。nat 表不能用于报文过滤和报文修改,因为每一个连接流仅有一次机会进入该表中的规则链
  • 网络地址转换在路由功能前后都可能发生,源地址转换是在数据包通过路由之后在 POSTROUTING 规则链进行地址转换。目的地址转换是在路由之前,在 PREROUTING 规 则链进行地址转换

mangle(修改表)

  • 这个表主要用来进行报文修改
  • 有5个内置规则链:
    • ①REROUTING:针对到来的报文,在路由之前修改的地方
    • ②INPUT:针对目的地址为网关本身的报文
    • ③FORWARD:针对通过网关路由转发的报文
    • ④POSTROUTING:将要发送出去的报文的地方
    • ⑤OUTPUT:本机产生报文在路由之前修改的地方
  • 通常使用该表进行报文修改,以便进行 QoS 和策略路由。通常每一个报文都进入该表,但不使用它来做报文过滤

raw(原始表)

  • 这个表很少被用到,主要用于配置连接跟踪相关内容,在 ip_conntrack 之前调用
  • 它提供了两个内置规则链:
    • ①PREPROUTING:到达本机的报文
    • ②OUTPUT:本机进程产生的报文
  • 这里是能够在连接跟踪生效前处理报文的地方,你可以标记符合某种条件的报文不被 连接跟踪处理。一般很少使用

security表

  • 这个表用于安全Linux的防火墙规则,是iptables最近的新增 表,在实际项目中还很少用到

四、处理目标

  • 防火墙规则检测报文的特征是否符合规则,如果匹配,就进入规则的处理目标(TARGET)中。如果报文不匹配则进入该规则链的下一条规则进行检测。就这样逐条规则进行比较,直到整个规则链比较完成

系统内置的4种处理方式

  • ACCEPT(接收):表示让这个报文通过
  • DROP(丢弃):表示将这个报文丢弃。详细的介绍可以看下面的REJECT处理介绍
  • QUEUE(入队):表示把这个报文传递到用户空间的队列中
  • RETURN(返回):表示停止这条规则链的匹配,返回到调用这个规则链的上一条 规则链的规则处执行。如果到达了一个内建的规则链的末端,或者遇到内置链的 规则目标是 RETURN,报文的命运将由规则链指定的默认目标处理方式决定
  • 还有其他扩展的目标处理方式,例如REJECT、DNAT、SNAT、MASQUERADE、LOG和 REDIRECT等

REJECT(拒绝)

  • 概念:REJECT 和 DROP 一样丢弃报文
  • 特点:但REJECT 的不同之处在于同时还向发送者返回一 个ICMP错误消息。这样发送者将知道报文被丢弃,如果发送端检测到返回的错误信息, 将不再尝试发送报文,这样可以在特定条件下减少发送端重发报文
  • 例如:禁止访问主机上80端口的服务,访问者将收到端口不可达的ICMP消息
iptables -A IPNUT -p tcp --dport 80 -j REJECT

DROP和REJECT含义的比较:

DROP 和 REJECT 报文,许多人选择丢弃报文,因为其安全优势超过拒绝,因为这样 暴露给攻击者的信息较少,然而在调试网络问题时会遇到困难,应用程序也不知所措

  • 如果报文被 REJECT:路由器将响应一个 ICMP 目的端口不可达消息,这样连接将立即失 败。这意味着每一个试图连接特定端口都会有 ICMP 响应报文产生。如果有大量的访问或攻 击,这样做会有大量的 ICMP 消息产生,导致占用所有的带宽而合法的连接不可用(DOS)
  • 当使用DROP时:客户端不知道报文被丢弃,会继续使用重传机制来发送报文,直到 连接超时。具体行为依赖于客户端软件的实现,这将导致程序挂起等待超时,然后才会继续执行

DROP和REJECT利弊如下:

  • DROP:
    • 信息暴露较少
    • 攻击面减少
    • 客户软件可能无法很好地处理它(程序挂起直到连接超时)
    • 可能使网络调试复杂化(报文丢弃,不清楚导致问题出现的原因,可能是路由器 的问题,或者报文丢失)
  • REJECT
    • 暴露了防火墙的 IP 地址信息(例如流量被实际阻挡的 IP)
    • 客户端软件能立即从拒绝连接尝试中恢复过来
    • 网络调试更容易(路由和防火墙问题可以清晰地区分出来)

DNAT(目的网络地址转换)

  • 特点:当你的局域网内的多个服务器需要对互联网的机器提供服务时,你就会用到这个目标处理方式。这个目标是用来实现目的网络地址转换的,就是重写报文的目的IP地址。如果一个报文被匹配了,那么和它属于同一个流的所有报文都会被自动转换,然后就可以被路由到正确的主机或网络
  • 这个处理目标仅可以用在nat表中的PREROUTING和OUTPUT链以及被这些链调用的自定义链中
  • 例如:将访问路由器的80端口的流量重定向到192.168.6.100上:(这样Web服务器就可以搭建在局域网的主机(192.168.6.100)上对外提供服务,处理流程如下)
    • ①报文进入防火墙之后,将目标地址修改为 192.168.6.100,然后离开防火墙到达 HTTP 服务器
    • ②HTTP 服务器处理完成后,将源地址改为目标地址,使用自身 IP 作为源地址发送 报文
    • ③ 防火墙收到响应报文后将报文的源地址转换为防火墙的出接口地址,然后返回给 请求方。整个通信流程完成
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.6.100

SNAT(源网络地址转换)

  • 这是另外一种网络地址转换方式
  • 仅仅在nat表的POSTROUTING和INPUT链,以及和被这些链调用的自定义链中可以使用
  • 它指定报文的源地址将被修改,它至少需要一 个参数-源地址,报文的源地址将被指定地址替换。此连接的后续报文并不进入该规则中, 连接中的报文源IP均被自动替换
  • 设置参考命令如下:
iptables -t nat -A POSTROUTING –s 192.168.6.0/24 –o eth0 \
-j SNAT --to-source 10.0.2.15
  • 这个目标处理方式经常用于仅有少量固定 IP 地址上网的情形,局域网的私有地址在 访问因特网时,源地址被路由器外网地址替换

MASQUERADE(伪装)

  • MASQUERADE是最常用的处理目标,因为大多数情况下,路由器并没有一个固定的IP 地址。我们的路由器是通过 PPPoE 拨号上网或者是通过DHCP自动分配的 IP 地址。这 个处理目标和SNAT处理目标作用是一样的,区别就是它不需要指定源地址
  • MASQUERADE是被专门设计用于那些动态获取IP地址的连接,比如拨号上网、DHCP连接等
  • 如果你有固定的IP地址,还是用SNAT处理目标,这样可以节省计算资源
  • MASQUERADE只能用于nat表的POSTROUTING链
  • 例如:局域网来自192.168.6.0网络的报文通过MASQUERADE进行源地址转换
iptables -t nat -A POSTROUTING –s 192.168.6.0/24 –o eth0 -j MASQUERADE

LOG

  • 为匹配的报文开启内核记录
  • 当在规则中设置了这一选项后,Linux内核会通过printk函数打印一些关于匹配包的信息,然后通过syslog机制记录在日志文件中。该处理目标并非最终目标,处理完成后,报文还会接着进入下一条规则继续匹配
  • 有以下几个选项可以设置:
    • --log-level:日志级别
    • --log-prefix:prefix 在记录 log 信息前加上的特定前缀:最多 14 个字母长,用来和 日志中其他信息区别
    • --log-tcp-sequence:记录 TCP 序列号
    • --log-tcp-options:记录 TCP 报文头部的选项
    • --log-ip-options:记录 IP 报文头部的选项

REDIRECT

  • 只适用于nat表的PREROUTING和OUTPUT链,以及它们调用的用户自定义链
  • 修改报文的目标IP地址来发送报文到机器自身(本地生成的报文被设置为地址127.0.0.1)。经常用于HTTP代理,例如将80端口的HTTP请求重定向到SQUID的3128端口
  • 它包含一个选项:
--to-ports []
  • 指定使用的目的端口或端口范围。不指定的话,目标端口不会被修改。只能用于指定了TCP或UDP的规则
  • 注意,iptables中的所有表都是小写字母表示,内置规则链均大写字母表示,所有处理目标均以大写字母表示

五、接收报文处理流程

  • iptables有5个表,每一个表中又有几个不同的链,不同的表中有相同名称的规则链, 但这些规则链处理的任务是不同的。报文按照预定的流程来顺序进入到各个规则链中
  • 同一名称规则链根据表的先后顺序进入,进入顺序依次是 raw、 mangle、filter 和 nat

总体流程

报文处理流程如下图所示

  • 报文从网络来的,首先进入到 PREROUTING 链中进行处理,再对目标 IP 地址进行判 断,如果目标 IP 地址和本机相同就会把报文转到 INPUT 链,再转到应用程序。如果报文 的 IP 地址和本机不同,则是转发报文,进入 FORWARD 链,再经过 POSTROUTING 链发出报文

详细步骤

  • (1)首先网卡从网络上收到 IP 报文
  • (2)报文进入 raw 表的 PREROUTING 链。 这里能够在连接跟踪生效前对报文进行处理, 你可以标记某种类型的报文不被连接跟踪处 理。一般很少使用
  • (3)报文进入到连接跟踪处理。这里是收 到报文进行连接跟踪处理的位置
  • (4)报文进入到 mangle 表的 PREROUTING 链。这里是报文进入网关之后、路由之前修改 报文的地方
  • (5)报文进入到 nat 表的 PREROUTING 链。在这里我们做目的地址转换(DNAT)。这 里不能用于报文过滤,因为每一个连接数据流 仅第一个报文进入到这里
  • (6)进行路由决策,因为前面的 mangle 和 nat 表可能修改了报文的 IP 地址信息
    • 如果目标地址为网关,则直接进入到 INPUT 链 中
      • 报文进入到 mangle 表的 INPUT 链。这里是报文进入网关时修改报文的地方,在 这里做报文过滤是不被推荐的,因为它可能有副作用。通常也很少修改报文
      • 报文进入到 filter 表的 INPUT 链。这里是对收到报文做过滤的地方,然后将报文 转到应用程序
    • 如果和本机地址不同,则是进入路由转发
      • 对于转发报文进入到 mangle 表的 FORWARD 链。这里是对转发报文进行修改的地方
      • 报文进入到 filter 表中的 FORWARD 链,对转发报文进行过滤。这里是唯一适合 对转发报文过滤的地方。所有的转发报文均经过这个规则链
      • 报文进入到 mangle 表的 POSTROUTING 链。这条链可能被两种报文遍历,一种 是转发的报文,另外就是本机产生的报文。这个链通常很少使用
      • 报文进入到 nat 表的 POSTROUTING 链。在这里我们做源地址转换(SNAT)。 这里不能用于报文过滤,因为每一个数据 流仅有第一个报文进入到这里
      • 最后经过网卡发送报文

六、发送报文的处理流程

  • 如果是本机应用程序发送报文则在 netfilter 中是另外的处理流程
  • 如下图所示。报文则首先通过OUTPUT链,然后经过POSTROUTING链再发送报文。网络报文在各个表中的规则链中流动,按照 raw、 mangle、filter和nat表的顺序依次进行匹配

详细步骤

  • (1)首先本地进程产生报文,并进行 路由选择,选择源 IP 地址及出接口设备。 如果没有找到路由将直接返回失败
  • (2)进入 raw 表 OUTPUT 链。这里是 能够在连接跟踪生效前处理报文的地方, 你可以标记某种类型的报文不被连接跟踪处理。一般很少使用。
  • (3)连接跟踪。这里是本地发出报文进行连接跟踪处理的位置。
  • (4)进入到 mangle 表的 OUTPUT 链。这里是我们修改报文的地方。不推荐在这里做 报文过滤,因为它可能有副作用。
  • (5)进入到 nat 表 OUTPUT 链。这里对于本机发送的报文做目的地址转换(DNAT)。 不能用于过滤,因为每一个数据流仅第一个报文进入到这里
  • (6)进入路由决策。因为前面的 mangle 和 nat 表可能修改了报文的 IP 地址信息
  • (7)进入到 filter 表的 OUTPUT 链。对本机发出报文做过滤的地方
  • (8)进入到 mangle 表的 POSTROUTING 链。这条链可能被两种报文遍历,一种是转 发的报文,另外就是本机产生的报文
  • (9)进入到 nat 表的 POSTROUTING 链。在这里我们做源地址转换(SNAT)。这里 不 能用于报文过滤,因为每一个数据流仅有第一个报文进入到这里
  • (10)在网卡接口上发出报文,报文离开主机

七、报文匹配规则

  • 防火墙规则用于匹配报文,有多种匹配报文特征的方法,常见的有根据数据链路层、 IP 层及传输层特征进行匹配,甚至可以根据应用层特征进行匹配,例如用户、域名以及内 容匹配等

MAC地址

  • MAC 地址过滤用于匹配报文以太网卡的物理地址。必须是 XX:XX:XX:XX:XX:XX 这样 的格式。它只对来自以太网设备并进入 PREROUTING、FORWORD 和 INPUT 链的报文有 效。注意:MAC 地址过滤只对源 MAC 地址有效。
  • 格式为:-m mac --mac-source [!] address
  • 如下面所示的规则将丢弃来自指定 MAC 的报文
iptables -I INPUT -m mac --mac-source 28:D2:44:15:D5:A4 -j DROP

IP层匹配

  • 常用的有协议、源 IP 地址和目标 IP 地址,经常和传输层的端口一起使用
  • -p 用于匹配 IP 层报头所指定的传输层协议。常见的协议为 TCP、UDP、IGMP、ICMP 或者 ALL,等等。也可以是一个数字,数字代表的协议在文件/etc/protocols 描述。数字零 表示所有协议。例如禁止 UDP 5060 报文通过命令如下:
iptables -A FORWARD -p UDP --m udp dport 5060 -j DROP
  • s 和-d 用于匹配 IP 报文的源和目标 IP 地址。IP 地址可以是网络地址、主机名或具体 的 IP 地址。如果是主机名,在插入到内核之前将被解析为 IP 地址。网络掩码长度是指 IP 地址左边“1”的个数。例如 24 表示 255.255.255.0。例如禁止 192.168.1.0 网段访问本机的 设置命令如下:
iptables -A INPUT -s 192.168.1.0/24 -j DROP

owner模块

  • owner 模块用于匹配报文发起者,用于本机进程产生的报文,一般为用户或用户组 ID。 这些规则仅可以在 OUTPUT 和 POSTROUTING 链中使用。转发的报文不会匹配到任何的用 户信息,内核线程产生的报文也没有所有者,例如 ICMP 信息。这在一些严格限制仅限定用 户进程可以通过的场合使用,每一个进程一个用户,这样可以非常方便地对进程加以区分。
  • 例如,允许 1002 用户进程的报文通过:
iptables -I OUTPUT -m owner --uid-owner 1002 -j ACCEPT

接口匹配

模块提供了根据报文的出入接口来匹配的方法,如果不限定接口,规则将匹 配所有的网卡接口网络。可以通过以下方法来设置匹配接口

  • -i [name]:这是报文经由该接口接收的流入接口名称,报文通过该网卡接口接收 (在规则链 INPUT、FORWORD 和 PREROUTING 中进入的报文)。
  • -o [name]:这是报文经由该接口发出的流出接口名称,报文通过网卡该口发送(在 规则链 FORWARD、OUTPUT 和 POSTROUTING 中送出的报文)。
  • 当在接口名称前使用“!”修饰后,指的是不为该接口的报文,如果接口名后面加上“+”, 则所有以此接口名开头的接口都会被匹配。如果不指定这个选项,那么将匹配任意网卡接 口的报文

conntrack连接跟踪

conntrack连接跟踪是有状态防火墙的核心机制,用于存取这个报文的连接跟踪状态来 计算匹配返回的报文。state是连接跟踪的子集,用于存取连接跟踪的报文状态

  • 可选的状态列表如下:
    • NEW:这个报文开始新的连接,是连接建立的第一个报文。例如 TCP 连接的第一 个请求报文
    • ESTABLISHED:连接建立,这个报文关联的连接已经在双方向看到报文
    • RELATED:这个报文开始新的连接,但是关联到一个已存在的连接上,例如一个 FTP 数据传输或者一个 ICMP 错误
    • UNTRACKED:这个报文没有连接跟踪,如果你在 raw 表中使用-j CT -notrack 进 行了设置
    • INVALID:这个报文没有关联到已知的连接。例如收到不属于已有连接的 ICMP 错误信息
  • 可以和任何网络协议一起来使用 iptables 连接跟踪的状态功能,状态功能支持 TCP、 UDP 和 ICMP 协议。下面的例子使用连接跟踪来只转发与已建立连接相关的分组报文,这 种情况通常是禁止转发广域网的直接发起请求报文,这样就可以只用加入一条规则来允许 局域网指定协议可以通过
iptables -A FORWARD -i eth0 -m state --state ESTABLISHED,RELATED -j
ACCEPT
  • iptables 还支持很多扩展模块,例如 connlimit,用于限制并行连接数等

八、管理防火墙规则

  • iptables 工具提供了管理防火墙规则的功能,以下将介绍增加、删除、查看规则功能 如何使用
iptables [-t table] {-A|-C|-D} chain rule-specification
rule-specification = [matches...] [target]
match = -m matchname [per-match-options]
target = -j targetname [per-target-options]
  • 一个防火墙规则包含报文匹配规则和处理目标,处理目标在上面已经讲述,匹配规 则用于检测报文是否符合该规则标准。一般根据报文的 IP 特征进行匹配,典型根据报文 协议、IP 地址和端口进行匹配,在上面已经讲述

命令

  • -A --append:将防火墙规则增加到所选规则链的末尾。
  • -D --delete:在指定的规则链中删除规则。可以通过指定规则号来删除,也可以通 过规则匹配来删除。规则编号是指规则在规则链中的顺序号,顺序号从 1 开始增加。

注意:规则在规则链中的规则编号不是固定的,如果删除前面的规则,则后面的规则 自动往前移动

  • -I,--insert chain [rulenum] rule-specification:插入到规则链中的指定位置,如果不 指定插入位置,则插入到规则链的第一个位置处
  • -L,--list [chain]:查看防火墙规则,如果没有指明规则链,则所有的规则链均显 示出来
  • 所有的 iptables 命令,如果没有指定防火墙表就使用默认的 filter 表,所以查看网络地址 转换规则使用 iptables -t nat -n -L,注意经常使用的-n 选项,是为了避免长时间的 DNS 解析
  • iptables -F 清空所选的规则链中的规则。如果没有指定链,则清空指定表中的所有链 的规则。如果什么都没有指定,就清空默认表所有的链规则。当然也可以一条一条地删除, 但用这个命令会比较方便。例如清空 filter 表中 INPUT 链的规则:
iptables -t filter -F INPUT
  • ①默认策略的设置。每一条内置链的策略都是用来处理那些在相应的规则链中没有 被规则匹配的报文。也就是说,如果有一个报文没有被规则集中的任何规则匹配,那默认 策略就会命中,执行默认策略的行为
    • 一般有两种策略行为,默认通过(ACCEPT)和默认丢弃(DROP),在白名单模式会 使用默认丢弃,在黑名单模式下会默认通过。设置命令形式如下:
iptables [-P {chain} {policy}]

例如设置输入链为默认拒绝:iptables -P INPUT DROP
  • ②自定义规则链的创建。对于复杂规则,我们通常会创建自定义规则链来进行匹配, 并把自定义规则链加入到已有的规则链中,这样我们在删除及加载时非常方便。自定义规 则链设置命令如下:
iptables -N UDP_FILTER
  • ③清空整个防火墙。通常在进行防火墙配置前,需要将以前的规则全部删除,因此 我们清空整个防火墙
iptables -F
iptables -t nat -F
iptables -t mangle –F
  • ④一个典型路由器的配置。如果我们没有使用其他的额外的工具,我们手动进行 配置一个典型路由器防火墙如下图所示。从局域网发起的流量均可以通过,从互联 网发起的主动流量不能通过,从互联网来的被动报文也允许通过,因为这是局域网主机 请求的响应报文。所有局域网的请求转发后均进行网络地址转换,将源地址改为路由器 地址

  • ⑤如果我们需要停止防火墙,我们可以逐条删除规则,也可以直接清空规则,并设置其 默认策略,下图将停止防火墙

九、其他工具集(iptables-save、iptables-restore)

  • iptables提供了两个很有用的工具用来处理大规则集:iptables-save 和 iptables-restore, 它们把规则存入一个与标准脚本代码只有细微差别的特殊格式的文件中,或从中恢复 规则
  • 一般的 iptables 一次仅执行一条指令,如果对于很大的规则集也采用 iptables 来设置, 那就需要反复在内核和用户空间进行通信,这样将浪费很多的 CPU 时间,而这两个命令 通过一次调用就可以装载和保存整个规则集,这样节省了大量的时间
  • iptables-save:导出 iptables 规则到标准输出(即屏幕)中,我们使用 shell 的重定向命令可以将规则写入文件中。内容格式和 iptables 类似但稍有不同,这个格式便于程序解析
  • iptables-restore:用于加载导出的防火墙规则,使用标准输入的内容来导入,一般都是 通过 shell 提供的重定向从文件中读取规则之后来向内核导入规则

十、附加

猜你喜欢

转载自blog.csdn.net/qq_41453285/article/details/102734347
今日推荐