1、概述
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来解决这个问题,
因为是在应用层以下进行处理,NAT不但可以获得很高的访问速度,而且可以无缝的支持任何新的服务或应用。
还有一个方面的应用就是重定向,也就是当接收到一个包后,不是转发这个包,而是将其重定向到系统上的某一个应用程序。最常见的应用就是和squid配合使用成为透明代理,在对http流量进行缓存的同时,可以提供对Internet的无缝访问。
1.3 NAT的类型
在linux2.4的NAT-HOWTO中,NAT分成了两种类型,即源NAT(SNAT)和目的NAT(DNAT)

SNAT:源IP地址转换
平时说起NAT,一般指的是SNAT。
对于有Internet访问需求而内部又使用私有地址的网络,就要在组织的出口位置部署NAT网关,在报文离开私网进入Internet时,将源IP替换为公网地址,通常是出口设备的接口地址。一个对外的访问请求在到达目标以后,表现为由本组织出口设备发起,因此被请求的服务端可将响应由Internet发回出口网关。出口网关再将目的地址替换为私网的源主机地址,发回内部。这样一次由私网主机向公网服务端的请求和响应就在通信两端均无感知的情况下完成了。依据这种模型,数量庞大的内网主机就不再需要公有IP地址了。
DNAT:目的IP地址转换
DNAT主要有两大用处

  • 发布内部服务器,让外面的internet用户能访问到内网的服务器。

  • 网络重定向


2、原理
在“用iptales实现包过虑型防火墙”一文中我们说过,netfilter是Linux 核心中一个通用架构,它提供了一系列的"表"(tables),每个表由若干"链"(chains)组成,而每条链中可以有一条或数条规则(rule)组成。并且系统缺省的表是"filter"。但是在使用NAT的时候,我们所使用的表不再是"filter",而是"nat"表,所以我们必须使用"-t nat"选项来显式地指明这一点。因为系统缺省的表是"filter",所以在使用filter功能时,我们没有必要显式的指明"-t filter"。
同filter表一样,nat表也有三条缺省的"链"(chains),这三条链也是规则的容器,它们分别是:
PREROUTING:可以在这里定义进行目的NAT的规则,因为路由器进行路由时只检查数据包的目的ip地址,所以为了使数据包得以正确路由,我们必须在路由之前就进行目的NAT;
POSTROUTING:可以在这里定义进行源NAT的规则,系统在决定了数据包的路由以后在执行该链中的规则。
OUTPUT:定义对本地产生的数据包的目的NAT规则。

3、SNAT和DNAT的实现
3.1 SNAT基于原地址的转换

基于原地址的转换一般用在我们的许多内网用户通过一个外网的口上网的时候,这时我们将我们内网的地址转换为一个外网的IP,我们就可以实现连接其他外网IP的功能。
所以我们在iptables中就要定义到底如何转换:
定义的样式:比如我们现在要将所有192.168.10.0网段的IP在经过的时候全都转换成172.16.100.1这个假设出来的外网地址:

iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j SNAT --to-source 172.16.100.1

这样,只要是来自本地网络的试图通过网卡访问网络的,都会被统统转换成172.16.100.1这个IP.
那么,如果172.16.100.1不是固定的怎么办?
我们都知道当我们使用联通或者电信上网的时候,一般它都会在每次你开机的时候随机生成一个外网的IP,意思就是外网地址是动态变换的。这时我们就要将外网地址换成 MASQUERADE(动态伪装):它可以实现自动寻找到外网地址,而自动将其改为正确的外网地址。所以,我们就需要这样设置:

iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j MASQUERADE

这里要注意:地址伪装并不适用于所有的地方。
3.2 DNAT目标地址转换
对于目标地址转换,数据流向是从外向内的,外面的是客户端,里面的是服务器端通过目标地址转换,我们可以让外面的ip通过我们对外的外网ip来访问我们服务器不同的服务器,而我们的服务却放在内网服务器的不同的服务器上。
如何做目标地址转换呢?:

iptables -t nat -A PREROUTING -d 192.168.1.18 -p tcp --dport 80 -j DNAT --todestination 172.16.100.2

目标地址转换要做在到达网卡之前进行转换,所以要做在PREROUTING这个位置上
这里需要注意的是,系统是先进行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

4、应用场景-NAT 共享上网
4.1 服务端配置

(1)使用 iptables 防火墙实现 NAT 转发

echo 1 >/proc/sys/net/ipv4/ip_forward

(2)开启防火墙服务
/etc/init.d/iptables start
(3)清除 iptables 相关的规则

iptables -F  # 清除所有规则,不会处理默认的规则。
iptables -X  # 删除用户自定义的链。
iptables -Z  # 链的记数器清零。

(4)配置防火墙支持 NAT 转发

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

4.2 客户端配置
(1)将外网的 IP 禁用
(2)配置内网 IP 的网关

vim /etc/sysconfig/network-scripts/ifcfg-eth1
GATEWAY=172.16.1.6 #此 IP 地址为配置的服务端

(3)修改 DNS 配置文件,设置为网关

vim /etc/resolv.conf
nameserver 10.0.0.2

(4)测试网关是否可以通

ping 10.0.0.2

(5)如果可以 ping 通的话,则 ping 域名测试,但是不要忘记将外网的 IP 地址关闭

ping www.baidu.com

4.3 共享上网设置
实现 C 可经过 B,通过 A 上因特网。
提示:注意主机防火墙功能的影响,可以尝试 GW 上先/etc/init.d/iptables stop 后在加命令
服务端配置---lb01
(1)使用 iptables 防火墙实现 NAT 转发

echo 1 >/proc/sys/net/ipv4/ip_forward

(2)开启防火墙服务
/etc/init.d/iptables start
(3)清除 iptables 相关的规则

iptables -F
iptables -X
iptables -Z
iptables -nL

(4)添加 iptables 的内核模块

modprobe ip_tables
modprobe iptable_filter
modprobe iptable_nat
modprobe ip_conntrack
modprobe ip_conntrack_ftp
modprobe ip_nat_ftp
modprobe ipt_state

(5)查看模块是否加载

# lsmod|egrep ^ip
ipt_MASQUERADE          2338  1 
iptable_nat             5923  1 
iptable_filter          2793  0 
ip_tables              17831  2 iptable_nat,iptable_filter
ipv6                  336282  266

4..4 局域网共享的两条命令与方法
方法 1:适合与有固定外网地址的

# iptables -t nat -A POSTROUTING -s 172.16.1.0/24 -j SNAT --to-source 10.0.0.5

(1)-s 172.16.1.0/24 办公室IDC内网网段
(2)-o eth0 为网关的外网卡接口
(3) -j SNAT --to-source 10.0.0.5 是网关外网卡IP地址

# iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
SNAT       all  --  172.16.1.0/24        0.0.0.0/0           to:10.0.0.5 

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

方法 2:适合变化的外网地址( ADSL)

# iptables -t nat -A POSTROUTING -s 172.16.1.0/24 -j MASQUERADE #伪装
# iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
MASQUERADE  all  --  172.16.1.0/24        0.0.0.0/0           

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

为什么用POSTROUING?
企业共享上网
1. 办公网共享上网(网关要有外网IP),否则用路由(zebra)
2. IDC内网机器上网
4.5 客户端配置
(1)将外网的 IP 禁用
(2)配置内网 IP 的网关

# vim /etc/sysconfig/network-scripts/ifcfg-eth1
GATEWAY=172.16.1.6 #此IP地址为配置的服务端

(3)修改DNS配置文件,设置为网关

# vim /etc/resolv.conf
nameserver 10.0.0.2

(4)测试网关是否可以通

# ping 10.0.0.2

(5)如果可以 ping 通的话,则 ping 域名测试,但是不要忘记将外网的 IP 地址关闭

#ping www.baidu.com

5、总结

实现配置iptables的NAT功能需要 开启内核的转发功能

echo 1 >/proc/sys/net/ipv4/ip_forward

然后再配置iptables防火墙