iptables防火墙NAT服务器的设置

iptables防火墙NAT服务器的设置

NAT 服务器的设置

假设我们准备要架设一个路由器的延伸服务器,就称之为 NAT 服务器。NAT 是什么呢?简单的说,可以称它为内部 LAN 主机的 IP 分享器。

NAT 的全名是 Network Address Translation,即网络地址的转换。通过字面上的意思我们来想一想,TCP/IP 的网络数据包不是有 IP 地址吗?IP 地址不是有来源与目的地吗?iptables 命令就能够修改 IP 数据包的报头数据,连目标或来源的 IP 地址都可以修改,甚至连 TCP 数据包报头的 port number 也能修改。

NAT 服务器的功能除了可以实现类似 IP 分享的功能之外

firewall_01.png

图:单一网络,仅有一个路由器的环境示意图

还可以达到类似 DMZ(非军事化隔离区)的功能。

firewall_03.png

图:架设在防火墙后端的网络服务器环境示意图

这完全取决于 NAT 是修改来源 IP 还是目标 IP。下面我们就来聊一聊此内容。

什么是 NAT?SNAT?DNAT?

在介绍 NAT 的实际操作之前,让我们再来看一下比较简单的数据包通过 iptables 而传送到后端主机的表与链流程。
参考图如下:

iptables_04.png

图:iptables 内建各表与链的相关性(简图)

当网络布线如 单一网络 的架构,若内部 LAN 有任何一台主机想要传送数据包出去时,那么这个数据包要如何通过 Linux 主机而传送出去呢?是这样的:

  1. 先经过 NAT table 的 PREROUTING 链。
  2. 经由路由判断确定这个数据包是否要进入本机,若不进入本机,则下一步。
  3. 再经过 Filter table 的 FORWARD 链。
  4. 通过 NAT table 的 POSTROUTING 链,最后传送出去。

NAT 服务器的重点就在于上面流程的第 1、4 步,也就是 NAT table 的两条重要的链:PREROUTING 与 POSTROUTING。那这两条链有什么重要的功能呢?重点在于修改 IP。但这两条链修改的 IP 是不一样的,POSTROUTING 修改的是来源 IP,PREROUTING 则修改的是目标 IP。由于修改的 IP 不一样,所以就称为来源 NAT (Source NAT, SNAT) 及目标 NAT (Destination NAT, DNAT)。我们先来谈一谈 IP 分享器功能的 SNAT。

来源 NAT (SNAT):修改数据包报头的来源项目

你应该有听说过 IP 路由器,它可以让家庭里的好几台主机同时通过一条 ADSL 网络连接到 Internet 上,如图 单一网络 中所示,那个 Linux 主机就是 IP 路由器。那么它是如何实现 IP 分享的功能呢?就是通过 NAT 表的 POSTROUTING 来处理的。假设网络布线如图 单一网络 所示, 那么 NAT 服务器是如何处理这个数据包的呢?

如图所示:

nat_01.png

图:SNAT 数据包传送出去的示意图

在客户端 192.168.1.100 这台主机要连接到 http://tw.yahoo.com 去时,它的数据包报头会如何变化?

  1. 客户端所发出的数据包报头中,来源会是 192.168.1.100,然后传送到 NAT 这台主机。
  2. NAT 主机的内部接口 (192.168.1.2) 接收到这个数据包后,会主动分析报头数据,因为报头数据显示目的并非 Linux 本机,所以开始经过路由分析,将此数据包转到可以连接到 Internet 的 Public IP 处。
  3. 由于 Private IP 与 Public IP 不能互通,所以 Linux 主机通过 iptables 的 NAT table 内的 POSTROUTING 链将数据包报头的来源伪装成为 Linux 的 Public IP,并且将两个不同来源 (192.168.1.100 及 Public IP) 的数据包对应写入暂存内存当中,然后将此数据包传送出去

此时 Internet 上面看到这个数据包时,都只会知道这个数据包来自 Public IP 而不知道其实是来自内部。好了,那么如果 Internet 返回数据包呢?又会怎么做?如图

nat_02.png

图:SNAT 数据包接收的示意图
  1. 在 Internet 上面的主机接到这个数据包时,会将响应数据传送给那个 Public IP 的主机。
  2. 当 Linux NAT 服务器收到来自 Internet 的响应数据包后,会分析该数据包的序号,并比对刚刚记录到内存当中的数据,由于发现该数据包为后端主机之前传送出去的,因此在 NAT PREROUTING 链中,会将目标 IP 修改成为后端主机,亦即那台 192.168.1.100,然后发现目标已经不是本机 (Public IP),所以开始通过路由分析数据包流向
  3. 数据包会传送到 192.168.1.2 这个内部接口,然后再传送到最终目标 192.168.1.100 机器上去。

经过这个流程,就可以发现,所有内部 LAN 的主机都可以通过这部 NAT 服务器连接出去,而大家在 Internet 上面看到的都是同一个 IP(就是 NAT 那台主机的 Public IP),所以,如果内部 LAN 主机没有连上不明网站的话,那么内部主机其实是具有一定程度的安全性的,因为 Internet 上的其他主机没有办法主动攻击你的 LAN 内的 PC。所以我们才会说,NAT 最简单的功能就是类似 IP 分享器。这也是 SNAT 的一种。

Tips:
NAT 服务器与路由器有什么不同?基本上,NAT 服务器一定是路由器,不过,NAT 服务器由于会修改 IP 报头数据,因此与单纯转递数据包的路由器不同。最常见的 IP 分享器就是一个路由器,但是这个 IP 分享器一定会有一个 Public IP 与一个 Private IP,让 LAN 内的 Private IP 可以通过 IP 分享器的 Public IP 传送出去。至于路由器通常两边都是 Public IP 或同时为 Private IP。

目标 NAT (DNAT):修改数据包报头的目标项目

SNAT 主要是应付内部 LAN 连接到 Internet 的使用方式,**DNAT 则主要用在内部主机想要架设可以让 Internet 访问的服务器。就有点类似图 架设在防火墙后端的网络服务器 的 DMZ 内的服务器。下面也先来谈一谈 DNAT 的运行吧。

如图所示:

nat_03.png

图:DNAT 的数据包传送示意图

假设内部主机 192.168.1.210 启动了 WWW 服务,这个服务的 port 开启在 port 80,那么 Internet 上面的主机 (61.xx.xx.xx) 要如何连接到内部服务器呢?当然,还是得要通过 Linux NAT 服务器。所以这台 Internet 上面的机器必须要连接到 NAT 的 Public IP 才行。

  1. 外部主机想要连接到目的端的 WWW 服务,则必须要连接到 NAT 服务器上。
  2. NAT 服务器已经设置好要分析出 port 80 的数据包,所以当 NAT 服务器接到这个数据包后,会将目标 IP 由 Public IP 改成 192.168.1.210,且将该数据包相关信息记录下来,等待内部服务器的响应。
  3. 上述的数据包在经过路由后,来到 Private 接口处,然后通过内部的 LAN 传送到 192.168.1.210 上。
  4. 192.186.1.210 会响应数据给 61.xx.xx.xx,这个回应当然会传送到 192.168.1.2 上去。
  5. 经过路由判断后,来到 NAT POSTROUTING 的链,然后通过第二步骤的记录,将来源 IP 由 192.168.1.210 改为 Public IP 后,就可以传送出去了。

其实整个步骤几乎就等于 SNAT 的反向传送。这就是 DNAT。

简单的NAT服务器:IP分享功能

在 Linux 的 NAT 服务器服务当中,最常见的就是类似图 单一网络 的 IP 分享器功能。而由刚刚的介绍我们也该知道,这个 IP 分享器的功能其实就是 SNAT,作用就只是在 iptables 内的 NAT 表中,那个路由判断后的 POSTROUTING 链所做的工作就是进行 IP 的伪装。另外,需要了解的是,NAT 服务器必须要有一个 Public IP 接口,以及一个内部 LAN 连接的 Private IP 接口才行。下面的范例中,假设是这样的:

  • 外部接口使用 eth0,这个接口具有 Public IP。
  • 内部接口使用 eth1,假设这个 IP 为 192.168.100.254。

利用前面谈到的数据来设置网络参数后,务必要进行路由的检测,因为在 NAT 服务器的设置方面,最容易出错的地方就是路由。尤其是在拨号产生 ppp0 这个对外接口的环境下,这个问题最严重。一定要记住:如果 Public IP 取得的方式是拨号或 cable modem 时,对于配置文件 /etc/sysconfig/network、ifcfg-eth0、ifcfg-eth1 等,千万不要设置 GATEWAY,否则就会出现两个 default gateway,反而会造成问题。

编辑 iptables.rule 文件,该文件内已经含有 NAT 的脚本了。在该文件的第二部份关于 NAT 服务器的设置中,应该有看到下面这几行:

1
2
3
4
5
6
7
8
9
10
iptables -A INPUT -i $INIF -j ACCEPT
# 这一行为非必要的,主要的目的是让内网 LAN 能够完全的使用 NAT 服务器资源
# 其中 $INIF 在本例中为 eth1 接口

echo "1" > /proc/sys/net/ipv4/ip_forward
# 这一行则是在让 Linux 具有 router 的功能

iptables -t nat -A POSTROUTING -s $innet -o $EXTIF -j MASQUERADE
# 这一行最关键!就是加入 NAT table 数据包伪装。本例中 $innet 是 192.168.100.0/24
# 而 $EXTIF 则是对外界面,本例中为 eth0

以上输出重点在 “MASQUERADE”。这个设置值就是 IP 伪装成为封包出去 (-o) 的那块设备上的 IP。以上面的例子来说,就是 $EXTIF,也就是 eth0。所以数据包来源只要来自 $innet (也就是内部 LAN 的其他主机) ,只要该数据包可通过 eth0 传送出去,那就会自动的修改 IP 的来源报头成为 eth0 的 Public IP。将 iptables.rule 设置好你内、外网络接口,执行 iptables.rule 后,Linux 就拥有主机防火墙以及 NAT 服务器的功能。

例题:如同上面所述的案例,那么 LAN 内的其他 PC 应该要如何设置相关的网络参数?
答:答案其实很简单,将 NAT 服务器作为 PC 的 GATEWAY 即可。只要记得下面的参数值即可:

  • NETWORK 为 192.168.100.0
  • NETMASK 为 255.255.255.0
  • BROADCAST 为 192.168.100.255
  • IP 可以设置 192.168.100.1 ~ 192.168.100.254 之间,不可重复
  • 网关 (Gateway) 需要设置为 192.168.100.254(NAT 服务器的 Private IP)
  • DNS (/etc/resolv.conf) 需设置为 168.95.1.1 (Hinet) 或 139.175.10.20 (Seed Net),这个请依 ISP 而定

事实上,除了 IP 伪装 (MASQUERADE) 之外,我们还可以直接指定修改 IP 数据包报头的来源 IP。
如下面这个例子:

例题:假设对外的 IP 固定为 192.168.1.100,若不想使用伪装,该如何处理?
答:

1
iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 192.168.1.100

例题:假设 NAT 服务器对外 IP 有好几个,那想要轮流使用不同的 IP 时,该如何设置?
假设你的 IP 范围为 192.168.1.210 ~ 192.168.1.220
答:

1
iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 192.168.1.210-192.168.1.220

这样也可以修改网络数据包的来源 IP 资料。不过,除非使用的是固定 IP,且有多个 IP 可以对外连接,否则一般使用 IP 伪装即可,不需要使用到 SNAT。当然,你也可能有自己独特的环境。

iptables 的额外内核模块功能

如果在 iptables.rule 文件内的第二部分仔细观察,可能会奇怪,为何我们需要加载一些有用的模块?比如 ip_nat_ftp 及 ip_nat_irc ?这是因为很多通信协议使用的数据包传输比较特殊,尤其是 FTP 文件传输使用两个 port 来处理数据。在这里我们需要知道,iptables 提供很多好用的模块,这些模块可以辅助数据包的过滤,可以让我们节省很多 iptables 的规则拟定工作。

在防火墙后端的网络服务器上做 DNAT 设置

既然可以做 SNAT 的 IP 分享功能,我们当然可以使用 iptables 做出 DMZ。但是再次重申,不同的服务器数据包传输的方式可能有点差异,因此,建议新手不要玩这个东西。否则很容易导致某些服务无法顺利对 Internet 提供的问题

先来谈一谈,如果想要处理 DNAT 的功能时,iptables 要如何下达命令?另外,我们必须要知道的是,DNAT 用到的是 NAT table 的 PREROUTING 链。不要搞错了。

例题:假设内网有部主机 IP 为 192.168.100.10,该主机是可对 Internet 开放的 WWW 服务器。该如何通过 NAT 机制,将 WWW 数据包传到该主机上?
答:假设 Public IP 所在的接口为 eth0 ,那么规则就是:

1
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 192.168.100.10:80

上面例题中的 -j DNAT --to-destination IP[:port] 就是精髓,代表从 eth0 这个接口传入的,且想要使用 port 80 的服务时,将该数据包重新传递到 192.168.100.10:80 的 IP 及 port 上。可以同时修改 IP 与 port,真方便。其他还有一些较高级的 iptables 使用方式,如下所示:

1
2
3
4
5
6
7
8
9
10
-j REDIRECT --to-ports <port number>
# 这个也挺常见的,基本上,就是进行本机上面 port 的转换
# 不过,特别留意的是,这个操作仅能够在 NAT table 的 PREROUTING 以及
# OUTPUT 链上面实行

# 范例:将要求与 80 连接的数据包转递到 8080 这个 port
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
# 这种设置最容易在使用了非正规的 port 来进行某些 well known 的协议,
# 例如使用 8080 这个 port 来启动 WWW ,但是别人都以 port 80 来连接,
# 所以,就可以使用上面的方式来将对方对本机主机的连接传递到 8080 了
---------------- The End ----------------
0%