IPTABLES端口转发

2022-06-23 15:54:37 浏览数 (1)

文章前言

iptables是unix/linux系统自带的优秀且完全免费的基于包过滤的防火墙工具,它的功能十分强大、使用非常灵活、可以对流入、流出及流经服务器的数据包进行精细的控制,作为防火墙其端口转发功能自然是必不可少的,但是需要高的操作权限

基础知识
Tables

iptables包含5张表(tables):

  • raw:用于配置数据包,raw中的数据包不会被系统跟踪
  • filter:是用于存放所有与防火墙相关操作的默认表
  • nat:用于网络地址转换,例如:端口转发
  • mangle:用于对特定数据包的修改,例如:损坏数据包
  • security:用于强制访问控制网络规则,例如:SELinux
Chains

表由链组成,链是一些按顺序排列的规则的列表,默认的filter表包含INPUT、OUTPUT、FORWARD共计3条内建的链,这3条链作用于数据包过滤过程中的不同时间点,具体如下方流程图所示:

默认情况下,任何链中都没有规则,用户可以向链中添加自己想用的规则,链的默认规则通常设置为ACCEPT,如果想确保任何包都不能通过规则集,那么可以重置为DROP,默认的规则总是在一条链的最后生效,所以在默认规则生效前数据包需要通过所有存在的规则,用户可以加入自己定义的链,从而使规则集更有效并且易于修改

Rules

数据包的过滤基于规则,规则由一个目标(数据包匹配所有条件后的动作)和很多匹配(导致该规则可以应用的数据包所满足的条件)指定,一个规则的典型匹配事项是数据包进入的端口(例如:eth0或者eth1)、数据包的类型(ICMP, TCP, 或者UDP)和数据包的目的端口。

目标使用-j或者--jump选项指定,目标可以是用户定义的链(例如,如果条件匹配,则跳转到用户定义的链之后继续处理)、内置的特定目标或者是一个目标扩展,内置目标是ACCEPT、DROP、QUEUE和RETURN,目标扩展是REJECT and LOG,如果目标是内置目标,数据包的命运会立刻被决定,并且在当前表的数据包的处理过程会停止,如果目标是用户定义的链,并且数据包成功穿过第二条链,目标将移动到原始链中的下一个规则,目标扩展可以被终止(像内置目标一样)或者不终止(像用户定义链一样)

Modules

有许多模块可以用来扩展iptables,例如connlimit, conntrack, limit和recent,这些模块增添了很多功能,可以进行更复杂的过滤

Traversing Chains

位于上方的流程图描述了在任何接口上收到的网络数据包是按照怎样的顺序穿过表的交通管制链的,第一个路由策略包括决定数据包的目的地是本地主机(数据包穿过INPUT链),还是其他主机(数据包穿过FORWARD链),中间的路由策略包括决定给传出的数据包使用那个源地址、分配哪个接口,最后一个路由策略存在是因为先前的mangle与nat链可能会改变数据包的路由信息,数据包通过路径上的每一条链时,链中的每一条规则按顺序匹配,无论何时匹配了一条规则,相应的target/jump动作将会执行,最常用的3个target是ACCEPT、DROP、JUMP到用户自定义的链,内置的链有默认的策略,但是用户自定义的链没有默认的策略,在JUMP,若每一条规则都不能提供完全匹配,那么数据包像这张图片描述的一样返回到调用链,在任何时候,若DROP TARGET的规则实现完全匹配,那么被匹配的数据包会被丢弃,不会进行进一步处理,如果一个数据包在链中被ACCEPT,那么它也会被所有的父链ACCEPT,并且不再遍历其他父链,需要注意的是,数据包还会以正常的方式继续遍历其他表中的其他链

工作原理

下图简要描述了网络数据包通过iptables的过程:

端口转发
前期配置

修改配置文件,使iptables允许ipv4转发:

代码语言:javascript复制
vim /etc/sysctl.conf     #可以直接进文件修改
net.ipv4.ip_forward = 1   #开启ipv4 forward

也可以用这条命令直接修改

代码语言:javascript复制
sysctl -w net.ipv4.ip_forward=1

查看修改结果

代码语言:javascript复制
sysctl -p

规则说明

端口转发功能主要是用nat表中的三个链实现该功能:

代码语言:javascript复制
-t 指定配置表
-A 链中添加规则
-D 删除链中规则
-C 修改链中规则
-j target 决定符合条件的包到何处去,target模式很多
本地转发

REDIRECT模式可以将防火墙所在机子内部数据流量包转发到本地的另一个端口,它只能用在nat表的PREROUTING、OUTPUT链 ,并且通过--to-ports选项来指定转发到本地的那个端口号,例如:--to-ports 8080,当然也可以指定为一个范围,例如:--to-ports 8080-8090

Case 1:下面我们通过PREROUTING链,将外网访问4444端口的数据流量全部转发到本机22端口(注意:本机访问4444并不进行转发),这种方法适用于当我们的目标主机不允许外部访问特定的端口时我们可以通过端口转发实现对其访问

代码语言:javascript复制
iptables -t nat -A PREROUTING -p tcp --dport 4444 -j REDIRECT --to-ports 22

之后攻击者远程连接目标主机的4444端口的流量会被转发到22端口,实现对目标主机SSH服务的连接:

Case 2:我们也可以通过OUTPUT链,将本地访问4444端口的数据流量全部转发到本机22端口

代码语言:javascript复制
iptables -t nat -A OUTPUT -p tcp --dport 4444 -j REDIRECT --to-ports 22

之后再本地访问4444端口,可以成功连接到本地SSH服务:

远程转发

DNAT模式是用来做目的网络地址转换,它也可以做某种类型地负载平衡,只能用在nat表的PREROUTING和OUTPUT链,并且通过--to-destination选项指定要写入的IP头的地址,其参数可以是一个IP范围,例如: --to-destination 192.168.10.141-192.168.10.151

SNAT模式用来做源网络地址转换的,就是重写包的源IP地址,如果直接转发包的话,网络响应包上就不知道往哪儿发送应答,所以需要改为防火墙的地址,只能用在nat表的POSTROUTING链,且有一个--to-source选项,它可以是一个单独的地址也可以是一段连续的地址,例如:194.236.50.155-194.236.50.160,在指定-p tcp或-p udp的前提下,可以指定源端口的范围,例如:194.236.50.155:1024-32000

当前场景:

  • A主机:192.168.174.1
  • B主机:192.168.174.129
  • C主机:192.168.174.131

场景要求:

通过将B主机作为中间媒介,攻击者通过A主机访问B主机的4444端口实现对目标主机C的22号端口的访问

具体实现:

Step 1:通过PREROUTING链,将A访问B的4444端口的包,转发到C的22端口

代码语言:javascript复制
iptables -t nat -A PREROUTING --dst 192.168.174.129 -p tcp --dport 4444 -j DNAT --to-destination 192.168.174.131:22

Step 2:通过POSTROUTING链,修改请求包的源IP,为B主机IP

代码语言:javascript复制
iptables -t nat -A POSTROUTING --dst 192.168.174.131 -p tcp --dport 22 -j SNAT --to-source 192.168.174.129 

Step 3:A主机访问B的4444端口,此时C主机的22端口收到包,并显示是B发来的请求,但包里的Host并没有改变

分流机制

当前场景:

  • A主机:192.168.174.1
  • B主机:192.168.174.129
  • C主机:192.168.174.131

场景要求:

A主机访问B的4444端口转发到C主机的22端口,D主机访问则不进行转发(只对192.168.174.1来源IP有效,其他IP访问完全正常)

具体实现:

Step 1:通过PREROUTING链,将源为192.168.174.1访问B的4444端口的包,转发到C的22端口,其他的不管

代码语言:javascript复制
iptables -t nat -A PREROUTING --source 192.168.174.1 -p tcp --dport 4444 -j DNAT --to-destination 192.168.174.131:22

Step 2:MASQUERADE模式和SNAT模式作用一样,区别就是它不需要指定--to-source ,而是动态获取IP地址的连接的,比如:拨号上网、DHCP连接时我们IP是会变的,只能用于nat表的POSTROUTING链 ,有一个非必须--to-ports选项

代码语言:javascript复制
iptables -t nat -A POSTROUTING -p TCP -j MASQUERADE
iptables -t nat -A POSTROUTING --dst 192.168.174.131 -p tcp --dport 22 -j MASQUERADE

Step 3:使用攻击主机A链接B主机的4444端口发现成功转发

Step 4:使用其他主机连接,发现无法成功连接到目标主机C的22端口

删除规则

查询列表后,-D删除指定表的指定链上num的规则

代码语言:javascript复制
iptables -t nat -nL --line
iptables -t nat -D PREROUTING 1
iptables -t nat -D OUTPUT 1

参考链接

https://blog.csdn.net/zzchances/article/details/124062478

https://mp.weixin.qq.com/s/QOfORsSIcxuRXFj1xkUFcA

https://wiki.archlinux.org/title/iptables_(简体中文)

0 人点赞