简易 NAT 服务器
时间:2006-02-10 来源:dzsgo
-
我想,大家对于 NAT 一定是有所耳闻才对,不过,到底什么是 NAT 呢?NAT 其实是 Network Address Translation 的简写,字面上的意思是『网络地址的传送』,他主要的功能就是在提供内部私有网络的计算机之频宽分享了。简单的说,NAT 的功能就是『 IP 分享器』咯!(注:NAT 主机的功能相当的多,不过,这里我们仅说明频宽分享的部分!)。
- 这个 client 的 gateway 设定为 NAT 主机,所以当要连上 Internet 的时候,该封包就会被送到 NAT 主机啦,这个时候的封包 Header 之 source IP 为 192.168.1.100 喔;
- 而透过这个 NAT 主机,她会将 client 的对外联机封包的 source IP ( 192.168.1.100 ) 伪装成 ppp0 ( 假设为拨接情况 )这个接口所具有的公共 IP 啰,因为是公共 IP 了,所以这个封包就可以连上 Internet 了!同时 NAT 主机并且会记忆这个联机的封包是由哪一个 ( 192.168.1.100 ) client 端传送来的;
- 由 Internet 传送回来的封包,当然由 NAT 主机来接收了,这个时候, NAT 主机会去查询原本记录的路由信息,并将目标 IP 由 ppp0 上面的公共 IP 改回原来的 192.168.1.100 ;
- 最后则由 NAT 主机将该封包传送给原先发送封包的 Client 啰!
NAT 的功能
我们由 网络基础当中知道,要能够连接上 Internet 必须要具有『公共 IP (Public IP)』才行,内部私有 IP (Private IP) 是不能直接与 Internet 进行数据沟通的。好了,今天假设您是一家公司的主管,或者是一间学校的信息主任,而且您所负责的单位内有 20 部计算机好了,这 20 部计算机都需要能够连上 Internet ,并可以进行任何 Internet 的服务要求,请问您是否需要具备有 20 个公共 IP 呢?如果真的要提供 20 个公共 IP 的话,以最经济的价格来说,我们可以申请 Seednet 的 512/64 (下载/上传) 拨接制 ADSL ,每个专线都可以具有五个 IP ,因为我们有 20 部主机,所以就需要四条电话线~呵呵!怕了吧!光是接线与申请 ADSL 的流程就会让人崩溃,更不用说申请到之后还需要在每一部计算机上面设定拨接、管制计算机使用性、进行防毒等等的工作,光是用想的,就已经很头大了,更不用说实际去作.....
那么应该要怎么办呢?比较聪明的朋友已经想到要去买 IP 分享器来分享网络频宽了!那么 Linux 是否能够达到 IP 分享器的功能!?当然可以啦!那就是 NAT 主机的能力之一啰!我们在之前的 Router 设定当中,提过路由的概念了,封包的传送主要是透过路由的信息,但是,私有路由是不能直接与 Internet 沟通的啊!因此用 Linux 作为 Router 时,如果 Linux 主机本身就是仅有私有 IP ,自然也就无法直接连接到 Internet 上面去了。
到底该如何是好?呵呵!这个时候就得要回头谈一谈 TCP 封包的概念咯。由网络基础 章节里面提到的 TCP 封包的架构图,我们可以发现 TCP 封包里头有来源与目的地的 IP 及 port 的信息在 Header 里面,那么如果透过某些技术,来改变 TCP 封包的 header 呢?如果能够将 TCP 封包的来源 IP 由本来的 Private IP 变成 Public IP 的话,不就可以连接到 Internet 了吗?!呵呵!没错没错!谈到重点了!就是这样啦!NAT 主机的重要功能之一就是将来自内部 Client 端计算机封包的 Header 的 IP 『伪装』成公共 IP ,而提供 Client 端连上 Internet 的一个方法!(注:当然啦, IP 分享器也是使用同样的道理!)。那么 Linux 是用什么机制达到这样的功能?还记得简易防火墙设定当中提到的 iptables 吧?!iptables 可以进行封包的分析,当然,他还可以进行封包信息的修改呢!那么整个流程是如何呢?如下图所示,当我的区域内的具有 192.168.1.100 的 client 要对外联机的时候:
如果是在 iptables 的内建 table 当中,与 NAT 有关的就是 nat table 的 POSTROUTING 那个链了!就是简易防火墙当中的图九的示意图喔!也就是说,整个封包其实只有经过 NAT 主机的 iptables 机制在伪装 IP 与修改路由信息而已,并没有进入 NAT 主机内部啦! ^_^!由上面的信息我们可以知道一件事,那就是:『您的 NAT 主机至少需要有一个私有 IP 与一个公共 IP 才行』喔!而且,『NAT 主机,一般来说,也是一部 Router 喔!』如果 Router 两边都是私有 IP 或都是公共 IP 时,Linux 主机只要有 Router 的功能即可,若是两边分别为公共与私有 IP 时,才需要以 iptables 来启动 NAT 的功能。
其实 NAT 的功能也可以简单的这样想:『当您在私人赛车场上比赛的时侯,不必管您是否有注册过的车牌﹔但开到马路上却非得要一个监理站核发的车牌不可。如果您要将跑车开到街道上,必须要改挂一个合法的车牌。这时候,赛车场老板(NAT)自有办法帮您弄一个就是了。』!这样可以了解了吗?
联机示意图:
由上面的说明您应该可以了解了吧?!没错,您的 NAT 主机上面,至少需要『两块网络接口』请注意,鸟哥说的是『网络接口』而不是『网络实体适配卡』呦!以拨接为例,由于拨接之后会产生 ppp0 这个拨接后产生的网络接口,加上原本的实体网络接口,那么自然就有两个以上的网络接口啰!这么说应该很容易了解了吗?底下我以两块实体网络适配卡的布线情况作为联机的示意图,至于一块网络卡进行 NAT 的图示,将在待会说明啰。
图一、两块网络卡的 NAT 主机配置
-
在上面的图示当中,很清楚吧!我们的 Linux 共有两块实体适配卡,一块接在调制解调器 上面,一块接在 Hub/Switch 上面,并且以此 Hub/Switch 连接所有的局域网络内的计算机,以组成内部的私有网域!鸟哥个人是比较喜欢这样的接线方式啦!不过,人人各有其所好,而且这样的情况也不见得适合所有的人,所以还是得了解一下其它种类的连接方法!好吧,等一下再告诉您~ ^_^""
- Kernel 2.2.xx :使用 ipchains 做封包伪装的技术;
- Kernel 2.4.xx :使用 iptables 做封包伪装的技术!
- 频宽分享:我想,架设 NAT 的朋友大部分都是希望可以达到频宽分享的目的的!这毕竟是 NAT 主机的最大功能啰!
- 安全防护:咦!关安全防护什么事呀!?别忘了, NAT 之内的 PC 联机到 Internet 上面时,他所显示的 IP 是 NAT 主机的公共 IP ,所以 Client 端的 PC 当然就具有一定程度的安全了!最起码人家在进行 port scan 的时候,就侦测不到您的 Client 端的 PC 啦!安全多了!
核心版本:
我们在简易防火墙设定当中就提过了,核心与防火墙机制是有关系的,也就是:
所以,还是请仔细的检查一下您的核心版本吧!(用 uname-r 来察看)。简单的判别方法,如果是 Red Hat 7.0 ( 含 7.0 )以前的版本,使用的是 2.2.xx 的核心,自然只有 ipchains 而已,而如果是 Red Hat 7.1 ( 含 7.1 ) 以后的版本,则使用的是 Kernel 2.4.xx ,因此最好使用 iptables 的技术!因为 2.4.xx 的 IP 处理模块当中,大部分都是针对 iptables 来作为处理的软件, ipchains 的模块已经不含在 2.4.xx 里头了!由于我是以 Red Hat 7.2, 7.3 与 9 作为范例的,所以自然以 iptables 为准啰!如果还想要以 ipchains 来进行架设 NAT 的朋友,不妨参考一下底下这篇:
谁需要 NAT 架设:
由前面 NAT( Network Address Translation ) 的功能介绍,我们知道他可以作为频宽分享的主机,当然也可以管理一群在 NAT 主机后面的 Client 计算机!呵呵!所以 NAT 的功能至少有这两项:
-
NAT 的设定可以使用一块网络卡,当然也可以使用两块网络卡啦!鸟哥个人还是比较建议使用两块网络卡来完整的隔开私有网域的内外部分,毕竟还是比较安全一些!不怕内部私有网域的高手作怪啊! ^_^
- 关闭一些系统服务的 port :
为了安全起见,还是检查一下吧!首先,我们需要先来了解一下我的 Linux 主机的功用为何?!如果只是单纯的要作为 NAT 的话,那么 Linux 主机所开放的 port 是越少越好!鸟哥可不希望您开机了大约一个星期,就开始苦苦哀嚎说自己的主机无法以 root 登入了......。关闭 port 的方法与选择『系统一定需要的服务』的介绍在 限制联机的埠口 里面已经说的很清楚了!我以 Red Hat 9 来说明:1. 使用 ntsysv 设定开机时启动的服务项目:
[root@test root]# ntsysv
只要选择底下几个服务即可:
atd, cron, iptables, keytables, network, random, syslog, xinetd2. 重新开机让设定生效:
[root@test root]# reboot3. 观察目前的 port 开启多少个?
[root@test root]# netstat -an | more
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags Type State I-Node Path
unix 7 [ ] DGRAM 944 /dev/log
unix 2 [ ] DGRAM 3162963
unix 2 [ ] DGRAM 739227
unix 2 [ ] DGRAM 739189
unix 2 [ ] DGRAM 1070
unix 2 [ ] DGRAM 953
unix 2 [ ] STREAM CONNECTED 690
# 注意:尽量不要看到有 LISTEN 的咚咚!最多就是有 ssh 就好了!除非您有其它的服务! - 实体线路配置图:
怎么安装联机呢?赶快买线材来架设吧!由于 Linux 主机只有一张网络卡,所以所有的装置(包括 Linux 主机, client 端计算机, 调制解调器等等)都需要接在 Hub/Switch 上面,有点像底下的样子:
图二、一块网络卡的 NAT 主机配置
这个时候请特别留意啦!如果是使用 ADSL 拨接制的话,那么在 Linux 主机上应该会有安装 rp-pppoe 这个东西,并且在拨接之后会产生 ppp0 这个网络接口,同时不要忘了,启动网络卡的时候不是就已经有 eth0 这个实体网络界面的设定吗?,嘿嘿!那么我们不是就有两个网络接口了吗?!没错!就是这样!但是,如果是 Cable 或者是其它的固定制的方法的话,那么跟这个也差不多啦!不过由于 Cable 的方式没有自动产生两个以上的网络界面,所以就需要设定 IP Alias 啰,也就是 eth0:0 啦!亦即就是以 eth0 跟 eth0:0 这两个接口来联机啰!反正,只有一张网络卡,也可以进行 NAT 的啦! ^_^""
- 设定网络接口:
我们分别以拨接、 Cable 及固定 IP 为例啦!
-
ADSL拨接制 :
在进入 Linux 并启动网络卡之后,我们会得到 eth0 这个界面,再加上拨接之后的 ppp0 界面,所以我们就已经会有个两网络接口,分别是 ppp0, eth0!此外,我预计的私有网域的 IP 选用 192.168.1.0/24 这个 C Class 的网域,其中, Linux NAT 主机的私有 IP 选择为 192.168.1.2 这一个!
- 第一个网络接口 -- ppp0 -- 的设定:这个东西应该不难吧!就是我们在 连上 Internet 一文里头提到的关于 rp-pppoe 的拨接上网方式。
- 实体网络卡 -- eth0 -- 的设定:请注意,如果您要同时使用 ppp0 及 eth0 ,那么请在拨接之前启动 eth0 吧!以取得内部的 eth0 这个网络界面的设定!( 注:如果您不知道如何设定的话,那么就请照我的方式来填写即可 ):
[root@test root]# vi /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO=static
BROADCAST=192.168.1.255
IPADDR=192.168.1.2
NETMASK=255.255.255.0
NETWORK=192.168.1.0
ONBOOT=yes <==重要的地方在这里!请设定为 yes 呦!
# 如果您不晓得应该如何设定的话,就照上面的打就好了!
在 Cable 的情况又不太相同了!这个时候只有两块网络接口,分别是 eth0, eth0:0 啰!设定为:
- 实体网络卡 -- eth0 -- 的设定:请注意,由于 cable 使用的是 DHCP 主机,所以这个时候请特别留意您底下的设定呦!( 注:如果您不知道如何设定的话,那么就请照我的方式来填写即可 ):
[root@test root]# vi /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO=dhcp <==这里最重要!
BROADCAST=192.168.100.255
IPADDR=192.168.100.1
NETMASK=255.255.255.0
NETWORK=192.168.100.0
ONBOOT=yes
# 如果您不晓得应该如何设定的话,就照上面的打就好了! - 虚拟网络接口 --eth0:0 的设定:在 IP Alias 的设定当中,我们已经在 Router 当中说明过多次了!请务必回到该章节再阅读一次,如果您不记得如何设定的原理的话!
[root@test root]# vi /etc/sysconfig/network-scripts/ifcfg-eth0:0
DEVICE=eth0:0
BOOTPROTO=static
BROADCAST=192.168.1.255
IPADDR=192.168.1.2
NETMASK=255.255.255.0
NETWORK=192.168.1.0
ONBOOT=yes
# 如果您不晓得应该如何设定的话,就照上面的打就好了!
跟 cable 的设定几乎一模一样,只有两个接口,分别是 eth0, eth0:0,需要特别注意的是 eth0 这个东西,您必须要『填写正确的 IP, netmask, network, broadcast 而且 ONBOOT=yes 才可以!』,而 eth0:0 则与上面相同!
-
启动私有网域的 IP 网络接口:
启动之后顺便观察一下路由的信息![root@test root]# ifdown eth0
[root@test root]# ifup eth0
[root@test root]# route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
swks81-1.adsl.s * 255.255.255.255 UH 0 0 0 ppp0
192.168.1.0 * 255.255.255.0 U 0 0 0 eth0
127.0.0.0 * 255.0.0.0 U 0 0 0 lo
default swks81-1.adsl.s 0.0.0.0 UG 0 0 0 ppp0
# 嘿嘿!这样就是成功啦!注意,上面这个路由是以 adsl 拨接为例的! - 第一个网络接口 -- ppp0 -- 的设定:这个东西应该不难吧!就是我们在 连上 Internet 一文里头提到的关于 rp-pppoe 的拨接上网方式。
- 设定其它档案:
还有一些网络的相关档案要设定呦!/etc/hosts, /etc/resolv.conf, /etc/sysconfig/network,
别忘了我们还有其它的档案要设定呦!很重要的:1. 将私有 IP 加入到 /etc/hosts 里面去吧!
[root@test root]# vi /etc/hosts
127.0.0.1 localhost
192.168.1.1 linux001
192.168.1.2 linux002
.......(略)......
192.168.1.100 linux100
.......(略)......
192.168.1.254 linux2542. 将 DNS 的 IP 写到 /etc/resolv.conf 里面去,这里以中华电信跟 Seednet 为例
[root@test root]# vi /etc/resolv.conf
nameserver 168.95.1.1
nameserver 139.175.10.203. 设定主机名称跟 gateway 与否:
[root@test root]# vi /etc/sysconfig/network
NETWORKING=yes
HOSTNAME=your.domain.name <==写您的主机名称
GATEWAY= <==除非您是固定制的,不然这个不要填入任何东西! - 设计 NAT 的 shell scripts :
直接将一些指令写在 scripts 里头执行较快啦!正确的情况之下,目前您的 Linux 主机上面应该是已经可以正常的对外联机的才对!而且内部也已经可以正确的联机成功了才对!如果还没有成功的话,请赶快再到 局域网络设定 里头去查一查资料去!好了,接着下来只要执行一个程序,嘿嘿!就可以将 NAT 启动喔!这个就好玩了!因为基本上,我们使用的是 iptables 这个东西,自然就需要这个 ip_tables 的模块了!而查看模块与加载模块的指令分别为 lsmod, modprobe 哩!好了,您可以直接在命令提示字符底下进行工作:echo "1" > /proc/sys/net/ipv4/ip_forward
modprobe ip_tables
modprobe ip_nat_ftp
modprobe ip_nat_irc
modprobe ip_conntrack
modprobe ip_conntrack_ftp
modprobe ip_conntrack_irc
/sbin/iptables -F
/sbin/iptables -X
/sbin/iptables -Z
/sbin/iptables -F -t nat
/sbin/iptables -X -t nat
/sbin/iptables -Z -t nat
/sbin/iptables -P INPUT DROP
/sbin/iptables -P OUTPUT ACCEPT
/sbin/iptables -P FORWARD ACCEPT
/sbin/iptables -t nat -P PREROUTING ACCEPT
/sbin/iptables -t nat -P POSTROUTING ACCEPT
/sbin/iptables -t nat -P OUTPUT ACCEPT
/sbin/iptables -t nat -A POSTROUTING -o ppp0 -s 192.168.1.0/24 -j MASQUERADE[root@test root]# cd /usr/local/virus/iptables
[root@test iptables]# vi iptables.rule
#!/bin/bash
#...(略)...
# 设定对外的网络接口
EXTIF="ppp0"
# 设定对内的网络接口与内部私有网域的设定
INIF="eth0"
INNET="192.168.1.0/24" # This is for NAT's network
#....(略)....
if [ "$INIF" != "" ]; then
/sbin/iptables -A INPUT -i $INIF -j ACCEPT
echo "1" > /proc/sys/net/ipv4/ip_forward
/sbin/iptables -t nat -A POSTROUTING -s $INNET -o $EXTIF -j MASQUERADE
fi
#...(略)...
- Client 端的设定参数:包含的是网络的设定参数而已!这个等一下我们在客户端设定当中再讲!
- eth0 为对内的实体网络卡,具有私有 IP ,其 IP 为 192.168.1.2 。
- eth1 为对外的实体网络卡,被用来进行 ADSL 的拨接,所以开机的时候不要设定 on !
- 关闭一些系统服务的 port :与前一节相同!
- 实体线路配置图:与图一的配置相同。
- 设定网络接口:
重要的地方在安装第二块网络卡!安装网络卡的相关技巧请前往 连上 Internet 参考!不过,对于第二块网络卡的安装,在这里有些建议:基本上,第二张网络卡最好不用使用与第一张相同芯片的卡,例如您第一张卡使用 RTL 8139,那第二张卡最好使用别的卡。因为鸟哥曾经发现,在鸟哥的 RedHat 6.1 英文版中,安装两块相同的 ( 同公司出的 ) RTL8139 ,结果竟然两张卡的输出输入都是经由第一张!也就是说,第二张卡根本就没有用处!并且,也很容易发生 eth1 与 eth0 捉错的情况!所以,请记得,『第二张网络卡尽量不要使用与第一张网络卡相同芯片的卡!』当然,您要使用同一个芯片的网络卡也是可以啦!目前我的机器上面就是使用两块 RTL8139 的网络卡。不过,在安装的时候请特别留意,不要同时安插两块,最好是一块安装完毕之后,再安装另一块!会比较好一点啦!安装的步骤可以是(请注意,我以 ADSL 拨接为例的,其中, eth0 为对内, eth1 为对外,请依照您的设定来修正呢!):
- 关机、硬件安装:这个不用再提了吧!,先关机,然后拆开外壳,插入PCI网络卡即可;
- 开机、硬件扫瞄:然后再开机,而于开机的过程中,您的 Linux 会主动去找到这一张网络卡(如果这张卡是有被 Linux 支持的!);
- 安装网络卡驱动程序:如果在上一步骤中,您的网络卡并不能被捉到,哪就比较伤脑筋!请到连上 Internet 参考网络卡的驱动程序安装方法
- 检视设定 /etc/sysconfig/network-scripts/ifcfg-eth1:在安装完了网络卡的驱动程序之后,在 /etc/sysconfig/network-scripts/ 中,应该会有 ifcfg-eth1 这一个档案。请设定他吧!因为是对外卡,我这里假设他是利用 ADSL 拨接的,所以可以是这样:
[root@test root]# vi /etc/sysconfig/network-scripts/ifcfg-eth1
DEVICE=eth1
BOOTPROTO=static
BROADCAST=192.168.0.255
IPADDR=192.168.0.2
NETMASK=255.255.255.0
NETWORK=192.168.0.0
ONBOOT=no <==这里很重要!对外用来拨接的卡不要在开机的时候启动啦!
- 设定其它档案:
其它一些网络的相关档案也要设定!亦即/etc/hosts, /etc/resolv.conf, /etc/sysconfig/network,设定的方式跟前一小节相同!
- 设计 NAT 的 shell scripts :
基本上,设定的方式跟上面也是一模一样的啦!您依旧可以仅使用前一小节的 script 来进行 NAT 的设定,只是要注意那个粗体字部分的设定,如果您跟我的情况不同,那么就需要修改一下啦!赶快 下载 script 吧!
一块网络卡的 NAT 架设:
刚刚上面我们已经提过了,要架设 NAT 的话,只要『两块网络接口』就够了,倒不一定需要两块『实体网络卡( NIC )』,是的!所以鸟哥先以较为便宜的方式(因为少了一块网络卡呀!)来介绍 NAT 的架设!底下是我们介绍的安装步骤:
两块网络卡的 NAT 架设:
真是的,这个部分的联机架设在 局域网络联机当中已经提过很多遍了!这里不再重复的说明!仅列出几个重要的地方,基本上,跟刚刚一张网络卡的设定方式几乎完全相同,只是那个 eth0:0 变成了 eth1 而已啦!鸟哥的设定为:
同样的,我们的设定方式为:
在整个 NAT 的设定当中,最经典的错误联机讯息来自于 路由信息 的错误啦!这个在我们的 连上 Internet 及 网络侦测文章当中已经说明过了,不过,我们这里再次提醒一下!免得您又犯了同样的错误了!由于网络在进行连接的时候,都会指定所谓的 router 或者是 gateway 的设定,除非是来自于广播的网域之联机。而我们在设定网络时,常常会犯了一个错误,那就是指定错了 Gateway 了!请您参考一下连上 Internet 一文的设定方式,在 ADSL 拨接及 Cable 联机时,请『务必』不要设定 gateway 才好!
再来,请常下达 route的指令来观察一下您的 linux 主机的路由设定是否正确呦!
- network 设定需要为: 192.168.1.0
- broadcast 设定需要为: 192.168.1.255
- netmask 设定需要为 255.255.255.0
- IP 设定需要为 192.168.1.1 ~ 192.168.1.254 之一,且『不能重复』
- Gateway 或者说是 通讯闸 需要设定为您的 Linux 的对内 IP ,以我的例子来说,就是 192.168.1.2 !
- DNS 的设定:这个最容易出错了,您的 DNS 设定需要是您的 ISP 给您的 DNS IP,如果您不知道的话,可以填入 168.95.1.1 这一个中华电信的 DNS 或者是 139.175.10.20 这一个 SeedNet 的 DNS 即可!千万不要设定为 192.168.1.2 呦!会连不出去!
- 对于 Client 端来说,由于已经经过了 IP 伪装的功能,所以基本上,您通过 NAT 主机连出去的封包的 IP 都会是『 NAT 主机对外的公共 IP 』,因此对于内部 Client 端而言,由于网络 Cracker 几乎都是根据 IP 来进行破坏,而因为您连出去的封包 IP 是 NAT 主机的公共 IP ,自然您的 Client 端就比较安全多了!基本上, Client 端在 NAT 之内,没有安装防火墙软件也还好,但是『防毒软件一定要安装!』因为您毕竟会接收电子邮件呀等等的,所以还是可能会中毒啦!!
- 对于 Server 端来说,我们仅仅设定一些简单的防火墙规则,而且在原本的 iptables.rule 当中还预设开启了许多的埠口,所以其实这样的一个主机并不是十分的安全的,因此,您最好还是自行将 iptables.rule 内的最后面的几个开放的埠口给他批注掉才好吶!(如果您的 NAT 主机仅想要负责频宽分享的功能的话!)