Linux 如何进行网络地址转换


此文档说明如何进行伪装、透明代理、端口转发,和基于Linux 2.4内核其他类型的 网络地址转换(Network Address Translations)。

1. 简介
2. 官方站点及列表
2.1 什么是NAT?
2.2 我为什么需要NAT?
3. NAT的两种类型
4. 从2.0和2.2内核的快速转换
4.1 我只想伪装!救命!
4.2 关于ipmasqadm
5. NAT可以控制什么
5.1 用iptables做简单的选择
5.2 关于应当挑选哪些包来拆分(mangle)的要点
6. 说说如何拆分包吧
6.1 源地址NAT
6.1.1 伪装
6.2 目的地址NAT
6.2.1 重定向
6.3 深层次的映射
6.3.1 一个范围内多地址的选择
6.3.2 建立空的NAT映射
6.3.3 标准NAT行为
6.3.4 内部源端口映射
6.3.5 如果NAT失败会怎样?
6.3.6 多重映射,重叠和冲突
6.3.7 修改本地生成的连接的目标地址
7. 特定的协议
8. 关于NAT的警告
9. 源地址NAT和选路
10. 同一网络内的目标地址NAT
11. 感谢
1. 简介
欢迎,亲爱的读者。
你将要深入迷人的(有时是令人厌烦的)NAT世界:网络地址转换,这篇HOWTO可以成为你的Linux2.4内核及其以后的准确指南。
在Linux2.4(内核版本),引入了一个叫“netfilter”的部分,专门用于拆分(mangling) (IP)包的。他上一层提供NAT,是完全依靠以前的内核制作的。
(译者注:mangle实在找不出什么合适的翻译,抱歉)
(C) 2000 Paul `Rusty Russell. Licensed under the GNU GPL.

--------------------------------------------------------------------------------
 
2、 官方站点及列表位置
这里有三个官方站点:
o Thanks to Filewatcher http://netfilter.filewatcher.org.
o Thanks to The Samba Team and SGI http://netfilter.samba.org.
o Thanks to Harald Welte http://netfilter.gnumonks.org.
你可以通过以下站点访问全部相关站点。
http://www.netfilter.org and http://www.iptables.org
以下是netfilter官方邮件列表
http://www.netfilter.org/contact.html#list.

--------------------------------------------------------------------------------
 
2、1 什么是网络地址转换(Network Address Translation)?
通常,,网络中的(IP)包从他们的源(地址)出发(比如你家的电脑),到他们的目的地(比如www.gnumonks.org),会经过很多不同的连接(links):例如我所在澳大利亚就有19个。这些连接不会真去修改你的包:他们只是照原样传出去。
(译者注:这里的links应当认为是所有网络节点,包括主机、路由器等。通常,路由器并不是原样传送包,它至少会修改其中一点:TTL)
如果这些连接有一个做NAT,那么它(们)就会修改通过它们的包的源或者目标(地址)。正如你猜象的那样,这并非系统设计成那样 的,而是NAT做了一些事情。通常进行NAT的连接(主机、服务器、路由器)会记住它是如何拆分包的,而当另一头响应的包通过时,它会对响应的包做相反的 拆分,所以世界仍在运转。
(译者注:这一段的mangle应该想象为修改更合适)

--------------------------------------------------------------------------------
 
2、2 我为什么要NAT?
在完美的世界里,你不需要。同时,主要的理由是:
用调制解调器连接Internet
在你拨号上网时,大部分ISP只会给你一个IP地址,你可以发送你想发送的任何源地址包,但是只有响应这个(ISP给你的)地址的包才会返回。如果这种情况下你想有多台不同的机器上网(比如一个家庭网络),你就需要NAT。
这是现在NAT用得最多的功能,Linux世界的"masquerading"(伪装)非常出名,我称之为SNAT(SNAT即Source NAT,源地址转换),因为你改变了第一个包的源地址。
(译者:关于IP数据报的第一个包等内容,请参见各TCP/IP书籍)
多(重)服务器
有时你想改变进入网络中的包的目标地址(路由)。经常的,这是因为(就像上面的例子),你只有一个IP地址,但是你希望大家可以通过到那个“真实”的IP地址进入内部。如果你重写了进入包的目标地址,这样就没问题了。这种NAT在以前的Linux版本中被称为端口转发。
一个常见的变种是负载均衡,在一组机器上做映射。如果你要进行严格的比例限制, 可能需要参考Linux Virtual Server。http://linuxvirtualserver.org
透明代理
有时你可能想要经过你的Linux的包被送往本机的一个程序。这就需要用到透明代理了:代理是位于你的网络和外部世界之间的一个程序,帮助二者进行通信。之所以称为透明,是你的网络根本不知道他在和代理交谈,当然直到代理没有正常工作。
Squid可以配置为干这项工作,在以前Linux版本中它被称作重定向或者透明代理。

--------------------------------------------------------------------------------
 
3、 NAT的两种类型
我把NAT分为两种不同的类型:源NAT(SNAT)和目标NAT(DNAT)。(译者注:以下不再翻译SNAT和DNAT,直接用Source NAT和Destination NAT)
Source NAT是指修改第一个包的源地址:也就是说,改变连接的来源地。Source NAT会在包送出之前的最后一刻做好post-routing(动作),伪装是SNAT的一种特殊形式。
Destination NAT 是指修改第一个包的目标地址:也就是说,改变连接的目的地。Destination NAT 总是在包进入以后(马上)进行before routing(动作)。端口转发、负载均衡和透明代理都属于DNAT。

--------------------------------------------------------------------------------
 
4、 从2.0和2.2内核的快速转换
如果你还在为从2.0(ipfwadm)到2.2(ipchains)的转换手忙脚乱的话,很抱歉。不过这也算是个喜忧半参的消息。
首先,你可以轻松的使用ipchains和ipfwadm,就像从前一样。不过你需要安装最新发布的netfilter中的“ipchains.o”或者“ipfwadm.o”内核模块。它们是互斥的(你会被警告),而且不能和任何其他netfilter模块结合。
一旦这其中某个模块被载入,你可以像以前一样使用ipchains和ipfwadm,不过仍有以下区别:
用ipchains -M -S,或者用ipfwadm -M -s设置伪装超时不再有效。因为超时已经转移到新的NAT构架中,所以这不能做任何事。
在详细的伪装列表中,init_seq、delta和previous_delat字段始终为零。
归零和列表计数器的 -Z -L不再有效:计数器不能被归零。
这类向后兼容的部分可能和大部分连接都不能有效配合:不要在你的公司网关中使用
开发者们还要注意:
无论是否使用伪装,现在可以绑定61000 - 65095之间的端口。以前的伪装代码占用了这部分端口,因此不能使用。
尚未成文的“getsockname”,透明代理程序可以用来发现那些已不再工作的连接的真实目的地址。
尚未成文的“bind-to-foreign-address”同样还未启用:这个用于完整透明代理的设想。

--------------------------------------------------------------------------------
 
4、1 我只想伪装!救命!
这是绝大部分人想要的。如果你用PPP拨号上网来动态得到IP (如果你不知道,那应该就是的)你可能只想告诉你的机器,所有来自内部网络的包,要看上去同PPP连接服务器上的包一样。
# 装载NAT模块(这取代了其他的)
modprobe iptable_nat
# 在NAT表中(-t nat),路由后 POSTROUTING 加入一条规则(-A)
# 所有由ppp0送出的包(-o ppp0) 会被伪装( -j MASQUERADE)。
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
# 开启IP转发
echo 1 > /proc/sys/net/ipv4/ip_forward
注意这时你没有做任何的包过滤:如果需要,参见 the Packet Filtering HOWTO。

--------------------------------------------------------------------------------
 
4、2 那么ipmasqadm呢?
这个完全取决于用户,所以我不担心向后兼容的问题。你可以简单的使用“iptables -t nat”做端口转发。例如,在Linux2.2你要做:
# 在2.2内核,把指向1.2.3.4 8080端口的TCP包转到192.168.1.1的80端口
ipmasqadm portfw -a -P tcp -L 1.2.3.4 8080 -R 192.168.1.1 80
现在你可以这样:
# 2.4内核,在NAT(-t nat)表中加入一条规则,在路由之前(-A PREROUTING)指向
 
# 1.2.3.4(-d 1.2.3.4)8080端口(--dport 8080)的TCP包(-p tcp)目标地址(-j DNAT)
# 被重定向到 192.168.1.1的80端口(--to 192.168.1.1:80)。
iptables -A PREROUTING -t nat -p tcp -d 1.2.3.4 --dport 8080 -j DNAT --to 192.168.1.1:80

--------------------------------------------------------------------------------
 
5、NAT可以控制什么
你需要创建NAT规则,以告诉内核哪些连接将被改变和如何改变。要做到这一点,我们要用到一个用处很多的iptables工具,并告诉它用指定的“-t nat”选项修改NAT表。
NAT规则表包含三个称为“链”的列表:每个规则都按顺序检查包,直到有一个匹配。其中两个被称为PREROUTING(用于 Destination NAT,当包进入时检查),POSTROUTING(用于Source NAT,包离开时检查),第三个叫OUTPUT,这里可以忽略。
如果我有足够的艺术天分的话,下面的

相关内容

    暂无相关文章