配置NAT服务器<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

本章主要介绍如何使用 iptbales 实现 linux2.4 下的强大的 NAT 功能。
一、原理   
netfilter Linux 核心中一个通用架构,它提供了一系列的 " "(tables) ,每个表由若干 " "(chains) 组成,而每条链中可以有一条或数条规则 (rule) 组成。并且系统缺省的表是 "filter" 。但是在使用 NAT 的时候,我们所使用的表是 "nat" 表,所以我们必须使用 "-t nat" 选项来显式地指明这一点。
filter 表一样, nat 表也有三条缺省的 " "(chains) ,这三条链也是规则的容器,它们分别是:
PREROUTING :可以在这里定义进行目的 NAT 的规则,因为路由器进行路由时只检查数据包的目的 ip 地址,所以为了使数据包得以正确路由,我们必须在路由之前就进行目的 NAT;
POSTROUTING :可以在这里定义进行源 NAT 的规则,系统在决定了数据包的路由以后在执行该链中的规则。
OUTPUT :定义对本地产生的数据包的目的 NAT 规则。
二、操作语法
使用 iptables NAT 功能时,我们必须在每一条规则中使用 "-t nat" 显示的指明使用 nat 表。然后使用以下的选项 :
1. 对规则的操作
    加入 (append) 一个新规则到一个链 (-A) 的最后。
    在链内某个位置插入 (insert) 一个新规则 (-I) ,通常是插在最前面。
    在链内某个位置替换 (replace) 一条规则 (-R)
    在链内某个位置删除 (delete) 一条规则 (-D)
    删除 (delete) 链内第一条规则 (-D)
2. 指定源地址和目的地址
通过 --source/--src/-s 来指定源地址,通过 --destination/--dst/-s 来指定目的地址。可以使用以下四中方法来指定 ip 地址:
a. 使用完整的域名,如 “[url]www.linuxaid.com.cn[/url]”
b. 使用 ip 地址,如 “192.168.<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />1.1”
c. x.x.x.x/x.x.x.x 指定一个网络地址,如 “192.168.1.0/255.255.255.0”;
d. x.x.x.x/x 指定一个网络地址,如 “192.168.1.0/24” 这里的 24 表明了子网掩码的有效位数,这是 UNIX 环境中通常使用的表示方法。
缺省的子网掩码数是 32 ,也就是说指定 192.168.1.1 等效于 192.168.1.1/32
3. 指定网络接口
可以使用 --in-interface/-i --out-interface/-o 来指定网络接口。从 NAT 的原理可以看出,对于 PREROUTING 链,我们只能用 -i 指定进来的网络接口;而对于 POSTROUTING OUTPUT 我们只能用 -o 指定出去的网络接口。
4. 指定协议及端口
可以通过 --protocol/-p 选项来指定协议,如果是 udp tcp 协议,还可 --source-port/--sport --destination-port/--dport 来指明端口四、准备工作
1. 编译内核,编译时选中以下选项,具体可参看 iptales 实现包过虑型防火墙 一文:
Full NAT
MASQUERADE target support
REDIRECT target support
2. 要使用 NAT 表时,必须首先载入相关模块:   
modprobe ip_tables
modprobe ip_nat_ftp
iptable_nat 模块会在运行时自动载入。
五、案例
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
2. 目的 NAT(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
六、综合例子
1. 使用拨号带动局域网上网       
小型企业、网吧等多使用拨号网络上网,通常可能使用代理,但是考虑到成本、对协议的支持等因素,建议使用 ip 欺骗方式带动区域网上网。
成功升级内核后安装 iptables ,然后执行以下脚本:       
# 载入相关模块
modprobe ip_tables
modprobe ip_nat_ftp
# 进行 ip 伪装
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
 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 映射。
例建立包过滤防火墙

#touch /etc/rc.d/filter-firewall

#chmod u+x /etc/rc.d/filter-firewall

#echo "/etc/rc.d/filter-firewall">>/etc/rc.d/rc.local 使脚本能在系统启动时自动执行

#vi /etc/rc.d/filter-firewall

#!/bin/bash

echo "starting iptables rules..."

echo "1">/proc/sys/net/ipv4/ip_forward 开启内核转发功能

IPT=/sbin/iptables 定义变量

$IPT -F 刷新所有链的规则

$IPT -P FORWARD DROP 为永久链指定默认规则。 DROP 表示包被丢弃,即禁止转发任何通过的包

$IPT -A FORWARD -p tcp -d 192.168.80.251 --dport www -i eth0 ACCEPT

$IPT -A FORWARD -p tcp -d 192.168.80.252 --dport ftp -i eth0 ACCEPT

$IPT -A FORWARD -p tcp -d 192.168.80.253 --dport smtp -i eth0 ACCEPT

$IPT -A FORWARD -p tcp -s 0/0 --sport ftp-data -d 192.168.80.0/24 -i eth0 -j accept

$IPT -A FORWARD -p ICMP -s 0/0 -d 192.168.80.0/24 -i eth0 -j REJECT

#/etc/rc.d/filter-firewall 使防火墙起作用

例配置 SNAT 带动简单的局域网使用 Internet 资源

#touch /etc/rc.d/snat-firewall

#chmod u+x /etc/rc.d/snat-firewall

#echo "/etc/rc.d/snat-firewall">>/etc/rc.d/rc.local

#vi /etc/rc.d/snat-firewall

#!/bin/bash

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

IPT=/sbin/iptables

加载内核模块

/sbin/modprobe iptables

/sbin/modprobe iptable_nat

/sbin/modprobe ip_nat_ftp

/sbin/modprobe ipt_LOG

清除已设规则,还原到不设防火墙的状态

$IPT -p INPUT ACCEPT

$IPT -p FORWARD ACCEPT

$IPT -p OUTPUT ACCEPT

$IPT -t nat -p PREROUTING ACCEPT

$IPT -t nat -p POSTROUTING ACCEPT

$IPT -t nat -p OUTPUT ACCEPT

for TABLE in filter nat mangle;do

$IPT -t $TABLE -F 清除预设表 filter 中所有规则链中的规则

$IPT -t $TABLE -X 清除预设表 filter 使用者自定义链中规则

done

$IPT -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT 允许所有已经初始化了的回应数据包

for DNS in $(grep ^n /etc/resolv.conf|awk '{print $2}');do

$IPT -A INPUT -p udp -s $DNS --sport domain -j ACCEPT 允许 DNS 服务器进入防火墙的数据包

done

$IPT -N LOGDENY 创建用户定义链 LOGDENY, 在此链中添加规则,拒绝所有 ( 除了 lo 接口 ) 新建立或无效的连接请求并记入日志

$IPT -A LOGDENY -j LOG --log-prefix "iptables:"

$IPT -A LOGDENY -j DROP

$IPT -A INPUT -i ! lo -m state --state NEW,INVALID -j LOGDENY

$IPT -t nat -A POSTROUTING -o eth1 -j SNAT --to 200.200.200.1

例在局域网对外发布服务

#touch /etc/rc.d/snat-firewall

#chmod u+x /etc/rc.d/snat-firewall

#echo "/etc/rc.d/snat-firewall">>/etc/rc.d/rc.local

#vi /etc/rc.d/snat-firewall

#!/bin/bash

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

IPT=/sbin/iptables

加载内核模块

/sbin/modprobe iptables

/sbin/modprobe iptable_nat

/sbin/modprobe ip_nat_ftp

/sbin/modprobe ipt_LOG

清除已设规则,还原到不设防火墙的状态

$IPT -p INPUT ACCEPT

$IPT -p FORWARD ACCEPT

$IPT -p OUTPUT ACCEPT

$IPT -t nat -p PREROUTING ACCEPT

$IPT -t nat -p POSTROUTING ACCEPT

$IPT -t nat -p OUTPUT ACCEPT

for TABLE in filter nat mangle;do

$IPT -t $TABLE -F 清除预设表 filter 中所有规则链中的规则

$IPT -t $TABLE -X 清除预设表 filter 使用者自定义链中规则

done

$IPT -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT 允许所有已经初始化了的回应数据包

for DNS in $(grep ^n /etc/resolv.conf|awk '{print $2}');do

$IPT -A INPUT -p udp -s $DNS --sport domain -j ACCEPT 允许 DNS 服务器进入防火墙的数据包

done

允许访问被开放的服务

$IPT -A INPUT -p tcp --sport 80 -j ACCEPT

$IPT -A INPUT -p tcp --sport 443 -j ACCEPT

$IPT -A INPUT -p tcp --sport 21 -j ACCEPT

$IPT -N LOGDENY

$IPT -A LOGDENY -j LOG --log-prefix "iptables:"

$IPT -A LOGDENY -j DROP

$IPT -A INPUT -i ! lo -m state --state NEW,INVALID -j LOGDENY

$IPT -t nat -A POSTROUTING -o eth1 -j SNAT --to 200.200.200.1 SNAT

对防火墙的服务请求重定向到局域网内部

$IPT -t nat -A PREROUTIGN -p tcp -d 200.200.200.1 --dport 80 -j DNAT --to 192.168.88.47:80