📄 1638.html
字号:
我把NAT分为两种不同的类型:源NAT(SNAT)和目标NAT(DNAT)。(译者注:以下不再翻译SNAT和DNAT,直接用Source NAT和Destination NAT)<br>
Source NAT是指修改第一个包的源地址:也就是说,改变连接的来源地。Source NAT会在包送出之前的最后一刻做好post-routing(动作),伪装是SNAT的一种特殊形式。<br>
Destination NAT 是指修改第一个包的目标地址:也就是说,改变连接的目的地。Destination NAT 总是在包进入以后(马上)进行before routing(动作)。端口转发、负载均衡和透明代理都属于DNAT。<br>
<br>
--------------------------------------------------------------------------------<br>
<br>
4、 从2.0和2.2内核的快速转换<br>
如果你还在为从2.0(ipfwadm)到2.2(ipchains)的转换手忙脚乱的话,很抱歉。不过这也算是个喜忧半参的消息。<br>
首先,你可以轻松的使用ipchains和ipfwadm,就像从前一样。不过你需要安装最新发布的netfilter中的“ipchains.o”或者“ipfwadm.o”内核模块。它们是互斥的(你会被警告),而且不能和任何其他netfilter模块结合。<br>
一旦这其中某个模块被载入,你可以像以前一样使用ipchains和ipfwadm,不过仍有以下区别:<br>
用ipchains -M -S,或者用ipfwadm -M -s设置伪装超时不再有效。因为超时已经转移到新的NAT构架中,所以这不能做任何事。<br>
在详细的伪装列表中,init_seq、delta和previous_delat字段始终为零。<br>
归零和列表计数器的 -Z -L不再有效:计数器不能被归零。<br>
这类向后兼容的部分可能和大部分连接都不能有效配合:不要在你的公司网关中使用<br>
开发者们还要注意:<br>
无论是否使用伪装,现在可以绑定61000 - 65095之间的端口。以前的伪装代码占用了这部分端口,因此不能使用。<br>
尚未成文的“getsockname”,透明代理程序可以用来发现那些已不再工作的连接的真实目的地址。<br>
尚未成文的“bind-to-foreign-address”同样还未启用:这个用于完整透明代理的设想。<br>
<br>
--------------------------------------------------------------------------------<br>
<br>
4、1 我只想伪装!救命!<br>
这是绝大部分人想要的。如果你用PPP拨号上网来动态得到IP (如果你不知道,那应该就是的)你可能只想告诉你的机器,所有来自内部网络的包,要看上去同PPP连接服务器上的包一样。<br>
# 装载NAT模块(这取代了其他的)<br>
modprobe iptable_nat<br>
# 在NAT表中(-t nat),路由后 POSTROUTING 加入一条规则(-A)<br>
# 所有由ppp0送出的包(-o ppp0) 会被伪装( -j MASQUERADE)。<br>
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE<br>
# 开启IP转发<br>
echo 1 > /proc/sys/net/ipv4/ip_forward<br>
注意这时你没有做任何的包过滤:如果需要,参见 the Packet Filtering HOWTO。<br>
<br>
--------------------------------------------------------------------------------<br>
<br>
4、2 那么ipmasqadm呢?<br>
这个完全取决于用户,所以我不担心向后兼容的问题。你可以简单的使用“iptables -t nat”做端口转发。例如,在Linux2.2你要做:<br>
# 在2.2内核,把指向1.2.3.4 8080端口的TCP包转到192.168.1.1的80端口<br>
ipmasqadm portfw -a -P tcp -L 1.2.3.4 8080 -R 192.168.1.1 80<br>
现在你可以这样:<br>
# 2.4内核,在NAT(-t nat)表中加入一条规则,在路由之前(-A PREROUTING)指向<br>
<br>
# 1.2.3.4(-d 1.2.3.4)8080端口(--dport 8080)的TCP包(-p tcp)目标地址(-j DNAT)<br>
# 被重定向到 192.168.1.1的80端口(--to 192.168.1.1:80)。<br>
iptables -A PREROUTING -t nat -p tcp -d 1.2.3.4 --dport 8080 -j DNAT --to 192.168.1.1:80<br>
<br>
--------------------------------------------------------------------------------<br>
<br>
5、NAT可以控制什么<br>
你需要创建NAT规则,以告诉内核哪些连接将被改变和如何改变。要做到这一点,我们要用到一个用处很多的iptables工具,并告诉它用指定的“-t nat”选项修改NAT表。<br>
NAT规则表包含三个称为“链”的列表:每个规则都按顺序检查包,直到有一个匹配。其中两个被称为PREROUTING(用于 Destination NAT,当包进入时检查),POSTROUTING(用于Source NAT,包离开时检查),第三个叫OUTPUT,这里可以忽略。<br>
如果我有足够的艺术天分的话,下面的见图会准确的说明上述概念:<br>
<br>
_____ _____<br>
/ / <br>
PREROUTING -->[Routing ]----------------->POSTROUTING-----><br>
D-NAT/ [Decision] S-NAT/<br>
| ^<br>
| |<br>
| |<br>
| |<br>
| |<br>
| |<br>
| |<br>
--------> Local Process ------<br>
<br>
上述每一点,当我们查看连接(中)的包时,如果是一个新的连接,我们查看 NAT表中相对应的链,看看需要做些什么。其结果就会作为对这个连接后面所有包 的反应。<br>
(译者注:此处的连接是指一个HTTP会话之类的连接,而非物理上的线路、节点)<br>
<br>
--------------------------------------------------------------------------------<br>
<br>
5、1 用iptables做简单的选择<br>
下面列出了iptables的一些标准选项。所有双横杠(--)的选项都是可以缩写的。只要iptables可以将它们与其他选项区分开来就够了。如果你的内核是以模块方式支持iptables的,你需要先用命令:insmod ip_tables来加载ip_tables.o<br>
这是最重要的选项表格选择,“-t”。对所有NAT操作,你都需要使用'-t nat'以指定NAT表。其次重要的是'-A',添加一个新的规则到链的末尾(例如'-A POSTROUTING'到POSTROUTING链),或者'-I'从最开始插入一个规则(例如'-I PREROUTING')。<br>
你可以指定你想要进行NAT的包的源(地址)('-s' 或者'--source')和目的(地址)('-d' 或 '--destination')。这两个选项可以跟单个IP地址(例如192.168.1.1),一个名字(例如www.gnumonks.org),或者一个网络地址(例如192.168.1.0/24或192.168.1.0/255.255.255.0[译者:这二者是等价的,只是表示方法不同])。<br>
你可以指定进入或送出的匹配接口。不过能否指定取决于你想要写入规则的那个链:PREROUTING链你只能选择进入接口,POSTROUTING你只能选择送出接口。如果用错了,iptables会给出一个错误。<br>
<br>
--------------------------------------------------------------------------------<br>
<br>
5、2 关于应当挑选哪些包来拆分(mangle)的要点<br>
我上面说了你可以指定源地址和目标地址。如果忽略源地址选项,那么所有源地址都会被匹配,同样,如果忽略目标地址,所有目标地址都将被匹配。<br>
你还可以标出一个指定的协议('-p'或'--protocol'),诸如TCP或者UDP;那么只有这类协议的包会被匹配。这么做的主要原因是指定了协议,就可以增加额外的选项:指定'--source-port'源端口和'--destination-port'目的端口选项(可缩写为'- sport'和'-dport')。<br>
这些选项让你可以只匹配那些特定源端口及目标端口的包。这些对于重定向Web请求(TCP 80或8080端口)而不影响其他包非常有用。<br>
这些选项必须跟在'-p'选项后面(这可能会对加载该协议的连接库有一定影响)。你可以使用端口号,或者来自/etc/serverices文件的(端口)名。<br>
所有这些你可以对一个包作出的不同选择都详细的列在那详细得可怕的使用手册中了(man iptables)。(译者注:参见iptables man page中文版)<br>
<br>
--------------------------------------------------------------------------------<br>
<br>
6、说说如何拆分包吧<br>
现在我们知道如何选择我们想要拆分的包了。为完成我们的规则,我们需要准确的告诉内核我们想要它如何做。<br>
<br>
--------------------------------------------------------------------------------<br>
<br>
6、1 Source NAT<br>
你想要进行Source NAT,改变连接的源地址。这在POSTROUIING链中完成,就在它将送出去的最后一刻。这是一个重要的细节,所有Linux本机上的其他任何东西(路由、包过滤)都会看见那个尚未改变的包。也意味着'-o'(送出接口)选项可用了。<br>
用指定'-j SNAT'来进行Source NAT,'--to-source'选项指定一个或一段IP地址,(加上)一个或一段可选的端口号(只能用于UDP和TCP协议)。<br>
# 改变源地址为1.2.3.4<br>
# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 1.2.3.4<br>
<br>
# 改变源地址为1.2.3.4、1.2.3.5或者1.2.3.6<br>
# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 1.2.3.4-1.2.3.6<br>
<br>
# 改变源地址为1.2.3.4,端口1-1023<br>
# iptables -t nat -A POSTROUTING -p tcp -o eth0 -j SNAT --to 1.2.3.4:1-1023<br>
<br>
--------------------------------------------------------------------------------<br>
<br>
6、1、1 伪装<br>
Source NAT的一个特例被称作伪装。它只能被用于动态分配IP地址的情况。例如标准拨号服务(静态IP地址请用SNAT)。<br>
你无需为IP伪装明确指定源地址。它会使用包送出的那个接口(地址)作为源地址。不过更重要的是,如果那个线路关闭了的话,连接(无论如何都会丢失了)会被忘掉,意味着启用新的IP后返回的包就会有点问题了(指那些响应掉线前发出的包的包)。<br>
# 伪装所有由ppp0送出的东西<br>
# iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE<br>
<br>
--------------------------------------------------------------------------------<br>
<br>
6、2 Destination NAT<br>
用于PREROUTING链,包刚刚进入的时候。意味着本机上的任何东西看见的都是“真正”的目的地(译者注:即已修改过的目的地址)。也意味着'-i'(进入接口)可用了。<br>
用指定'-j DNAT'来进行Destination NAT,'--to-destination'选项指定定一个或一段IP地址,(加上)一个或一段可选的端口号(只能用于UDP和TCP协议)。<br>
# 改变目标地址为5.6.7.8<br>
# iptables -t nat -A PREROUTING -i eth0 -j DNAT --to 5.6.7.8<br>
# 改变目标地址为5.6.7.8、5.6.7.9或5.6.7.10<br>
# iptables -t nat -A PREROUTING -i eth0 -j DNAT --to 5.6.7.8-5.6.7.10<br>
# 改变Web传送的目标地址为5.6.7.8,8080端口<br>
# iptables -t nat -A PREROUTING -p tcp --dport 80 -i eth0 -j DNAT --to 5.6.7.8:8080<br>
<br>
--------------------------------------------------------------------------------<br>
<br>
6、2、1 重定向<br>
Destination NAT的一个特例被称为重定向。它相当于对进入接口进行DNAT的简单方便的一种形式。<br>
# 发送进入的80端口的Web传输到我们的Squid(透明)代理<br>
# iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j REDIRECT --to-port 3128<br>
注意Squid需要被配置为透明代理。<br>
<br>
--------------------------------------------------------------------------------<br>
<br>
6、3 深层次的映射<br>
还有一些可能大部分人不会用到的NAT的细节。<br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -