本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名原文链接~~~

iptables(4)之网络地址转换

微信搜索 zze_coding 或扫描 👉 二维码关注我的微信公众号获取更多资源推送:


NAT 概述

NAT(Network Address Translation,网络地址转换)是 1994 年提出的。当在专用网内部的一些主机本来已经分配到了本地 IP 地址(即仅在本专用网内使用的专用地址),但现在又想和因特网上的主机通信(并不需要加密)时,可使用 NAT 方法。

这种方法需要在专用网连接到因特网的路由器上安装 NAT 软件。装有 NAT 软件的路由器叫做 NAT 路由器,它至少有一个有效的外部全球 IP 地址。这样,所有使用本地地址的主机在和外界通信时,都要在 NAT 路由器上将其本地地址转换成全球 IP 地址,才能和因特网连接。

另外,这种通过使用少量的公有 IP 地址代表较多的私有 IP 地址的方式,将有助于减缓可用的 IP 地址空间的枯竭。在 RFC 2663 中有对 NAT 的说明。

功能

NAT 不仅能解决 IP 地址不足的问题,而且还能够有效地避免来自网络外部的攻击,隐藏并保护网络内部的计算机。

  1. 宽带分享:这是 NAT 主机的最大功能。
  2. 安全防护:NAT 之内的 PC 联机到 Internet 上面时,他所显示的 IP 是 NAT 主机的公共 IP,所以 Client 端的 PC 当然就具有一定程度的安全了,外界在进行 portscan(端口扫描) 的时候,就侦测不到源 Client 端的 PC 。

实现方式

NAT 的实现方式有三种,即静态转换 Static Nat、动态转换 Dynamic Nat 和端口多路复用 OverLoad。

静态转换是指将内部网络的私有 IP 地址转换为公有 IP 地址,IP 地址对是一对一的,是一成不变的,某个私有 IP 地址只转换为某个公有 IP 地址。借助于静态转换,可以实现外部网络对内部网络中某些特定设备(如服务器)的访问。

动态转换是指将内部网络的私有 IP 地址转换为公用 IP 地址时,IP 地址是不确定的,是随机的,所有被授权访问上 Internet 的私有 IP 地址可随机转换为任何指定的合法 IP 地址。也就是说,只要指定哪些内部地址可以进行转换,以及用哪些合法地址作为外部地址时,就可以进行动态转换。动态转换可以使用多个合法外部地址集。当 ISP 提供的合法 IP 地址略少于网络内部的计算机数量时。可以采用动态转换的方式。

端口多路复用(Port address Translation,PAT)是指改变外出数据包的源端口并进行端口转换,即端口地址转换(PAT,Port Address Translation).采用端口多路复用方式。内部网络的所有主机均可共享一个合法外部 IP 地址实现对 Internet 的访问,从而可以最大限度地节约 IP 地址资源。同时,又可隐藏网络内部的所有主机,有效避免来自 Internet 的攻击。因此,目前网络中应用最多的就是端口多路复用方式。

ALG(Application Level Gateway),即应用程序级网关技术:传统的 NAT 技术只对 IP 层和传输层头部进行转换处理,但是一些应用层协议,在协议数据报文中包含了地址信息。为了使得这些应用也能透明地完成 NAT 转换,NAT 使用一种称作 ALG 的技术,它能对这些应用程序在通信时所包含的地址信息也进行相应的 NAT 转换。例如:对于 FTP 协议的 PORT/PASV 命令、DNS 协议的 "A" 和 "PTR" queries 命令和部分 ICMP 消息类型等都需要相应的ALG来支持。

如果协议数据报文中不包含地址信息,则很容易利用传统的 NAT 技术来完成透明的地址转换功能,通常我们使用的如下应用就可以直接利用传统的 NAT 技术:HTTP、TELNET、FINGER、NTP、NFS、ARCHIE、RLOGIN、RSH、RCP 等。

技术背景

要真正了解 NAT 就必须先了解现在 IP 地址的使用情况,私有 IP 地址是指内部网络或主机的 IP 地址,公有 IP 地址是指在因特网上全球唯一的 IP 地址。RFC 1918 为私有网络预留出了三个 IP 地址块,如下:

  • A 类:10.0.0.0 ~ 10.255.255.255
  • B 类:172.16.0.0 ~ 172.31.255.255
  • C 类:192.168.0.0 ~ 192.168.255.255

上述三个范围内的地址不会在因特网上被分配,因此可以不必向 ISP 或注册中心申请而在公司或企业内部自由使用。
随着接入 Internet 的计算机数量的不断猛增,IP 地址资源也就愈加显得捉襟见肘。事实上,除了中国教育和科研计算机网(CERNET)外,一般用户几乎申请不到整段的 C 类 IP 地址。在其他 ISP 那里,即使是拥有几百台计算机的大型局域网用户,当他们申请 IP 地址时,所分配的地址也不过只有几个或十几个 IP 地址。显然,这样少的 IP 地址根本无法满足网络用户的需求,于是也就产生了 NAT 技术。
虽然 NAT 可以借助于某些代理服务器来实现,但考虑到运算成本和网络性能,很多时候都是在路由器上来实现的。

NAPT 网络地址端口转换

NAPT(Network Address Port Translation),即网络地址端口转换,可将多个内部地址映射为一个合法公网地址,但以不同的协议端口号与不同的内部地址相对应,也就是 <内部地址+内部端口><外部地址+外部端口> 之间的转换。NAPT 普遍用于接入设备中,它可以将中小型的网络隐藏在一个合法的 IP 地址后面。NAPT 也被称为“多对一”的 NAT,或者叫 PAT(Port Address Translations,端口地址转换)、地址超载(address overloading)。
NAPT 与动态地址 NAT 不同,它将内部连接映射到外部网络中的一个单独的 IP地址上,同时在该地址上加上一个由 NAT 设备选定的 TCP 端口号。NAPT 算得上是一种较流行的 NAT 变体,通过转换 TCP 或 UDP 协议端口号以及地址来提供并发性。除了一对源和目的 IP 地址以外,这个表还包括一对源和目的协议端口号,以及 NAT 盒使用的一个协议端口号。
NAPT 的主要优势在于,能够使用一个全球有效 IP 地址获得通用性。主要缺点在于其通信仅限于 TCP 或 UDP。当所有通信都采用 TCP 或 UDP,NAPT 允许一台内部计算机访问多台外部计算机,并允许多台内部主机访问同一台外部计算机,相互之间不会发生冲突。

工作原理

借助于 NAT,私有(保留)地址的“内部”网络通过路由器发送数据包时,私有地址被转换成合法的 IP 地址,一个局域网只需使用少量 IP 地址(甚至是1个)即可实现私有地址网络内所有计算机与 Internet 的通信需求。
NAT 将自动修改 IP 报文的源 IP 地址和目的 IP 地址,IP 地址校验则在 NAT 处理过程中自动完成。有些应用程序将源 IP 地址嵌入到 IP 报文的数据部分中,所以还需要同时对报文的数据部分进行修改,以匹配 IP 头中已经修改过的源 IP 地址。否则,在报文数据部分嵌入IP地址的应用程序就不能正常工作。

image.png

上图中,1、2、3 为 Clenit 向 Internet 发起请求的过程,4、5、6 为 Internet 响应客户端的过程。
其中:

  • 2 完成了客户端请求报文的源地址转换(SNAT,172.16.1.202 -> 10.0.1.200);
  • 5 完成了 Internet 响应报文的的目标地址转换(DNAT,10.0.1.200 > 172.16.1.202);

如上图这个 Client(终端) 的 Gateway (网关)设定为 NAT Server,所以当要连上 Internet 的时候,该封包就会被送到 NAT 主机,这个时候的封包 Header 之 Source IP(源 IP) 为 172.16.1.202

而透过这个 NAT Server,它会将 Client 的对外联机封包的 Source IP (172.16.1.202) 伪装成 NAT Server 所具有的公共 IP(10.0.1.200),因为是公共 IP 了,所以这个封包就可以连上 Internet 了,同时 NAT 主机并且会记忆这个联机的封包是由哪一个(172.16.1.202)Client 端传送来的;

由 Internet 传送回来的封包,当然由 NAT 主机来接收了,这个时候, NAT 主机会去查询原本记录的路由信息,并将目标 IP 由 NAT Server 上面的公共 IP(10.0.1.200)改回原来的 172.16.1.202

最后则由 NAT 主机将该封包传送给原先发送封包的 Client。

环境准备

image.png

我们要准备如上三台主机,并且要在 NAT Server 上开启核心转发功能,最后 Client 和 Internet Server 能够相互 ping 同即可,可参考【iptables(3)之配置网络防火墙——环境准备】。

为便于后续测试,我们还需要在 InternetServer、NAT Server、Client 中安装上 httpd 和 tcpdump:

$ yum install -y httpd tcpdump

修改 InternetServer 中 httpd 首页内容如下:

$ cat /var/www/html/index.html 
in Internet Server - 10.0.1.201

修改 NAT Server 中 httpd 首页内容如下:

$ cat /var/www/html/index.html 
in NAT Server  - 10.0.1.200/172.16.1.200

修改 Client 中的 httpd 首页内容如下:

$ cat /var/www/html/index.html 
in Client - 172.16.1.202

在 Client 中测试访问 InternetServer 中的 Web 服务:

$ curl 10.0.1.201
in InternetServer - 10.0.1.201

在 InternetServer 中测试访问 Client:

$ curl 172.16.1.202
in Client - 172.16.1.202

测试

在测试网络地址转换之前,我们先看一下未转换之前的情况是咋样的。
以 Client 访问 Internet Server 为例,客户端访问 10.0.1.0/24 网络时,网关为 NAT Server 的 172.16.1.200,经过 NAT Server 的核心转发功能到达 Internet Server,期间数据包地址未做修改,所以在 Internet Server 中接收到的请求的源地址应该就是 Client 的地址(172.16.1.202),目标地址则是 Internet Server 本机(10.0.1.201)。
下面使用通过在 Internet Server 上抓包验证一下,监听 Internet Server 的 tcp/80 端口:

$ tcpdump tcp port 80 -nn

在 Client 访问 Internet Server 的 Web 服务:

$ curl 10.0.1.201

查看 Internet Server 中的 tcpdump 监控输出:

13:53:36.692347 IP 172.16.1.202.40144 > 10.0.1.201.80: Flags [S], seq 2420639302, win 29200, options [mss 1460,sackOK,TS val 1627158 ecr 0,nop,wscale 7], length 0
13:53:36.692367 IP 10.0.1.201.80 > 172.16.1.202.40144: Flags [S.], seq 2133565126, ack 2420639303, win 14480, options [mss 1460,sackOK,TS val 1627719 ecr 1627158,nop,wscale 6], length 0
13:53:36.692853 IP 172.16.1.202.40144 > 10.0.1.201.80: Flags [.], ack 1, win 229, options [nop,nop,TS val 1627159 ecr 1627719], length 0
13:53:36.692860 IP 172.16.1.202.40144 > 10.0.1.201.80: Flags [P.], seq 1:75, ack 1, win 229, options [nop,nop,TS val 1627159 ecr 1627719], length 74
13:53:36.692871 IP 10.0.1.201.80 > 172.16.1.202.40144: Flags [.], ack 75, win 227, options [nop,nop,TS val 1627720 ecr 1627159], length 0
13:53:36.693340 IP 10.0.1.201.80 > 172.16.1.202.40144: Flags [P.], seq 1:299, ack 75, win 227, options [nop,nop,TS val 1627720 ecr 1627159], length 298
13:53:36.693503 IP 10.0.1.201.80 > 172.16.1.202.40144: Flags [F.], seq 299, ack 75, win 227, options [nop,nop,TS val 1627721 ecr 1627159], length 0
13:53:36.693737 IP 172.16.1.202.40144 > 10.0.1.201.80: Flags [.], ack 299, win 237, options [nop,nop,TS val 1627160 ecr 1627720], length 0
13:53:36.693911 IP 172.16.1.202.40144 > 10.0.1.201.80: Flags [F.], seq 75, ack 300, win 237, options [nop,nop,TS val 1627160 ecr 1627721], length 0
13:53:36.693920 IP 10.0.1.201.80 > 172.16.1.202.40144: Flags [.], ack 76, win 227, options [nop,nop,TS val 1627721 ecr 1627160], length 0

可以看到和我们的推测一样,没毛病~

源地址转换

静态源地址转换(SNAT)

这里“静态源地址转换”的意思是我们明确知道要转换为的地址。

下面在 NAT Server 中使用一下 iptables 的网络地址转发功能,以将源地址为 172.16.1.202、目标地址为 10.0.1.201 的报文的源地址修改为 NAT Server 的 10.0.1.200 为例:

$ iptables -t nat -A POSTROUTING -s 172.16.1.202 -d 10.0.1.201 -p tcp -j SNAT --to-source 10.0.1.200

再次使用 Client 访问 Internet Server 的 Web 服务,查看 Internet Server 中 tcpdump 监控的输出:

16:51:54.188625 IP 10.0.1.200.40148 > 10.0.1.201.80: Flags [S], seq 684765548, win 29200, options [mss 1460,sackOK,TS val 12324680 ecr 0,nop,wscale 7], length 0
16:51:54.188647 IP 10.0.1.201.80 > 10.0.1.200.40148: Flags [S.], seq 13587547, ack 684765549, win 14480, options [mss 1460,sackOK,TS val 12325216 ecr 12324680,nop,wscale 6], length 0
16:51:54.189214 IP 10.0.1.200.40148 > 10.0.1.201.80: Flags [.], ack 1, win 229, options [nop,nop,TS val 12324681 ecr 12325216], length 0
16:51:54.189223 IP 10.0.1.200.40148 > 10.0.1.201.80: Flags [P.], seq 1:75, ack 1, win 229, options [nop,nop,TS val 12324681 ecr 12325216], length 74
16:51:54.189238 IP 10.0.1.201.80 > 10.0.1.200.40148: Flags [.], ack 75, win 227, options [nop,nop,TS val 12325216 ecr 12324681], length 0
16:51:54.189792 IP 10.0.1.201.80 > 10.0.1.200.40148: Flags [P.], seq 1:299, ack 75, win 227, options [nop,nop,TS val 12325217 ecr 12324681], length 298
16:51:54.189931 IP 10.0.1.201.80 > 10.0.1.200.40148: Flags [F.], seq 299, ack 75, win 227, options [nop,nop,TS val 12325217 ecr 12324681], length 0
16:51:54.190132 IP 10.0.1.200.40148 > 10.0.1.201.80: Flags [.], ack 299, win 237, options [nop,nop,TS val 12324682 ecr 12325217], length 0
16:51:54.190434 IP 10.0.1.200.40148 > 10.0.1.201.80: Flags [F.], seq 75, ack 299, win 237, options [nop,nop,TS val 12324682 ecr 12325217], length 0
16:51:54.190441 IP 10.0.1.201.80 > 10.0.1.200.40148: Flags [.], ack 76, win 227, options [nop,nop,TS val 12325218 ecr 12324682], length 0
16:51:54.190480 IP 10.0.1.200.40148 > 10.0.1.201.80: Flags [.], ack 300, win 237, options [nop,nop,TS val 12324682 ecr 12325217], length 0

可以看到,这里对于 Internet Server 来说,来访问它的 Web 服务的主机就是 NAT Server(10.0.1.200)了,所以它的响应也是先给 NAT Server 主机,然后由 NAT Server 做目标地址转换将报文给到初始请求的 Client 主机(172.16.1.202)。

动态源地址转换(MASQUERADE)

还有一种情况,就是我们的 NAT Server 上的外网 IP 可能是动态分配的,所以我们指定转换的网络地址时就不能固定写死为 10.0.1.200 了,这个时候我们可以使用 MASQUERADE 动作了。

我们先清空一下上面测试静态源地址转换的规则:

$ iptables -t nat -F

这里以让源地址为 172.16.1.202 网络、目标地址为 10.0.1.0/24 网络的报文的源地址自动修改为可与 10.0.1.0/24 通信的地址为例,在 NAT Server 中添加如下规则:

$ iptables -t nat -A POSTROUTING -s 172.16.1.202 -d 10.0.1.0/24 -p tcp -j MASQUERADE

使用 Client 访问 Internet Server 的 Web 服务,查看 Internet Server 中 tcpdump 监控的输出:

17:39:48.806073 IP 10.0.1.200.40152 > 10.0.1.201.80: Flags [S], seq 586257372, win 29200, options [mss 1460,sackOK,TS val 15199323 ecr 0,nop,wscale 7], length 0
17:39:48.806091 IP 10.0.1.201.80 > 10.0.1.200.40152: Flags [S.], seq 2238246948, ack 586257373, win 14480, options [mss 1460,sackOK,TS val 15199833 ecr 15199323,nop,wscale 6], length 0
17:39:48.806620 IP 10.0.1.200.40152 > 10.0.1.201.80: Flags [.], ack 1, win 229, options [nop,nop,TS val 15199324 ecr 15199833], length 0
17:39:48.806682 IP 10.0.1.200.40152 > 10.0.1.201.80: Flags [P.], seq 1:75, ack 1, win 229, options [nop,nop,TS val 15199324 ecr 15199833], length 74
17:39:48.806696 IP 10.0.1.201.80 > 10.0.1.200.40152: Flags [.], ack 75, win 227, options [nop,nop,TS val 15199834 ecr 15199324], length 0
17:39:48.807228 IP 10.0.1.201.80 > 10.0.1.200.40152: Flags [P.], seq 1:299, ack 75, win 227, options [nop,nop,TS val 15199834 ecr 15199324], length 298
17:39:48.807381 IP 10.0.1.201.80 > 10.0.1.200.40152: Flags [F.], seq 299, ack 75, win 227, options [nop,nop,TS val 15199834 ecr 15199324], length 0
17:39:48.807656 IP 10.0.1.200.40152 > 10.0.1.201.80: Flags [.], ack 299, win 237, options [nop,nop,TS val 15199325 ecr 15199834], length 0
17:39:48.807826 IP 10.0.1.200.40152 > 10.0.1.201.80: Flags [F.], seq 75, ack 299, win 237, options [nop,nop,TS val 15199325 ecr 15199834], length 0
17:39:48.807833 IP 10.0.1.201.80 > 10.0.1.200.40152: Flags [.], ack 76, win 227, options [nop,nop,TS val 15199835 ecr 15199325], length 0
17:39:48.807875 IP 10.0.1.200.40152 > 10.0.1.201.80: Flags [.], ack 300, win 237, options [nop,nop,TS val 15199325 ecr 15199834], length 0

可以看到,即便我们没有在 NAT Server 指定与 10.0.1.0/24 网络通信要使用的地址,MASQUERADE 策略也可以自动感知到 NAT Server 中可与 10.0.1.0/24 通信的地址只有 10.0.1.200,随之将请求报文中的源地址(172.16.1.202)也设为了 10.0.1.200

目标地址转换(DNAT)

目标地址转换可以实现隐藏内部主机的效果,这里我们依旧先清空一下 NAT Server 上之前的规则:

$ iptables -t nat -F

这里我们先将 Client 的 Web 服务监听的端口修改为 8088 并重启服务:

$ sed -i 's/^Listen 80/Listen 8088/g' /etc/httpd/conf/httpd.conf 
$ systemctl restart httpd

以让 Internet Server 访问 NAT Server 的 80 端口、实际将目标地址转换为 Client 的 8088 端口为例,我们在 NAT Server 中添加如下规则:

$ iptables -t nat -A PREROUTING -d 10.0.1.200 -p tcp --dport 80 -j DNAT --to-destination 172.16.1.202:8088

这时候我们再使用 Internet Server 访问 Client 看效果:

$ curl 10.0.1.200
in Client - 172.16.1.202

可以看到,虽然我们指定的主机是 NAT Server 的 80 端口,但实际上访问到了 Client 监听在 8088 端口上的 Web 服务。

端口映射

实际上我们还可以通过 DNAT 完成端口映射的功能,端口映射实际上就是将报文中的目标 Port 位修改为我们指定的端口,以达到我们访问 A 端口的效果和访问 B 端口的效果相同的目的。

假如此时 NAT Server 中也有一个占用 80 端口的 Web 服务,因经上述配置后 Internet Server 访问 NAT Server 的 80 端口是会转发给 Client 主机,所以此时 Internet Server 是访问不到 NAT Server 中的 Web 服务的,如果我们要让它访问到该怎么做呢?

聪明如你一定想到了,可以把 NAT Server 中的另一个端口映射为映射为它自己的 80 端口呀~~~
是的!这里我们就以 Internet Server 访问 NAT Server 时将其的 8080 端口映射为 80 为例,在 NAT Server 中添加如下规则并启动 httpd 服务:

$ systemctl start httpd
$ iptables -t nat -I PREROUTING -s 10.0.1.201 -d 10.0.1.200 -p tcp --dport 8080 -j DNAT --to-destination 127.0.0.1:80

再使用 Internet Server 访问一下 NAT Server 的 80 和 8080 端口:

$ curl 10.0.1.200
in Client - 172.16.1.202
$ curl 10.0.1.200:8080
in NAT Server  - 10.0.1.200/172.16.1.200

可以看到,访问 NAT Server 的 80 端口实际上访问的是 Client 的 Web 服务,这个没影响,访问 NAT Server 的 8080 端口实际上访问到的是 Nat Server 本身监听在 80 端口上的 Web 服务。

小结一下

源地址转换可分为静态源地址转换(SNAT)和动态源地址(MASQUERADE)转换,规则必须添加在 POSTROUTING 链上,语法格式如下:

静态源地址转换:
	iptables -t nat -A POSTROUTING -s <SOURCE_ADDR> -j SNAT --to-source <EXIST_IP>
动态源地址转换:
	iptables -t nat -A POSTROUTING -s <SOURCE_ADDR> -j MASQUERADE

参数说明:
	SOURCE_ADDR:源地址;
	EXIST_IP:存在的 IP;

目标地址转换(DNAT)不仅可以做地址转换,还可以实现本机的端口映射的功能,规则必须添加在 PREROUTING 链上,其语法格式如下:

地址转换:
	iptables -t nat -A PREROUTING -d <EXIST_IP> -j DNAT --to-destination <INTERNET_SERVER_IP>
端口映射:
	iptables -t nat -A PREROUTING -d <ME_IP> -j DNAT -p {tcp|udp} --dport <PORT> --to-destination <ME_IP>:<NEW_PORT>

参数说明:
	EXISTIP:存在的 IP;
	INTERNET_SERVER_IP:远程主机 IP;
	ME_IP:部署 iptables 的主机本机 IP;
	PORT:访问的原端口;
	NEW_PORT:要映射到的新端口
# iptables  

如果这篇文章对您有帮助,可点击下方链接分享给你的朋友们😋,如果遇到问题欢迎评论、留言~~~😇

评论

公众号:zze_coding

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×