解释Linux NAT(网络地址转换)路由

时间:2020-03-21 11:46:05  来源:igfitidea点击:

为了使计算机彼此通信,每台计算机都必须具有唯一的地址才能发送和接收数据。
如果我们没有唯一的地址,则其他人将无法向我们发送数据。
在IPv4中,大约有2 ^ 32个地址,其中588514304用于特殊目的,这意味着我们只有2 ^ 32 588514304个唯一的公共IP地址。

想象一下一个办公室,其中有1000台计算机供员工工作。
如果每个人都需要与Internet上的主机进行通信,则为每个人分配一个唯一的公共IP地址将是白痴,也将浪费Internet资源。

同样,出于安全原因,有时我们也想从公开的Internet隐藏内部网络地址的详细信息。
NAT是解决这些问题的一种解决方案。

什么是NAT(网络地址转换)?

该名称本身表明它进行地址的翻译。
IP地址可以在NAT的帮助下转换为另一个。
NAT设备的主要工作是重写IP数据包的源地址和目标地址。

有一些硬件设备可以完成这项工作,但是我们将在Linux系统的帮助下完成此工作(因为它几乎可以完成所有由硬件nat设备完成的工作。
)。

无论如何,理解此NAT教程不是我们关注的一部分。
假设google通过其网页答复了该请求。

收到Google的回复后,Linux路由器将检查/proc/net/ip_conntrack以查看该回复是否属于其任何连接。
找到来自192.168.0.3的连接后,Linux路由器会将目标IP地址从4.4.7.23重写为192.168.0.3.
(请注意,我们的Linux路由器仅将目标ip从其自身的ip重写为192.168.0.3,因为请求来自192.168.0.3.
源ip地址保留为google.com本身。

第4步:我们的内部计算机的IP地址为192.168.0.3,从Google收到回复,如下所示。

源地址:google.com,目标地址:192.168.0.3

现在,让我们使用iptables了解Linux中SNAT的配置。

什么是DNAT?

在上面显示的SNAT示例中,连接是由内部网络内部的主机发起的。
如果Internet上的主机需要启动连接该怎么办。
在这种情况下,我们需要设计Linux路由器,以使从Internet到路由器上特定公共IP地址的流量将被转发到一个特定的私有IP地址。

这种配置称为DNAT或者目标NAT。
之所以称为目标NAT,是因为路由器进行的第一个地址重写是针对目标地址的。

让我们以一个例子来了解DNAT。
假设来自Internet的IP地址2.2.7.23要与4.4.7.23(在我们的Linux路由器上分配的公共IP地址)进行通信,让我们完成完成该连接所涉及的步骤。

步骤1:主机2.2.7.23通过以下IP数据包启动与4.4.7.23(这是我们的Linux路由器公共IP地址)的连接。

源地址:2.2.7.23目标地址:4.4.7.23

步骤2:在收到数据包后,Linux路由器会将数据包的目标地址从4.4.7.23重写为192.168.0.3,并在文件/proc/net/ip_conntrack中添加了包含连接完整信息的条目。

步骤3:处理完请求后,来自192.168.0.3的回复将发送到我们的Linux路由器,其中包含以下IP详细信息。

源地址:192.168.0.3,目标地址:2.2.7.23

步骤4:在收到IP数据包后,Linux路由器将查看ip_conntrack表以查找有关此连接的详细信息,并看到该连接是由2.2.7.23到4.4.7.23发起的,Linux路由器将重写该连接的源地址。
数据包到其自己的公共IP地址。
因此,最终的最终数据包将发送到2.2.7.23,如下所示。

源地址:4.4.7.23,目标地址:2.2.7.23

DNAT的缺点

  • 配置DNAT意味着我们允许Internet上的主机发起通信,并且能够访问私有主机。从安全角度来看,这不是一个好主意
  • 仅使用路由器上的一个公共IP地址配置DNAT有点困难

全NAT

完全NAT只是SNAT和DNAT的组合。
如果我们在单个Linux路由器中结合了上述两种命名方法(SNAT和DNAT),那么我们就在进行FULL NAT。

在FULL NAT中,内部计算机以及来自Internet的主机都可以启动连接。

iptables中的SNAT和DNAT配置

iptable中的NAT表内部有三个链。
让我们通过查看NAT表来查看所有这些。

[root@myvm1 ~]# iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
[root@myvm1 ~]#

如上所示,nat表中有三个链。
输出,输出,输出。
路由器的主要功能是路由IP数据包。
我们的Linux路由器执行完全相同的操作。
因此,PREROUTING talble将包含在做出路由决策之前需要分析的规则。

让我们借助iptables进行SNAT。

我们将使用与私有网络和公共ip地址完全相同的示例进行此SNAT配置。
我们的路由器有两个IP地址(192.168.0.6和4.4.7.23)。

具有专用IP地址的NIC卡已连接到LAN网络,所有内部网络都可以在该LAN网络上相互通信。
我们的Linux路由器将是IP地址为192.168.0.0/24的所有其他内部LAN机器的默认网关,并且Linux路由器上的另一个NIC卡已连接到ISP(为我们提供了4.4的公共IP地址) .7.23)

让我们在Linux路由器上添加一个SNAT规则,该规则IP地址范围为192.168.0.0/24的所有内部主机与Internet上的主机进行通信。

[root@myvm1 ~]# iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j SNAT --to 4.4.7.23

这使我们的iptable的nat表如下所示。

[root@myvm1 ~]# iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
SNAT       all  --  192.168.0.0/24       anywhere            to:4.4.7.23
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

如前所述,伪装和SNAT几乎相同,除了不能指定传出IP地址这一事实。
在伪装中,我们可以指定传出接口而不是IP地址。
当我们从ISP通过dhcp获取动态公共IP地址时,这非常有用。

[root@myvm1 ~]# iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j MASQUERADE
[root@myvm1 ~]#

进行SNAT的另一种更好的方法是仅对将从Linux路由器上的eth1接口(公共IP接口)传出的那些数据包进行NAT。
我们还可以为iptables提供一个ip地址范围,以便iptables可以使用该范围进行SNAT。

[root@myvm1 ~]# iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o eth1 -j SNAT --to 4.4.3.27-4.4.3.45
[root@myvm1 ~]#

大多数人在听到有关PREROUTING&POSTROUTING的消息时会感到困惑。
POSTROUTING是为SNAT完成的,因为它是在做出路由决定之后且在数据包离开系统之前完成的。
PREROUTING主要在DNAT中完成,因为在DNAT中,我们可以从Internet访问内部机器,因为即使在做出路由决定之前,我们也需要更改其目标地址(当然,更改目标地址将对路由决定产生影响..因此,一旦数据包到达计算机,则完成DNAT,这意味着PREROUTING)。

iptables的DNAT配置示例

假设我们希望允许从Internet连接到内部计算机192.168.0.3之一,以便任何员工都可以使用Ineternet从家里访问192.168.0.3.

为此,我们需要将Linux路由器上的一个公共ip地址专门映射到该内部计算机192.168.0.3.
假设我们正在将我们的公共IP地址4.4.7.23映射到192.168.0.3.

[root@myvm1 ~]# iptables -t nat -A PREROUTING -d 4.4.7.23 -j DNAT --to 192.168.0.3
[root@myvm1 ~]#

应用上述规则后,任何人都可以通过访问路由器上的公共IP地址4.4.7.23来访问内部计算机。
为了安全起见,如果我们只想允许从Internet访问某些公共IP地址,则可以通过添加-s <公共IP列表>来实现。

在上述规则中,所有进入4.4.7.23的流量都将通过DNAT发送到192.168.0.3.
更好的方法是只允许访问192.168.0.3到4.4.7.23上的所需服务。

例如,我们可以通过添加如下所示的DNAT规则,将Web服务器托管在Intranet服务器192.168.0.3上,并允许来自Internet的人们访问站点。

[root@myvm1 ~]# iptables -t nat -A PREROUTING -d 4.4.7.23 -p tcp --dport 80 -j DNAT --to 192.168.0.3
[root@myvm1 ~]#

添加上述规则后,我们可以让人们访问位于192.168.0.3上的。

我们可以借助DNAT允许SSH访问Intranet服务器192.168.0.3,其方式与我们允许访问192.168.0.3上的Web服务器的方式完全相同。

[root@myvm1 ~]# iptables -t nat -A PREROUTING -d 4.4.7.23 -p tcp --dport 8532 -j DNAT --to 192.168.0.3:22
[root@myvm1 ~]#

在上面显示的iptable规则中,任何到达端口8532(通过4.4.7.23)的流量都将发送到192.168.0.3上的ssh。
任何需要ssh到192.168.0.3的人都应该对ssh进行4.4.7.23:8532

我们还可以在iptable DNAT的帮助下设置透明代理。
由于人们可以在访问Internet时从浏览器禁用代理设置,因此我们可以通过将所有流量发送到Internet上的端口80到代理服务器端口来强制使用代理。

让我们看看如何。

[root@myvm1 ~]# iptables -t nat -A PREROUTING -s 192.168.0.0/24 -p tcp --dport 80 -j REDIRECT --to-port 1234

在上面显示的示例中,来自本地Intranet且源地址为192.168.0.0/24的所有http通信将被重定向到我们假定的代理服务器端口1234.

这样,我们可以强制本地Intranet用户在浏览网页时使用代理服务器。