[Linux用户空间编程-5]:用IPTable实现NAT功能

Posted 文火冰糖的硅基工坊

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Linux用户空间编程-5]:用IPTable实现NAT功能相关的知识,希望对你有一定的参考价值。

作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的博客_文火冰糖的硅基工坊_CSDN博客

本文网址:https://blog.csdn.net/HiWangWenBing/article/details/123427800


目录

前言:

第1章 NAT功能概述

1.1 什么是NAT

1.2 为什么要进行NAT

1.3 NAT的类型

第2章 IP Table概述

2.1 IP Table概述

2.2. Iptable的链和表结构

2.3 五个链(chain)

2.4  四个表(table)

2.5 详细的数据包流程

2.5 IP Table操作命令处理流程

第3章 IP Table对Nat的支持命令

3.1 IP Table对NAT的支持概述

3.1 对规则的操作

3.3 通过命令指定具体的源地址和目的地址

3.4 通过命令指定网络接口

3.5 指定协议及端口

3.6 内核开关与编译

第4章 实际操作案例解析

4.1 源NAT(SNAT)

4.2 目的SNAT(DNAT)

第5章 综合例子

5.1 案例1:使用拨号局域网上网

5.2 案例2:ip映射

附录:NAT、DNAT和MASQUERADE进一步比较


前言:

5G DUT实现了私网IP的接入,internet服务,DUT就需要实现NAT功能,完成私网IP地址到公网IP地址的转换。

第1章 NAT功能概述

1.1 什么是NAT

在传统的标准的TCP/IP通信过程中,所有的路由器仅仅是充当一个中间人的角色,也就是通常所说的存储转发,路由器并不会对转发的数据包进行修改, 更为确切的说,除了将源MAC地址换成自己的MAC地址以外,路由器不会对转发的数据包做任何修改。

NAT(Network Address Translation网络地址翻译)恰恰是出于某种特殊需要而对数据包的源ip地址目的ip地址、源端口、目的端口进行改写的操作。

1.2 为什么要进行NAT

我们来看看再什么情况下我们需要做NAT。

假设有一家ISP提供园区Internet接入服务,为了方便管理,该ISP分配给园区用户的IP地址都是伪IP,但是部分用户要求建立自己的WWW 服务器对外发布信息,这时候我们就可以通过NAT来提供这种服务了。我们可以再防火墙的外部网卡上绑定多个合法IP地址,然后通过NAT技术使发给其中某 一个IP地址的包转发至内部某一用户的WWW服务器上,然后再将该内部WWW服务器响应包伪装成该合法IP发出的包。

再比如使用拨号上网的网吧,因为只有一个合法的IP地址,必须采用某种手段让其他机器也可以上网,通常是采用代理服务器的方式,但是代理服务器,尤其 是应用层代理服务器,只能支持有限的协议,如果过了一段时间后又有新的服务出来,则只能等待代理服务器支持该新应用的升级版本。如果采用NAT来解决这个 问题,

因为只在应用层以下进行处理,不但可以获得很高的访问速度,而且可以无缝的支持任何新的服务或应用。

还有一个方面的应用就是重定向,也就是当接收到一个包后,不是转发这个包,而是将其重定向到系统上的某一个应用程序。最常见的应用就是和squid配合使用成为透明代理,在对http流量进行缓存的同时,可以提供对Internet的无缝访问。

另一种情况就是4G/5G的DUT,需要在私网和公网之间进行转换。

1.3 NAT的类型

源NAT(SNAT)和目的NAT(DNAT),顾名思义,所谓SNAT就是改变转发数据包的源地址,所谓DNAT就是改变转发数据包的目的地址。

DNAT:Destination Network Address Translation 目标网络地址转换。 DNAT是一种改变数据包目的ip地址的技术,经常和SNAT联用,以使多台服务器能共享一个ip地址连入Internet,并且继续服务。通过对同一个ip地址分配不同的端口,来决定数据的流向。

SNAT:Source Network Address Translation源网络地址转换。这是一种改变数据包源ip地址的技术, 经常用来使多台计算机分享一个Internet地址。这只在IPv4中使用,因为IPv4的地址已快用完了,IPv6将解 决这个问题。

第2章 IP Table概述

2.1 IP Table概述

Lnux系统中,防火墙(Firewall),网址转换(NAT),数据包(package)记录,流量统计,这些功能是由Netfilter子系统所提供的,而iptables是控制Netfilter的工具.
iptables将许多复杂的规则组织成成容易控制的方式,以便管理员可以进行分组测试,或关闭、启动某组规则。

iptable能够为Unix、Linux和BSD个人工作站创建一个防火墙,也可以为一个子网创建防火墙以保护其它的系统平台。iptable只读取数据包头,不会给信息流增加负担,也无需进行验证。

2.2. Iptable的链和表结构

2.3 五个链(chain)

PREROUTING: 在数据包进入防火墙之后、路由判断之前对数据包进行修改

INPUT: 在数据包被路由到本地之后,但在用户空间程序看到它之前对数据包进行修改

OUTPUT: 用户空间程序处理数据包后,由本地发出,再次被路由之前更改数据包

FORWARD: 在最初的路由判断之后、最后一次更改包的源地址之前对数据包进行修改

POSTROUTING: 在所有路由判断之后,对数据包进行修改

注意: 链 是每个数据包流需要经过的不同环节,你可以在不同的环节根据需要设置不同的过滤策略,每个链的默认策略都是Accept

2.4  四个表(table)

Mangle表:这个表主要用来mangle包,你可以使用mangle匹配来改变包的一些属性,比如 TOS(TYPE OF SERVICE),TTL (TIME TO LIVE),MARK(后续流量控制TC等)

Nat表: 此表仅用于NAT,也就是转换包的源或目标地址。注意,就象我们前面说过的,只有流的第一个 包会被这个链匹配,其后的包会自动被做相同的处理(DNAT,SNAT,MASQUERADE)

Filter表:此表用来过滤数据包,我们可以在任何时候匹配包并过滤它们。 我们就是在这里根据包的内容对包做DROP或ACCEPT的. iptalbe中,要用 -t 参数指定要操作哪个表,如果没有 -t 参数,就默认对filter表操作.

Raw表: 优先级最高,设置raw时一般是为了不再让iptables做数据包的链接跟踪处理,提高性能

注意: 表 是规则的集合组,每个表中的规则条目是按顺序匹配的,你可以在数据包经过的不同环节设置规则,表的处理优先级:raw > mangle > nat > filter

2.5 详细的数据包流程

在上图中,NAT的功能发生在三个地方:

(1)接收到来自公网网卡的数据包:在包的预处理阶段进行目的IP地址的替换,转换后进行路由由。

(2)接收到来自本地应用程序的输出数据包:在包的输出处理模块阶段进行目的IP地址的替换

(3)发送到公网网卡上输出的数据包:在包的后处理阶段,进行源IP地址的转换,转换成本地的公网IP地址。

2.5 IP Table操作命令处理流程

在用户空间的IP table命令,会通过内核接口,操作内核的Ip_table规则表,并最终操作的是内核空间的Netfilter钩子函数。

第3章 IP Table对Nat的支持命令

3.1 IP Table对NAT的支持概述

netfilter是Linux 核心中一个通用架构,它提供了一系列的"表"(tables),每个表由若干"链"(chains)组成,而每条链中可以有一条或数条规则(rule)组 成。并且系统缺省的表是"filter"。因为系统缺省的表是"filter",所以在使用filter功能时,我们没有必要显式的指明"-t filter"。

但在使用NAT的时候,我们所使用的表不再是"filter",而是"nat"表,所以我们必须使用"-t nat"选项来显式地指明这一点。

同filter表一样,nat表也有三条缺省的"链"(chains),这三条链也是规则的容器,它们分别是:

(1)PREROUTING:可以在这里定义进行目的NAT的规则,因为路由器进行路由时只检查数据包的目的ip地址,所以为了使数据包得以正确路由,我们必须在路由之前就进行目的NAT; 

(2)POSTROUTING:可以在这里定义进行源NAT的规则,系统在决定了数据包的路由以后在执行该链中的规则。 

(3)OUTPUT:定义对本地产生的数据包的目的NAT规则。 

3.1 对规则的操作

加入(append) 一个新规则到一个链 (-A)的最后。 

在链内某个位置插入(insert) 一个新规则(-I),通常是插在最前面。 

在链内某个位置替换(replace) 一条规则 (-R)。 

在链内某个位置删除(delete) 一条规则 (-D)。 

删除(delete) 链内第一条规则 (-D)。 

3.3 通过命令指定具体源地址和目的地址

通过--source/--src/-s来指定源地址(这里的/表示或者的意思,下同),通过--destination/--dst/-s来指定目的地址。可以使用以下四种方法来指定ip地址:

使用完整的域名,如“www.linuxaid.com.cn”; 

使用ip地址,如“192.168.1.1”; 

用x.x.x.x/x.x.x.x指定一个网络地址,如“192.168.1.0/255.255.255.0”; 

用x.x.x.x/x指定一个网络地址,如“192.168.1.0/24”这里的24表明了子网掩码的有效位数,这是UNIX环境中通常使用的表示方法。缺省的子网掩码数是32,也就是说指定192.168.1.1等效于192.168.1.1/32。 

3.4 通过命令指定网络接口

可以使用--in-interface/-i或--out-interface/-o来指定网络接口。

从NAT的原理可以看出,对于 PREROUTING链,需要修正目的IP地址,因此,通常情况下,我们用-i指定公网IP接口然后把目的IP地址转换成内部的私网IP地址+端口号。

而对于POSTROUTING和OUTPUT我们只能用-o指定出去的网络接口,POSTROUTING是源IP地址,因此通常用于输出到公网前,进行源地址的替换。

3.5 指定协议及端口

可以通过--protocol/-p选项来指定协议,如果是udp和tcp协议,还可--source-port/--sport和 --destination-port/--dport来指明端口。

3.6 内核开关与编译

(1)编译

Linux内核对Nat的支持,是需要打开内核选项的。

编译内核,编译时选中以下选项:
Full NAT
 MASQUERADE target support
 REDIRECT target support

(2)加载ko

要使用NAT表时,必须首先载入相关模块:

modprobe ip_tables

modprobe ip_nat_ftp

iptable_nat 模块会在运行时自动载入。

第4章 实际操作案例解析

需要注意的时,大多数情况下,

私网到公网的源地址转换是多对1.

而公网到私网的转换是1对多

因此,NAT的转换是基于端口的转换,NAT内部需要维护一个私网IP地址和端口号的对应关系的表。

4.1 源NAT(SNAT)

比如,更改所有来自192.168.1.0/24的数据包的源ip地址为1.2.3.4:
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to 1.2.3.4

这里需要注意的是,系统在路由及过虑等处理直到数据包要被送出时才进行SNAT。

有一种SNAT的特殊情况是ip欺骗,也就是所谓的Masquerading,通常建议在使用拨号上网的时候使用,或者说在合法ip地址不固定的情况下使用。比如
# iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE

可以看出,这时候我们没有必要显式的指定源ip地址等信息。

4.2 目的SNAT(DNAT)

比如,更改所有来自192.168.1.0/24的数据包的目的ip地址为1.2.3.4:
iptables -t nat -A PREROUTING -s 192.168.1.0/24 -i eth1 -j DNAT --to 1.2.3.4

这里需要注意的是,系统是先进行DNAT,然后才进行路由及过虑等操作。

有一种DNAT的特殊情况是重定向,也就是所谓的Redirection,这时候就相当于将符合条件的数据包的目的ip地址改为数据包进入系统时的网 络接口的ip地址。通常是在与squid配置形成透明代理时使用,假设squid的监听端口是3128,我们可以通过以下语句来将来自 192.168.1.0/24,目的端口为80的数据包重定向到squid监听端口:
iptables -t nat -A PREROUTING -i eth1 -p tcp -s 192.168.1.0/24 --dport 80 -j REDIRECT --to-port 3128

第5章 综合例子

5.1 案例1:使用拨号局域网上网

小型企业、网吧等多使用拨号网络上网,通常可能使用代理,但是考虑到成本、对协议的支持等因素,建议使用ip欺骗方式带动区域网上网。

成功升级内核后安装iptables,然后执行以下脚本:

#载入相关模块
modprobe ip_tables
modprobe ip_nat_ftp
#进行ip伪装
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE

5.2 案例2:ip映射

假设有一家ISP提供园区Internet接入服务,为了方便管理,该ISP分配给园区用户的IP地址都是伪IP,但是部分用户要求建立自己的WWW 服务器对外发布信息。我们可以再防火墙的外部网卡上绑定多个合法IP地址,然后通过ip映射使发给其中某一个IP地址的包转发至内部某一用户的WWW服务 器上,然后再将该内部WWW服务器响应包伪装成该合法IP发出的包。

我们假设以下情景:

该ISP分配给A单位www服务器的ip为:

伪ip:192.168.1.100

真实ip:202.110.123.100


该ISP分配给B单位www服务器的ip为:

伪ip:192.168.1.200

真实ip:202.110.123.200


linux防火墙的ip地址分别为:

内网接口eth1:192.168.1.1

外网接口eth0:202.110.123.1

然后我们将分配给A、B单位的真实ip绑定到防火墙的外网接口,以root权限执行以下命令:

ifconfig eth0 add 202.110.123.100 netmask 255.255.255.0
ifconfig eth0 add 202.110.123.200 netmask 255.255.255.0

成功升级内核后安装iptables,然后执行以下脚本:

#载入相关模块
modprobe ip_tables
modprobe ip_nat_ftp

首先,对防火墙接收到的目的ip为202.110.123.100和202.110.123.200的所有数据包进行目的NAT(DNAT):

iptables -A PREROUTING -i eth0 -d 202.110.123.100 -j DNAT --to 192.168.1.100
iptables -A PREROUTING -i eth0 -d 202.110.123.200 -j DNAT --to 192.168.1.200

其次,对防火墙接收到的源ip地址为192.168.1.100和192.168.1.200的数据包进行源NAT(SNAT):

iptables -A POSTROUTING -o eth0 -s 192.168.1.100 -j SNAT --to 202.110.123.100
iptables -A POSTROUTING -o eth0 -s 192.168.1.200 -j SNAT --to 202.110.123.200

这样,所有目的ip为202.110.123.100和202.110.123.200的数据包都将分别被转发给192.168.1.100和 192.168.1.200;而所有来自192.168.1.100和192.168.1.200的数据包都将分别被伪装成由 202.110.123.100和202.110.123.200,从而也就实现了ip映射.

附录:NAT、DNAT和MASQUERADE进一步比较

IP Tables中可以灵活的做各种网络地址转换(NAT),网络地址转换主要有两种:SNAT和DNAT。

SNAT是source networkaddress translation的缩写,即源地址目标转换。比如,多个PC机使用ADSL路由器共享上网,每个PC机都配置了内网IP。

PC机访问外部网络的时候,路由器将数据包的报头中的源地址替换成路由器的ip,当外部网络的服务器比如网站web服务器接到访问请求的时候,他的日志记录下来的是路由器的ip地址,而不是pc机的内网ip,这是因为,这个服务器收到的数据包的报头里边的“源地址”,已经被替换了,所以叫做SNAT,基于源地址的地址转换。

DNAT是destination networkaddress translation的缩写,即目标网络地址转换,典型的应用是,有个web服务器放在内网配置内网ip,前端有个防火墙配置公网ip,互联网上的访问者使用公网ip来访问这个网站,当访问的时候,客户端发出一个数据包,这个数据包的报头里边,目标地址写的是防火墙的公网ip,防火墙会把这个数据包的报头改写一次,将目标地址改写成web服务器的内网ip,然后再把这个数据包发送到内网的web服务器上,这样,数据包就穿透了防火墙,并从公网ip变成了一个对内网地址的访问了,即DNAT,基于目标的网络地址转换。

MASQUERADE,地址伪装,算是snat中的一种特例,可以实现自动化的snat。

在iptables中有着和SNAT相近的效果,但也有一些区别,但使用SNAT的时候,出口ip的地址范围可以是一个,也可以是多个,例如:

如下命令表示把所有10.8.0.0网段的数据包SNAT成192.168.5.3的ip然后发出去,

iptables-t nat -A POSTROUTING -s 10.8.0.0/255.255.255.0 -o eth0 -j SNAT --to-source192.168.5.3

如下命令表示把所有10.8.0.0网段的数据包SNAT成192.168.5.3/192.168.5.4/192.168.5.5等几个ip然后发出去

iptables-t nat -A POSTROUTING -s 10.8.0.0/255.255.255.0 -o eth0 -j SNAT --to-source192.168.5.3-192.168.5.5

这就是SNAT的使用方法,即可以NAT成一个地址,也可以NAT成多个地址,但是,对于SNAT,不管是几个地址,必须明确的指定要SNAT的ip,假如当前系统用的是ADSL动态拨号方式,那么每次拨号,出口ip192.168.5.3都会改变,而且改变的幅度很大,不一定是192.168.5.3到192.168.5.5范围内的地址,这个时候如果按照现在的方式来配置iptables就会出现问题了,因为每次拨号后,服务器地址都会变化,而iptables规则内的ip是不会随着自动变化的,每次地址变化后都必须手工修改一次iptables,把规则里边的固定ip改成新的ip,这样是非常不好用的。

MASQUERADE:就是针对这种场景而设计的,他的作用是,从服务器的网卡上,自动获取当前ip地址来做NAT。

比如下边的命令:

iptables-t nat -A POSTROUTING -s 10.8.0.0/255.255.255.0 -o eth0 -j MASQUERADE

如此配置的话,不用指定SNAT的目标ip了,不管现在eth0的出口获得了怎样的动态ipMASQUERADE会自动读取eth0现在的ip地址然后做SNAT出去,这样就实现了很好的动态SNAT地址转换。


作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的博客_文火冰糖的硅基工坊_CSDN博客

本文网址:https://blog.csdn.net/HiWangWenBing/article/details/123427800

以上是关于[Linux用户空间编程-5]:用IPTable实现NAT功能的主要内容,如果未能解决你的问题,请参考以下文章

Linux网络基础设定selinux/iptable/firewall

#私藏项目实操分享# 使用iptable实现: 放行telnet, ftp, web服务,放行samba服务,其他端口服务全部拒绝

#私藏项目实操分享# 使用iptable实现: 放行telnet, ftp, web服务,放行samba服务,其他端口服务全部拒绝

Linux进程5——实模式和保护模式

[Linux用户空间编程-3]:Linux定时机制的几种实现方法

linux用户空间 - 多进程编程(三)