iptables(12)实际应用举例:策略路由、iptables转发、TPROXY

简介

前面的文章中我们已经介绍过iptables的基本原理,表、链的基本操作,匹配条件、扩展模块、自定义链以及网络防火墙、NAT等基本配置及原理。

这篇文章将以实际应用出发,列举一个iptables的综合配置使用案例,将我们前面所涉及到的功能集合起来,形成一个完整的配置范例。

TPROXY

TPROXY(Transparent Proxying)允许代理服务器透明地处理网络流量,而无需修改客户端或服务器的配置。在 TCP/IP 栈中,这通常是通过修改 IP 地址或端口号来完成的,但 TPROXY 允许代理服务器接收原始数据包,并在不修改 IP 地址或端口号的情况下转发它们

以下是关于 TPROXY 的详细解释:

1. 功能与特点
透明性:客户端和服务端感知不到代理的存在,无需修改任何配置或代码。
灵活性:可以拦截、修改或转发任何进出网络的流量。
高性能:由于直接在内核层面处理流量,因此具有较低的性能开销。

2. 工作原理
流量拦截:使用 iptables 在 PREROUTING 链的 mangle 表中创建一个规则,拦截需要处理的流量。
路由规则:创建一个路由规则,将所有带有特定标记的数据包查找特定的路由表。
数据包映射:在特定的路由表中将所有 IPv4 地址声明为本地,实现数据包的映射。
数据包处理:在 tproxy 的监听端口上接收数据包,并编写网络应用或使用支持 tproxy 的软件(如 Squid 或 Envoy)来处理数据包。

3. 配置步骤(以 iptables 为例)
流量拦截:
使用 iptables 的 -t mangle 选项和 -A PREROUTING 命令,创建一个规则拦截特定流量到 tproxy 处理。例如,iptables -t mangle -A PREROUTING -p tcp -dport 9080 -j TPROXY --on-port 15001 --on-ip 127.0.0.1 --tproxy-mark 0x1/0x1。
路由规则:
使用 ip rule 命令创建一个规则,将所有带有特定标记的数据包查找特定的路由表。例如,ip rule add fwmark 1 lookup 100。
数据包映射:
使用 ip route 命令在特定的路由表中将所有 IPv4 地址声明为本地。例如,ip route add local 0.0.0.0/0 dev lo table 100。

4. 优点
提高带宽和减少传输延迟:通过缓存和减少网络中的冗余流量,提高服务质量。
安全性:可以记录和限制客户端请求,用于计费或审计。
灵活性:支持多种网络协议和应用场景,如 HTTP、HTTPS、MySQL 等。

5. 注意事项
内核版本:确保你的 Linux 内核版本支持 TPROXY。
防火墙规则:确保防火墙或安全组规则允许相关流量通过。
性能监控:定期监控代理服务器的性能和资源使用情况,确保系统稳定运行。

6. 应用场景
网络监管:用于屏蔽或允许对某些主机、网站的访问。
负载均衡:作为网络中继,实现负载均衡和流量分发。
TCP 连接分析:用于分析 gRPC、MySQL 等 TCP 连接的连接状态、生命周期等信息。
总之,通过透明地处理网络流量,为网络监管、负载均衡和 TCP 连接分析等多种应用场景提供了灵活的解决方案。
grep -Ei 'tproxy|TPROXY' /boot/config-$(uname -r) 如果看到CONFIG_NETFILTER_TPROXY=m或CONFIG_NETFILTER_TPROXY=y,说明TPROXY作为模块或编译进了内核

mangle表

在第一篇文章我们介绍Iptables基本原理的时候就提到过mangle表,现在我们再来回顾一下mangle表。

我们对每个”链”上都放置了一串规则,但是这些规则有些很相似,比如,A类规则都是对IP或者端口的过滤,B类规则是修改报文,那么这个时候我们把实现相同功能的规则放在一起,那么具有相同功能的规则的集合就叫做”表”。不同功能的规则,我们可以放置在不同的表中进行管理,而iptables已经为我们定义了4种表,每种表对应了不同的功能。

  1. filter 表:负责过滤功能;与之对应的内核模块是 iptables_filter
  2. nat(Network Address Translation) 表:网络地址转换功能,典型的比如 SNAT、DNAT,与之对应的内核模块是 iptables_nat
  3. mangle 表:解包报文、修改并封包,与之对应的内核模块是 iptables_mangle
  4. raw 表:关闭 nat 表上启用的连接追踪机制;与之对应的内核模块是 iptables_raw
表    
rawPREROUTING,OUTPUT
manglePREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
natPREROUTING,OUTPUT,POSTROUTING,INPUT
filterINPUT,FORWARD,OUTPUT

如上图所示,mangle表可以有REEROUTING、INPUT、FORWARD,OUTPUT,POSTROUTING链。

如上图所示,也就是说在5个链中,都可以通过mangle表去操作影响数据包的处理。

策略路由

说到策略路由,那么还有一个词叫路由策略,它们两者在网络中扮演着不同的角色,虽然都涉及到数据包路由转发的决策过程,但具体实现和应用方式存在显著区别。以下是两者的详细比较:

一、定义与概念

  1. 策略路由(Policy-Based Routing, PBR)
    • 是一种比基于目标网络进行路由更加灵活的数据包路由转发机制。
    • 允许管理员根据特定的策略来决定数据包的路由路径,这些策略可以基于数据包的源地址、目的地址、协议类型、端口号等多种因素。
    • 路由器将通过PBR决定如何对需要路由的数据包进行处理,PBR决定了一个数据包的下一跳转发路由器。
  2. 路由策略(Routing Policy)
    • 主要是为了改变网络流量所经过的途径而修改路由信息的技术,主要通过改变路由属性(包括可达性)来实现。
    • 是一种控制层面的行为,操作的对象是路由条目,匹配的是路由,具体是指目标网段、掩码、下一跳、度量值、Tag、Community等。

二、应用与特点

  1. 策略路由
    • 应用场景包括但不限于:确保关键数据包通过特定的路径、实现负载均衡、强制数据包通过特定的接口或链路等。
    • 优势在于其高度的灵活性和可控性,可以实现传统路由方法难以实现的复杂路由需求。
    • 广泛应用于各种网络环境中,特别是在需要精细控制网络流量的场合。
  2. 路由策略
    • 主要通过修改路由表的路由条目来控制数据流量的可达性,即对接受和发布的路由进行过滤。
    • 种类包括目的地址路由和源地址路由,现在还有智能均衡的策略方式。

三、总结

  1. 主要区别
    • 策略路由是基于策略进行流量的转发,而路由策略是基于路由表进行流量的转发。
    • 策略路由关注的是数据包级别的转发决策,而路由策略关注的是路由条目级别的控制。
    • 策略路由的操作对象是数据包,而路由策略的操作对象是路由条目。
  2. 应用差异
    • 策略路由更适用于需要精细控制数据包转发路径的场景。
    • 路由策略更适用于需要改变网络流量所经过的途径或解决特定网络问题的场景。

四、配置策略路由

在linux中有两张表用来管理和控制路由策略的不同方面分别是ip rule和ip route

ip rule

  • 关注的是路由策略,即如何根据特定条件将数据包路由到不同的路由表。
  • 定义了数据包应该使用哪个路由表进行转发。
  • 通过规则的条件和优先级来控制数据包的路由行为。

ip route

  • 关注的是路由表本身,即数据包在网络中的具体转发路径。
  • 定义了数据包从一个网络接口转发到另一个网络接口的路径。
  • 通过路由条目和优先级来控制数据包的转发行为。
当我们使用ip rule命令的时候默认会看到3张表具体含义如下
以下是每行规则的含义和作用:

0: from all lookup local
优先级(0):这是规则的优先级。数值越小,优先级越高。因此,这个规则有最高的优先级。
from all:这个条件表示这个规则适用于所有来源的数据包。
lookup local:如果数据包匹配这个规则(即所有数据包都匹配),则系统会在 local 路由表中查找路由。local 路由表通常包含本地接口地址和广播地址的路由条目。这确保了对本地地址的访问不会发送到其他接口或网关。

32766: from all lookup main
优先级(32766):这个规则的优先级低于 local 规则。
from all:同样,这个规则适用于所有来源的数据包。
lookup main:如果数据包不匹配 local 路由表(即不是本地地址或广播地址),则系统会在 main 路由表中查找路由。main 路由表是大多数系统配置的标准路由表,包含了大多数路由条目。

32767: from all lookup default
优先级(32767):这是最低的优先级。
from all:适用于所有来源的数据包。
lookup default:如果数据包不匹配 local 或 main 路由表,则系统会在 default 路由表中查找路由。通常,default 路由表包含一个或多个默认路由条目,这些条目定义了当数据包的目的地不在其他路由表中时应该发送到哪里。
运行 ip route 命令而不指定任何路由表时,默认看到的是 main 路由表。main 路由表是大多数Linux系统中配置的标准路由表,它包含了大多数路由条目。
要查看其他路由表,需要使用 ip route show table <table_id> 命令,其中 <table_id> 是要查看的路由表的标识符。例如,要查看 local 路由表,可以运行 ip route show table local

举例

如上图所示,我本机有一个开放端口是2017,跑了一个应用用来处理数据

需求1:

        到达本机的目的地址不是私有ip地址网段(10.0.0.0/8,172.16.0.0/12,192.168.0.0/16)的tcp/udp流量全部转发至本机的2017端口。

那么该如何实现该功能呢?

iptables -t mangle -N INSIDE-TP
在 mangle 表中创建了一个名为 INSIDE-TP 的新链。

iptables -t mangle -A INSIDE-TP -d 192.168.0.0/16 -j RETURN
在 INSIDE-TP 链中,对于目标 IP 地址在 192.168.0.0/16 范围内的数据包,执行 RETURN 动作。RETURN 动作意味着数据包将不会被此链中的后续规则处理,而是返回到它被调用的链(在这种情况下是 PREROUTING 链或其他调用 INSIDE-TP 链的链)中继续处理

iptables -t mangle -A INSIDE-TP -d 172.16.0.0/12 -j RETURN
对于目标 IP 地址在 172.16.0.0/12 范围内的数据包,也执行 RETURN 动作

iptables -t mangle -A INSIDE-TP -d 10.0.0.0/8 -j RETURN
对于目标 IP 地址在 10.0.0.0/8 范围内的数据包,也执行 RETURN 动作

iptables -t mangle -A INSIDE-TP -d 127.0.0.1/32 -j RETURN
对于目标 IP 地址在 127.0.0.1/32 范围内的数据包,也执行 RETURN 动作,因为后面我们需要通过127.0.0.1发送至本地回环接口

iptables -t mangle -A INSIDE-TP -d 224.0.0.0/4 -j RETURN
对于目标 IP 地址在 224.0.0.0/4 范围内的数据包(这是多播地址范围),执行 RETURN 动作

iptables -t mangle -A INSIDE-TP -p tcp -j TPROXY --on-ip 127.0.0.1 --on-port 2017
对于 TCP 协议的数据包,执行 TPROXY 动作。TPROXY 是一种特殊的透明代理功能,允许在不对数据包进行任何更改的情况下将其重定向到本地应用程序。这里,数据包将被重定向到 IP 地址 127.0.0.1 的 2017 端口

iptables -t mangle -A INSIDE-TP -p udp -j TPROXY --on-ip 127.0.0.1 --on-port 2017
这次是针对 UDP 协议的数据包

iptables -t mangle -A PREROUTING  -j INSIDE-TP
在 PREROUTING 链的末尾添加了一个规则,该规则将所有数据包(无论其协议或目标地址如何)都发送到 INSIDE-TP 链进行处理。请注意,由于前面的 RETURN 规则,大多数数据包将在到达 TPROXY 规则之前返回,因此只有那些目标地址不在前面指定的范围内的数据包才会被 TPROXY 规则处理。

注意:如上图配置所示,我们配置了 TPROXY --on-ip 127.0.0.1 --on-port 2017这个参数后,系统会将数据包发往127.0.0.1的2017端口,但是这里有一个问题,虽然我们在iptables中设置了该动作,但是,数据包仍然会经过路由表的处理。也就是说依旧会查路由表的条目,但是iptables的mangle并没有修改数据包的目的IP地址和端口信息。那么此时路由表是什么样的呢?

我们在上面介绍策略路由的时候介绍过过路由表

注意查看上面路由表,并没有任何条目匹配将发往目的地址不是私网地址的数据包发往127.0.0.1即lo接口的路由条目,此时需要添加路由条目。

那么该如何添加路由条目呢?我们的目的是为了让我们上面配置的iptables最后重定向到127.0.0.1的2017端口的数据包发往127.0.0.1端口,那么也就是说我们在写路由条目的时候只需要匹配这两个条目匹配的数据包就可以了。如何实现这个功能呢?我们可以通过mark标记来实现。

如下图所示,修改我们上面那两条iptables规则:

通过--tproxy-mark1给数据包打上1的标签

当数据包打上1的标签后,就可以针对标签1的数据包做对应的策略。

配置策略路由

系统会将带有 fwmark 1 标记的数据包路由到环回接口,而不考虑它们的目标地址。

ip rule add fwmark 1 table 10

这条命令用于添加一个新的路由规则。具体解释如下:

  • ip rule add:这是添加新路由规则的命令。
  • fwmark 1:这是一个标记(firewall mark),用于标记数据包。当数据包被防火墙或其他网络工具处理时,它们可能会被赋予这样的标记。在这里,特定的标记值是 1
  • table 10:这指定了当数据包具有上述标记时,应该查找哪个路由表来进行路由决策。在这里,是路由表 10

该条目的含义是:任何被打上 fwmark 1 标记的数据包都应该根据路由表 10 中的路由条目进行路由决策。

ip route add local 0.0.0.0/0 dev lo table 10

这条命令在特定的路由表(在这里是路由表 10)中添加了一个新的路由条目。具体解释如下:

  • ip route add:这是添加新路由条目的命令。
  • local:这指定了这是一个本地路由,用于处理发往本地地址(例如环回地址或其他本地网络接口地址)的数据包。由于目标地址是 0.0.0.0/0(即所有地址),它实际上是一个特殊的条目,用于捕获所有目标地址的本地路由。
  • 0.0.0.0/0:这是一个目标网络,但在这里,它表示所有目标地址。然而,由于这是一个 local 路由,它实际上只会影响发往本地地址的数据包(尽管目标地址是 0.0.0.0/0)。
  • dev lo:这指定了数据包应该通过哪个网络接口发送。在这里,是环回接口 lo
  • table 10:这指定了这条路由条目应该添加到哪个路由表中。在这里,是路由表 10

该条目的含义是:将所有本地流量(目的地址为任意IP地址)通过本地设备(loopback设备)发送,并将此路由规则添加到表编号为10的路由表中

合在一起的整体含义为:将所有标记为1 的数据包(目的地址为任意IP地址)通过本地设备(loopback设备)发送。

当我们设置了策略路由后,我们的数据包通过iptables打上标签,然后查看路由表发送至本机的2017端口。

 需求2:

本机发起的流量目的地址不是私有ip地址网段(10.0.0.0/8,172.16.0.0/12,192.168.0.0/16)的tcp/udp流量全部转发至本机的2017端口。

iptables -t mangle -N LOCAL-TP
这行命令在mangle表(通常用于修改数据包的标记,例如QoS或路由)中创建了一个新的链(chain)叫做
LOCAL-TP。

iptables -t mangle -A LOCAL-TP -d 192.168.0.0/16 -j RETURN
这行命令在LOCAL-TP链中添加了一条规则,用于匹配目标地址(destination address)在
192.168.0.0/16范围内的数据包。-j RETURN表示如果数据包匹配这条规则,则停止在当前链中的处理并返
回调用链(在这种情况下是OUTPUT链)。这通常用于排除某些不需要被处理的流量。

iptables -t mangle -A LOCAL-TP -d 172.16.0.0/12 -j RETURN
与上一条类似,但这次排除的是目标地址在172.16.0.0/12范围内的数据包。

iptables -t mangle -A LOCAL-TP -d 10.0.0.0/8 -j RETURN
这条命令排除目标地址在10.0.0.0/8范围内的数据包。

iptables -t mangle -A LOCAL-TP -d 224.0.0.0/4 -j RETURN
排除目标地址在224.0.0.0/4范围内的数据包,这通常是多播地址的范围。

iptables -t mangle -A LOCAL-TP -p tcp -j MARK --set-mark 1
对于TCP协议的数据包,如果它们没有匹配上述任何RETURN规则,则给它们打上标记(mark)1。这个标记稍
后可以用于路由决策或其他目的。

iptables -t mangle -A LOCAL-TP -p udp -j MARK --set-mark 1
与上一条类似,但这次是针对UDP协议的数据包。

iptables -t mangle -A OUTPUT -j LOCAL-TP
最后,这条命令在mangle表的OUTPUT链(负责处理从系统本地产生的数据包)中,将数据包重定向到LOCAL-TP
链进行处理。这意味着所有从系统本地产生的数据包(除了那些被上述RETURN规则排除的)都将被LOCAL-TP
链中的规则处理,并可能被打上标记1。

注意:虽然已经给数据包打上了标记,但您还需要确保有相应的路由规则或其他机制来实际使用这些标记,以便将它们发送到适当的目的地或经过特定的处理。例如,您可能需要设置策略路由规则来根据fwmark将数据包路由到特定的接口或路由表。

按照如上图所示,我已经给本机发出的数据包除去私有地址和广播地址外,打上了1的标记。但是只有标记是没有用的,还需要针对匹配上的标记进行对应的处理。

下面我们再次回顾一下iptables的数据包处理流程:

上图中是数据包处理的详细流程

上面我们在配置iptables时,自定义链LOCAL-IN关联在OUTPUT链上,那么数据包到达mangle表的OUTPUT链是如何处理的呢?

如上图所示,在数据包经过mangle的output链处理后,我们给数据包打上1的标签,那么数据包会有一次reroute-check的过程,即重路由的过程。那么我们就需要在重路由的时候对我们打标记的数据包进行对应的操作。以便使其发送至自己的2017端口。在重路由的时候会重新匹配PREROUTING链,就会匹配到我们需求1中的mark 1,重定向到127.0.0.1 2017端口,然后查路由表,将数据包标记为1的发往lo接口。

注意:

        需求1和需求2合在一起已经完成了我们的目标,但是其中有一个问题,如果我们将数据包都发送至本机的2017端口,然后本机2017端口的应用程序将数据包转发出去,那么转发出去的话如果不修改任何数据包,那么数据包发出的时候就会继续匹配到我们引用在OUTPUT链上的规则,就会再次在本地进行回环。此时就需要监听在该端口的应用程序在转发出数据包的时候给数据包重新打上标记,并且对于重新打上标记不能再次进行回环操作。比如从2017端口主动发出的数据包可以打上100的标记,那么此时防火墙就需要对打上100标记的数据包全部放行,不能再次打上标记mark1进行本地回环。

假设由本机2017发出的数据包打上的是100的标记,那么我们的防火墙规则应该增加如下条目:

图中mark 0x64是16进制,10进制就是100

此时匹配上100标记的数据包就不会再次进行重定向。

另一个问题是监听在该端口的应用程序如果和外部建立连接以后,此时,由该应用程序从连接接收到的数据返回内部主机的时候数据包也会匹配到我们PREROUTING链上的iptables规则,会打上1的标签,会导致数据包重路由再次经过iptables从而重新发送至2017端口。此时其实不需要进行路由重定向操作,即匹配上的数据包直接通过查找路由表发送发送至lo0接口即可。


iptables -t mangle -N SPLIT
-t mangle:指定要操作的表为 mangle。mangle 表主要用于修改数据包的头部信息,而不是决定数据包是否应该被允许或拒绝。
-N SPLIT:在 mangle 表中创建一个新的链(chain)名为 SPLIT。链是规则的集合,数据包按顺序与链中的规则进行匹配。

iptables -t mangle -I SPLIT -j MARK --set-mark 1
-I SPLIT:在 SPLIT 链的开头插入一个规则。
-j MARK --set-mark 1:当数据包与这条规则匹配时,使用 MARK 目标来修改数据包的 fwmark(即,标记)。在这里,它设置了数据包的 fwmark 为 1。

iptables -t mangle -A SPLIT -j ACCEPT
-A SPLIT:在 SPLIT 链的末尾追加一个规则。
-j ACCEPT:当数据包与这条规则匹配时,接受该数据包。但在这里,由于这条规则在 MARK 规则之后,并且 mangle 表通常不决定数据包的接受或拒绝。

iptables -t mangle -I PREROUTING -p tcp -m socket -j SPLIT
-I PREROUTING:在 PREROUTING 链的开头插入一个规则。
-p tcp:这条规则仅适用于 TCP 协议的数据包。
-m socket:使用 socket 匹配模块。这个模块通常用于匹配与本地套接字关联的数据包。
-j SPLIT:如果数据包与这条规则匹配,将其跳转到前面创建的 SPLIT 链进行处理。

影响:
当 TCP 数据包到达系统时,它首先会经过 mangle 表的 PREROUTING 链,并可能匹配到上面定义的规则,从而跳转到 SPLIT 链。
在 SPLIT 链中,数据包首先会被标记为 fwmark 1。

综上所述,即数据包匹配上-m socket即建立连接以后接收到的数据包打上标签1,然后通过路由表直接发送至本地lo接口。

总结:

上文我们写的iptables规则在我们前面所介绍的文章中提到的并不是很多,因为前面我们介绍的规则都是基于filter表,nat表的规则,多是网络流量过滤,网络防火墙规则,nat转换等这类。而本篇文章多为基于mangle的数据包规则修改。本篇文章更多的介绍了iptables防火墙策略的多样性,更多防火墙策略的应用需要大家更多的探索和尝试。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Monster✺◟(∗❛ัᴗ❛ั∗)◞✺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值