LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 6845|回复: 26

Linux网络管理员手册[共16章节][转帖]

[复制链接]
发表于 2002-4-24 11:07:32 | 显示全部楼层 |阅读模式
[这个贴子最后由北南南北在 2002/04/24 11:20am 编辑]

   
Linux网络管理员手册(1)
<p>第一章 网络绪论
1.1 历史
连网的主意大概与电讯事业本身一样的久远。考虑人们生活的石器时代,那时鼓可能已经用于在人们之间传递消息了。假释穴居人A想邀请穴居人B进行一场互扔石块的游戏,但是他们互相之间居住得太遥远,以至B听不见A的击鼓声。那么,A能够做些什么呢?他可以1)走到B的地方去,2)使用一个更大的鼓,或者3)询问C,C居住在他们中间的地方,来传递消息。这最后一个办法就叫做连网。
当然,我们已经比我们祖先的原始嗜好和设备有了长足的进步。现在,通过大量的线缆的集合,如光纤、微波、等等,我们用计算机进行相互间的对话来作星期六足球比赛的约会。[1] 下面,我们将涉及实现上述的手段和方法,但不考虑线缆,也不考虑足球的部分。
在本手册中,我们将讨论两种网络类型:基于UUCP的,和基于TCP/IP的。这是一些协议集和软件包,它们提供了在两台计算机之间传输数据的方法。在这一章中,我们将考虑这两种网络类型,并且讨论它们的基本原理。
我们定义网络是一个互相之间能够通信主机(hosts)的集合,这常常依赖于一些专用(指定)主机的服务,即是在参与者之间中继数据。主机通常就是计算机,但也不一定;也可以将X-终端或者智能打印机当作主机。少量的主机聚合也称为站点(sites)。
没有语言或者代码,进行通信是不可能的。在计算机网络中,这些语言共同地被称为协议(protocols)。然而,这里你不用关心协议是如何制定出来的,而是要,例如,考虑州长开会时注意到的高度形式化的行为代码。同样,用于计算机网络中的协议仅仅是两台或多台主机之间交换消息所用的非常严格的一些规则。 <p>1.2 UUCP网络
UUCP是Unix-to-Unix Copy的缩写。刚开始它是作为一个程序包,用于在串行线路上传输文件、确定这些传输的时间、并且在远程站点上启动程序的执行。自从七十年代末它第一次实现以来,已经历了很大的变化,但其提供的服务仍然很简单。他的主要应用仍然是在基于拨号连接的广域网中。
UUCP是贝尔实验室在1977年首先开发出来的,用于在他们的Unix开发站点之间的通信。在1978年中期,这个网络已经连接了80多个站点。它应用于运行电子邮件以及远程打印。然而,这个系统主要用于分发新软件以及调试程序。[2] 现今,UUCP不再被限制于这个环境内了。在许多种类的平台上已有免费的和商业的移植版本了,包括AmigaOS、DOS、Atari的TOS等等。
UUCP网络的主要缺点之一是它的低带宽。一方面,电话设备对最高传输速率有严密的限制。另一方面,UUCP链接很少有固定的连接;而是在有规则的时间间隔上主机拨号来相互连接。因此,大多数时间,是用于在UUCP网络上传输存储于某些主机磁盘上的邮件消息、等待下次连接的建立。
尽管有这些限制,世界各地仍有许多UUCP网络在运转着,主要是由计算机业余爱好者在运行着,它以合适的价格为私人用户提供网络访问。UUCP流行的主要原因是:与将你的计算机连接到大Internet电缆上相比,它是极其便宜的。为了使你的计算机成为一个UUCP节点,你只须有个modem、一个运行着的UUCP程序,以及愿意供你邮件和新闻的其他的UUCP节点。 <p>1.2.1 如何使用UUCP
UUCP后面的概念是非常简单的:就如同它的名字指出的一样,它基本上是将文件从一台主机上拷贝到另一台上去,但它也允许在远程主机上进行一定的操作。
假设你的机器允许访问名为swim的假想的主机,并且让它为你执行lpr打印命令。那么你可以命令行上键入下面一行在swim上打印出本书来:[3] <p>$ uux -r swim!lpr !netguide.dvi <p>这使得uux为swim调度了一个作业(job)。uux是UUCP组中的一个命令。这个作业由输入文件netguide.dvi、以及馈送该文件到lpr的请求组成。-r标志告诉uux不用立刻访问远程系统,而是将作业存储起来直到稍后时有个连接被建立起来。这叫作假脱机(打印)(spooling)。
UUCP的另一个特性是它允许通过几台主机转发作业和文件,假如它们合作的话。假定上面例子中的swim与groucho有一个UUCP链接,groucho中保存着大量的应用程序文档。为了下载文件tripwire-1.0.tar.gz到你的站点上,你可以发出 <p>$ uucp -mr swim!groucho!~/security/tripwire-1.0.tar.gz
trip.tgz <p>所创建的作业将请求swim从groucho取得该文件,并将文件送到你的站点,这里UUCP将把文件存为trip.tgz并且通过文件到达的邮件来通知你。这将分三步完成。首先,你的站点将作业送至swim。当下次swim与groucho建立了连接,就会下载该文件。最后一步是从swim到你站点的实际的传输。
目前,UUCP网络所提供的最重要的服务就是电子邮件和新闻。稍后我们将会讨论这些,所以这里我们仅给出一个概要的介绍。
电子邮件 – 简称email – 允许你与远程主机上的用户交换消息而无需实际地知道如何访问这些主机。控制一个消息从你的站点到达目的站点的任务是完全由邮件处理系统完成的。在一个UUCP环境中,邮件一般是通过在比邻的主机上执行rmail命令传送的,并把接收者的地址和邮件消息传给rmail。然后rmail将会转发消息到另一台主机上等等,直到消息到达目的主机为止。我们将在第13章中详细地讨论。
News可以最恰当地描述成一类分布式的电子公告板系统。绝大多数情况下,这个术语指的是Usenet News,它是直到目前为止最著名的估计有着120,000-参与站点的新闻交换网络。Usenet的起源可追溯至1979年,那时,在新的Unix-V7版本发布以后,三个研究生有了一个在Unix团体中通用信息交换的点子。他们整理了一些脚本,这成了第一个网络新闻系统。在1980年里,这个网络连接了北卡罗林纳州的两所大学里的duke、unc和phs网络。从这衍生出来,Usenet最终成长起来了。尽管它起初是一个基于UUCP的网络,现已不再限于单种类型的网络了。
信息的基本单元是文章,它可能被投寄到专用于某个特殊主题的新闻组的层次结构中。大多数站点仅仅接收全部新闻组的一个选集,而全部新闻组每天平均传送相当于60MB的文章。
在UUCP的世界中,news通常是按照从请求的组中收集所有的文章,并且打包成几批(batches),再通过一个UUCP链接来发送的。这几批文章被发送到接收站点,并在那里被送给了rnews命令来打开这几批数据包以及更进一步的处理。
最后,对于许多拨号上网的供公共访问的文档站点来说,UUCP也同样是一种供选择的方法。你通常可以这样来使用它们:使用UUCP拨号上网、作为来客(guest)用户登录、并从公共访问文档区域下载文件。这些来客帐号的登录名/口令通常是uucp/nuucp或者是其他一些类似的。 <p>1.3 TCP/IP网络
尽管UUCP可能是一种廉价的拨号上网链接的选择,但还存在着许多情况,在这些情况下,这种存储-与-转发的技术被证明是不灵活的,例如在局域网(LANs)的情况下。这通常是由位于同一幢建筑物、甚至是位于同一层的少数机器组成,它们互相连接以提供一个相似的工作环境。典型地来讲,你将在这些主机上共享文件,或者在不同的机器上运行分布式应用程序。
这些任务需要一种完全不同的连网途径。所有的数据被分解成更小的块(packets 包、分组),这些块被立刻转发到目的主机上,并再重新组合起来。而不是随同一个作业脚本转发整个文件。这类网络被称为包[分组]交换(packet-switched)网络。从其它方面来讲,这允许在网络上运行交互式的应用程序。当然,所付出的代价是大大地增加了软件的复杂性。
这种系统---不一定就是主机---所采用的解决方案就是著名的TCP/IP。在本节中,我们将看一下它的基本概念。 <p>1.3.1 TCP/IP网络引言
TCP/IP的起源可以上溯到1975年美国DARPA(Defense Advanced Research Projects Agency 国防部远景规划局)支助的研究计划。那是个试验性的网络,ARPANET,在经证实成功以后,于1975年转入正常运行。
1983年,新的TCP/IP协议组被作为标准采用,并且网络中的所有主机必须使用它。当ARPANET最终成长为Internet时(ARPANET本身于1990年停止使用),TCP/IP的使用已经传播到Internet以外的网络上去了。最值得注意的是局域网络,但随着象ISDN等快速数字电话设备的出现,将来肯定也会应用于拨号上网的传输。
在贯穿以下几节的TCP/IP讨论当中,作为一个看待的具体实例,我们将考虑坐落在Fredland某地的Groucho Marx大学(GMU),绝大多数系部运行他们自己的局域网,有些系部共享一个局域网,有些有好几个局域网络。他们都是互连的,并且通过一个高速链接与Internet相连。
假设你的机器在数学系连接到局域网上,并且假设你的机器名为erdos。为了访问物理系的一个名为guark的主机,你键入以下命令:
$ rlogin quark.physics
Welcome to the Physics Department at GMU
(ttyq2) login:
在提示符下,输入你的登录名,假如说是andres,以及你的口令。这时你就进入了quark的shell,在那里你就可以象是在系统的控制台上一样键入各种命令。在你退出shell以后,就会退回到自己机器的提示符下。你刚才即使用了TCP/IP提供的即时的、交互式的应用程序:远程登录。
在你登录进quark时,你也会想要运行一个基于X11的应用程序,就象函数绘图程序,或一个PostScript预览器。为了让这个程序知道你想要把窗口显示在你的主机屏幕上,你就必须设置DISPLAY环境变量: <p>$ export DISPLAY=erdos.maths:0.0 <p>如果你现在运行你的应用程序,它将联系你的X服务器而不是quark的,并在你的屏幕上显示它的所有窗口。当然,这需要X11运行在erdos上。这里的要点是TCP/IP允许quark和erdos来回传送X11分组,并给了你这样一种幻觉,好象你只在单个系统上。在这里,网络几乎是透明的。
TCP/IP网络的另一个重要的应用程序是NFS,它代表网络文件系统(Network File System)。这是另一种透明使用网络的形式,因为它基本上允许你从其他主机上直接加载目录分层结构,所以它们就好象本地的文件系统一样。例如,所有用户的登录主目录可能在一台中心服务器机器上,局域网上所有其它主机都可以从它上面加载这个目录。这样做的效果是用户可以登录到任何机器上,并且会发现自己在同一个主目录中。类似地,仅在一台机器上安装需要大量磁盘空间的应用程序(比如象TeX),并且将这些目录导出到其它机器上。我们将在第十一章中再次讨论NFS。
当然,这些仅是在TCP/IP网络上你能做些什么的例子。这种可能性几乎是无限的。
我们现在进一步讨论TCP/IP工作的原理。你需要知道这些以理解如何和为什么要配置你的机器。我们将首先从分析硬件着手,然后慢慢地深入。 <p>1.3.2 以太网
在局域网中广泛使用的硬件类型就是众所周知的以太网(Ethernet)。它由主机通过连接器与之连接的单根电缆、三通头或收发器组成。简易以太网安装起来一点不贵,而且其网络传输速率达到每秒10M,这也基本上说明了它为什么如此普及。
以太网可分成三类,分别称为粗缆(thick)、细缆(thin)和双绞线(twisted pair)。细缆和粗缆以太网都使用同轴电缆,只是粗细不同以及与主机连接的方式不同。细缆以太网使用一个T形的“BNC”连接头,两端连电缆,一头旋到计算机背面的一个插头上。粗缆以太网需要在电缆上钻一个小孔,并且使用一个“吸血鬼式的三通头”连接收发器。这样,一个或多个主机就能连接到收发器上。以太网的细缆和粗缆使用的长度最长分别可达200米和500米,因此它们也分别称为10base-2和10base-5。双绞线使用一根由两根铜线做成的线缆,也就是在普通电话装置中用的那种,但通常还需要另外一些硬件。它也以10base-T知名。
尽管将一台主机加入粗缆以太网有些烦琐,但不会断开网络。要往细缆以太网装置中增加一台主机的话,就不得不中断网络服务几分钟,因为需要切断电缆以接入一个连接头。
许多人偏爱细缆以太网,因为它非常便宜:PC网卡售价只有50美元左右,并且电缆每米也只有几美分。然而,对于大规模的安装,粗缆以太网则更适合。例如,GMU数学系的以太网使用的是粗缆,所以每当往网上增加一台主机时就不需要中断网络。
以太网技术的缺点之一是它有限的电缆长度,这妨碍了它在除局域网以外地方的使用。然而,几个以太网段可以使用中继器、桥接器或路由器来相互连接在一起。中继器只是简单地在两个或多个网段之间拷贝信号,所以,所有用其连接在一起的网段将表现出好象是一个以太网。由于时限的要求,在网络上的任何两台主机之间都不能多于四个网段。桥接器和路由器是很复杂的。它们分析输入的数据,并且仅在接收主机不在本地以太网上时才转发数据。
以太网的运作如同一个总线系统,在该总线上,一个主机可以发送最大长度可达1500字节的分组(或帧 frames)到同一以太网上的另一台主机中。主机是通过一个六字节地址寻址的,这个地址是固化在以太网板上的固件中的。这些地址通常是使用以冒号分开的两位十六进制数的序列形式写出的,就如同格式aa:bb:cc:dd:ee:ff。
某个站点发送的帧,别的所有站点都能看到,但只有目的主机会拾取并处理该帧。如果两个站点试图同时发送,就会发生碰撞[冲突](collision)。这个问题解决的办法是两个站点都放弃发送,并在片刻以后再次尝试发送。 <p>1.3.3 其它硬件类
在大规模的装备中,例如象Groucho Marx大学,以太网通常并不是唯一使用的设备。在Groucho Marx大学,每个系部的局域网都连接到校园主干网上,那是运行着FDDI(光纤分布式数据接口 Fiber Distributed Data Interface)的纤维光缆(fiber optics cable)。FDDI使用一种完全不同的方法来传输数据,它基本上包括向四周发送令牌,仅允许获得令牌的站点发送帧。FDDI的主要优点是有高达100Mbps传输速率、光缆最大长度可达200km。
对于长距离网络连接来讲,常常使用不同种类的设备,这些设备是基于名为X.25的标准的。许多所谓的公用数据网(Public Data Networks),如美国的Tymnet、德国的Datex-P就提供这种服务。X.25需要一种特殊的硬件,即分组组合/分拆(Packet Assembler/Disassembler)或PAD。X.25定义了一套自己的网络协议,然而它常常用于连接运行TCP/IP和其它协议的网络。由于IP分组不能简单地映射到X.25上(反之也然),所以IP分组只是简单地包装入X.25分组中在网上传输。
业余无线电爱好者常常使用他们自己的一套装置把计算机连成网;称为分组无线网(packet radio)或业余无线电报务员无线网(ham radio)。分组无线网所使用的协议称为AX.25,是从X.25派生出来的。
其它技术包括使用慢速但廉价的拨号访问串行线路。这些需要另外一些用于传输分组的协议,例如SLIP或PPP,这些将在下面讨论。 <p>1.3.4 Internet协议
当然,你不会希望你的网络连接仅限于一个以太网络之中。理想地来说,你希望能够使用一个网络而不管它是运行在什么硬件上的,也不管它是由多少个子单元组成的。例如,象Groucho Marx大学那样的大规模网络装置,你通常有几个用某些方法连接起来的独立的以太网络。在GMU,数学系有两个以太网:一个是教授和研究生的快速机器的网络,另一个是学生用的慢速机器的网络。这两个网络都连到了FDDI校园主干网上。
这种连接是由称为网关(gateway)的专用主机来处理的,它通过在两个以太网络以及光缆之间拷贝进入和传出的分组来处理的。例如,如果你在数学系并且想从你的机子上访问物理系局域网上的quark,那么网络连接软件不能够直接将分组发送到quark,因为不在同一个以太网内。因此,必须依靠网关作为一个转发者。然后,网关(给它取名为sophus)利用主干网将这些分组转发到物理系的niels网关上,由niels将分组传递到目的机器中。Erdos与quark之间的数据流见图1.1(对Guy L. Steele致歉)。 <p>图1.1 从erdos到quark发送一个数据报的三个步骤。 <p>这种引导数据至远程主机的方案称为路由选择或选路(routing),并且在此时常将分组称作数据报(datagrams)。为使事情简单,数据报交换是由单独一个与所用硬件无关的协议来管理的:IP,或互连网协议(Internet Protocol)。在第二章中,我们将极详细地描述IP以及路由选择的方法。
IP的主要好处在于它将物理上不同的网络转换成一个明显同类的网络。这叫做网络互连(internetworking),其所形成的“后网络”称为一个互连网络(internet)。在这里请注意an internet和the Internet的细微差别。后者是特指全球互连网的官方名称。
当然,IP也需要一个硬件独立的寻址方案。这是通过对每个主机分配一个32位的数值来完成的,这个32位数值称为IP-地址(IP-address)。一个IP地址通常用四个十进制数来表示,每一个十进制数表示一个8位部分,用点分开。例如,guark主机可能有一个IP地址是0x954C0C04,它可以写成149.76.12.4。这种格式也称为点分四组(dotted quad)表示法。
你将注意到我们现在有三种不同的地址类型:首先有象quark这样的主机名、然后我们有IP地址、最后还有硬件地址,如6字节的以太网地址。这些类型的地址要以某种方式加以匹配,这样,当你键入rlogin quark时,网络软件能够给出quark的IP地址;并且当IP发送任何数据到物理系的以太网上时,它会以某种方式找出与指定IP地址相映的以太网地址。这有些令人混淆。
这里我们不再深入讨论下去,而将在第二章中讨论之。现在已足够记住寻址的这些步骤的含义,对于将主机名映像到IP地址的操作成为主机名解析(hostname resolution),对于将IP地址映像到硬件地址的操作称为地址解析(address resolution)。 <p>1.3.5 串行线上的IP
在串行线路上,常常使用一个以SLIP或串行线路IP而知名的“事实上的”标准。一个对SLIP的修改被称为是CSLIP,或压缩的SLIP,用以进行IP头的压缩以充分利用串行线路提供的低带宽达到更好的性能。[4] 另一个不同的串行线路协议是PPP,或点对点协议(Point-to-Point Protocol)。PPP比SLIP有更多的特色,包括一个链接协商步骤。然而,它比SLIP出色的主要优点在于它不限于仅仅传输IP数据报,而是设计成能够传输任何类型的数据报的。 <p>1.3.6 传输控制协议(Transmission Control Protocol)
当然,将数据报从一个主机传送到另一个主机并没有完,如果你登录进quark,你就想在你的erdos上rlogin进程和quark上的shell进程之间有一个可靠的连接。这样,发送者就必须将发送和回应信息分解成分组,并且接收者将接收到的分组再重新组合成字符流。这看上去很琐细,但其中包括许多细微的任务。
关于IP要知道的一件重要的事情是,实际上,它不是可靠的。假设在你的以太网上有十个人开始从GMU的FTP服务器上下载Xfree86的最新版本。由此而产生的通信量对于网关处理能力来说可能太多,因为它太慢,并且内存也不多。如果你现在恰巧给quark发送了一个分组,网关sophus此时正好用完了缓冲空间因此没法转发此分组。IP解决此问题的方法只是简单地丢弃了这个分组。这个分组就完全失去了。因此,检查数据的完整性,并且在遇到出错时重传数据是进行通信的主机的责任。
这是由另一个协议来完成的,即TCP,或传输控制协议(Transmission Control Protocol),该协议在IP之上建立了一个可靠的服务。TCP的基本特性是,它利用IP给你一个在你的主机进程和远端主机进程之间一个简单连接的幻觉,这样你就不用关心你的数据是如何以及通过哪个路由器传输的。一个TCP的连接操作基本上象个双向的管道,两个进程都可以对其进行读写操作。可以把它想象成一次电话对话。
TCP是通过两台相关主机的IP地址以及称为端口(port)的数值来识别一个连接的末(尾)端的。端口可以看作是网络连接的附加点。如果我们对电话的例子夸张一点讲,可以把IP地址比作地区码(对应城市的代码),把端口数值比作本地码(对应于某人的电话号码)。
在rlogin的例子中,客户应用程序(rlogin)在erdos上打开了一个端口,并且连接到quark上的端口513上,该端口是rlogind服务器一直在监听的。这样就建立了一个TCP连接。使用这个连接,rlogind执行授权程序,并且然后产生shell进程。该shell的标准输入和输出被重定向至TCP连接上,所以在你的机器上你对rlogin所键入的任何字符将通过TCP流被当作标准输入给予shell。 <p>1.3.7 用户数据报协议(User Datagram Protocol)
当然,TCP并不是TCP/IP连网中唯一的用户协议。尽管它适合象rlogin这样的应用程序,其所用的总开销阻止了它用于象NFS这样的应用程序中。取而代之的是,NFS使用一个TCP的同属协议称为UDP,或用户数据报协议(User Datagram Protocol)。正如TCP一样,UDP也同样允许一个应用程序连接到远程机器上一个端口的服务上,但它不会为此建立一个连接。而是,你可以使用它来发送单个分组到目的服务上—正如它的名字表示的一样。
假设你将系中心的NFS服务器,galois,上的TeX目录结构加载到了你的机器上,并且你想查看描述如何使用LaTeX的文档。你启动了编辑器,该编辑器首先读入整个文件。然而,需要很长的时间与galois建立一个TCP连接、传送文件、并且再释放该连接。取而代之的是,向galois发送一个请求,galois以几个UDP分组的形式发送出该文件,这是非常快的。然而,UDP是不处理分组的丢失与坏分组的。这要依靠应用程序—在这里是指NFS—来处理的。 <p>1.3.8 关于端口
端口可以看作是网络连接的附属件。如果一个应用程序想要提供一个服务,它就将自身附加到一个端口上并且等待客户的到来(这也称为在端口上侦听listening)。想要使用该服务的客户在自己的本地主机上分配一个端口,并且将其连接到远程主机的该服务的端口上。
端口的一个重要特性是,一旦在客户和服务器之间建立了一个连接,服务器的另一个拷贝就会附加到服务器端口上并且侦听其它的客户。这准许,例如,在同一台主机上的几个并发远程登录操作,都使用端口513。TCP能够在这些连接之中加以区别,因为它们都来自于不同的端口或主机。例如,你从erdos两次登录到quark上,那么第一个rlogin客户就会用本地端口1023,第二个会用端口1022。然而,两者将连至quark上的同一个端口513上。
这个例子示出了作为汇聚点的端口的使用,在那里,客户联络一个指定的端口以获得一给定的服务。为了让客户知道正确的端口号,双方系统管理员必须在这些端口号分配上达成一个协定。对于广泛使用的服务,例如rlogin,这些数值必须集中管理。这是由IETF(或互连网工程任务团体Internet Engineering Task Force)来管理的,它定期地发表一个标题为分配的数值(Assigned Numbers)的RFC。在其中,它描述了分配给众所周知的服务的端口号,以及其它一些事情。Linux使用一个文件来映像服务到号码,这个文件是/etc/services。它将在The services and protocols Files一节中加以叙述。
尽管TCP和UDP的连接都依赖于端口,这些数值并不会冲突。这表示,例如,TCP的端口513与UDP的端口513是不同的。实际上,这些端口是作为两个不同服务的访问点的,如rlogin(TCP)和rwho(UDP )。 <p>1.3.9 套接字(Socket)库
在UNIX操作系统中,执行所有上述任务和协议的软件通常是内核的一部分,或是在内核里的。世界上最通用的编程接口是伯克利套接字库(Berkeley Socket Library)。[译者注:socket原意是插座、窝、孔] 这个名称得自于通俗的比喻,即将端口比作插座,并且将连接到一个端口比作插入插座。它提供(bind(2))调用来指定一个远程主机、一个传输协议、以及一个程序能够连接或侦听的服务(使用connect(2)、listen(2)、以及accept(2))。无论如何,这个套接字库还是比较通用的,因为它不仅提供了基于TCP/IP类的套接字(AF_INET套接字),而且也提供了处理本地机器内部连接的类(AF_UNIX套接字)。有些套接字库的实现同样还能处理其它的类,象XNS(Xerox Networking System)协议,或X.25。
在Linux系统中,套接字库是属于标准libc C-library中的。目前,它仅支持AF_INET和AF_UNIX套接字,但已在努力将Novell的网络协议并入,所以最终向这样的一类或几类套接字将被加进来。 <p>1.4 Linux连网
作为全世界编程者协作努力的结果,如果没有全球网络系统要编制出Linux是不可能的。所以在开发的早期,就有几个人开始做提供网络能力的工作,这一点也不用奇怪的。几乎从一开始,一个UUCP的实现就运行于Linux上,并且在1992年的秋季开始着手基于TCP/IP的网络工作,那时,Ross Biro以及其他人创建了如今以Net-1而知名的网络实现。
1993年五月,在Ross停止了开发活动以后,Fred van Kempen开始了一个新的实现的工作,改写了代码的主要部分。这个不断进行的努力以Net-2而知名。第一个公开发行的版本,Net-2d,是于1992年夏季编制的(作为0.99.10内核的一部分),并且从那以后经有几个人的维护和扩充,值得一提的是Alan Cox,形成了Net-2Degugged。在对代码大量的调试和许多改进之后,在Linux1.0发行之后,他将其更名为Net-3。这是目前包括在官方内核发行版中的网络代码版本。
Net-3给出了大量的以太网卡的设备驱动程序、SLIP(用于在串行线路上传输网络信息)设备驱动程序、以及PLIP(用于并行线路)设备驱动程序。使用Net-3,Linux在局域网环境中有一个运行得很好的TCP/IP实现,显示出在正常运行时其性能可与一些商业PC UNIX媲美。开发的重点目前已面向在Internet主机上运行的稳定性和可靠性上。
除了这些功能外,还有一些正在进行的计划项目将增强Linux的多功能性。一个PPP(点对点协议,另一个在串行线路上进行网络传输的方法)驱动程序,目前正处于Beta测试阶段,一个ham无线电的AX.25驱动程序正处于Alpha测试阶段。Alan Cox同样还完成了Novell的IPX协议的驱动程序,但是对与Novell兼容的完整的网络套件的研究工作此刻没有开展下去,因为Novell公司不愿意提供所需的文档资料。另一个非常有希望的许诺是samba,一个免费的UNIX NetBIOS服务器,由Andrew Tridgell编制的。[5] <p>1.4.1 不同的发展方向
目前,Fred正继续着开发工作,正在进行Net-2e的工作,这是个具有非常精简的网络层设计特色的。在写本书的同时,Net-2e仍是个Beta的软件。最值得注意的是Net-2e并入了DDI,设备驱动程序接口(Device Driver Interface)。DDI为所有的网络设备和协议提供了统一的访问和配置方法。
还有一个TCP/IP的实现来自于Matthias Urlichs,他为Linux和FreeBSD编制了一个ISDN驱动程序。在这里,他集成了一些BSD网络代码到Linux内核中。
然而,可以预测,Net-3将会在此停滞不前了。Alan目前正在进行用于业余无线电爱好者的AX.25协议的实现的工作。毫无疑问,仍需要进行开发的内核的“模块化”将对网络代码带来新的冲击。模块化允许你在运行时刻往内核中增加驱动程序。
尽管这些不同的网络实现都努力提供同样的服务,但在内核和设备层它们之间有很大的不同。因此,你不能够使用Net-2d或Net-3的工具来配置一个运行Net-2e内核的系统,反之也不行。这仅能应用于与内核紧密相关的命令;应用程序以及通用的网络命令,如rlogin或telnet,可以在它们任何一个上面运行。
不过,你并不用担心这些不同的网络版本。除非你参加实际的开发活动,你不用担心运行那一个版本的TCP/IP代码。官方的内核发行版总是带有一套与内核中的网络代码兼容的网络工具。 <p>1.4.2 从何处获得代码
Linux网络代码的最新版本可以通过各个站点的匿名FTP获得。Net-3的官方站点是sunacm.swan.ack.uk,其镜象在sunsite.unc.edu的system/Network/sunacm下。最新的Net-2e的补丁工具和执行代码在ftp.aris.com有。Matthias Urlichs的源自BSD的网络代码能够从ftp.ira.uka.de的/pub/system/linux/netbsd下取得。
最新的内核能够在nic.funet.fi的/pub/OS/Linux/PEOPLE/Linux;sunsite和tsx-11.mit.edu有这个目录的镜象。 <p>1.5 维护你的系统
贯穿本书,我们将主要涉及安装与配置问题。然而,管理要做的比这多—在设置好一个服务以后,你也还需要使它运行。对于大多数这些问题来说,你仅需要很少的维护工作,而对于有一些问题,象mail和news,就需要执行例程任务以使你的系统保持最新。我们将在后面章节里讨论这些任务。
最少的维护是定期地检查系统以及每个应用程序的日志文件是否有出错情况和不正常的事件发生。通常,你需要写上几行管理用的shell脚本并且从cron中周期地运行它们。有些主要应用程序的源程序发行,如smail或C News,含有这样的脚本,你只需修改它们以适应你的需求以及偏好。
你的任何cron作业的输出应该邮递到一个管理员帐号中。缺省地,许多应用程序将送出出错报告、应用统计值、或者日志文件的概要到root帐号。这只有在你经常以root登录时才有意义;一个更好的办法是将root的邮件转发到你个人的帐号中,见第14章中设置邮件别名的描述方法。
然而,不管你已经如何仔细地配置了你的站点,墨菲法则确认有些问题最终将会暴露出来。因此,维护一个系统也意味着会有抱怨存在。通常,人们会期待系统管理员起码能够通过root的email来接触,但是,同样还有其它一些地址,这些地址常用来联系到负责维护某一方面的人。例如,有关错误的邮件配置的抱怨信息常常邮递到postmaster;news系统的问题可以报告到newsmaster或Usenet。到hostmaster的邮件应该重定向到负责主机基本网络服务以及DNS名字服务(如果运行了名字服务器)的人那里去。 <p>1.5.1 系统安全
网络环境中系统管理的另一个非常重要的方面是保护你的系统与用户免受入侵者的干扰。粗心管理的系统给怀有恶意的人许多攻击目标:攻击的范围从猜测口令到以太网探听,导致的损害可能从伪造的邮件消息到数据的丢失或用户权限的侵犯。当讨论相关方面时我们将论及一些特殊的问题,以及针对它们的一些常用的防范措施。
本节将讨论有关系统安全的一些例子和基本技术。当然,所覆盖的主题不能详尽地涉及到你可能要面对的所有安全问题;它们仅仅举例说明可能碰到的问题。因此,阅读一本有关安全的好书是绝对必要的,尤其是在一个连网的系统中。Simon Garfinkel的“实用UNIX 安全”(见[Spaf93])是极为值得推荐的。
系统安全开始于好的系统管理。这包括检查所有重要文件和目录的所有权和权限,监视特权帐号的使用等等。例如,COPS程序将检查你的文件系统以及常用的配置文件的不寻常的权限和异常情况。它也能够聪明地使用一组口令来迫使用户的口令遵循一定规则以使得它们难以猜出。例如,影子口令集需要口令至少有五个字符,并且含有大小写字符和数字。
当使一个服务在网络上可以访问时,确信给它“最低权限”,这意味着你不允许它做在设计时对于它的工作不需要的事情。例如,仅仅在它们真的需要的情况下,你才应该使程序setuid到root或一些其他特权帐号。同样,如果你想对仅仅非常有限的应用程序使用一个服务时,不要犹豫,就你的特定应用程序所允许的条件下尽量严格地配置它。例如,如果你想要允许无盘主机从你的机器上进行引导,你必须提供TFTP(直接文件传输服务(trivial file transfer service)),这样它们就可以从/boot目录中下载基本配置文件。然而,如果不加限制地使用,TFTP就允许世界上的任何用户从你的系统中下载任何可读的文件。如果这并不是你想做的,为什么不限制TFTP服务只能访问/boot目录呢?[6]
同样的想法,你可能也想要来自某些主机的用户限制某些服务,比如说来自你的本地网络的用户。在第9章,我们将介绍tcpd,它会针对各种网络应用程序来做这个事情。
另一个重要点是避免运行“危险的”软件。当然,你所用的任何软件都可能很危险,因为软件都可能有错误,聪明的人可能会利用它来取得对你的系统的访问。这种事情发生过,而且对于此并没有完全的保护措施。这个问题同样影响自由软件以及商业软件产品。[7] 然而,需要特殊权限的程序天生就比其它程序更危险,因为任何漏洞都可能带来强烈的后果。[8] 如果你为了网络的目的而安装setuid程序,要有双倍的小心,不要遗漏文档上所说的任何事情,以便于你不会意外地建立了一个安全上的裂口。
不管你是如何地小心,决不能排除你的防范可能会失效。因此,必须尽早地察觉入侵者。检查系统日志文件是一个良好的开端,但是,入侵者也会是同样的聪明,会删除他或她留下的任何明显的痕迹。然而,有一种象tripwire一样的工具[9] ,它允许你检查重要的系统文件,以发现它们的内容或权限是否改动过。Tripwire在这些文件中计算各种强壮的检查和并且存储在一个数据库中。在以后的运行期间,会重新计算检查和并与存储的检查和比较以检测出任何改动的情况。 <p>1.6 以下各章展望
以下几章将涉及TCP/IP网络的配置,以及一些主要程序的运行。在开始编辑文件等工作之前,我们将在第2章更进一步地讨论IP。如果你早已知道IP路由选择的工作方法,以及地址解析是如何进行的,你可以跳过这一章。
第3章讨论最基本的配置问题。比如象建立一个内核以及设置你的以太网卡。串行口的配置在一个独立的一章中讨论,因为它的讨论不仅仅适用于TCP/IP网络,同样也与UUCP相关。
第5章帮助你针对TCP/IP网络设置你的机器。它包括只有回环使能的独立的主机的安装提示,以及连接至以太网的主机的安装提示。它也将介绍一些有用的工具,用以测试和调试你的安装设置。下一章将讨论如何配置主机名解析,并解释如何安装设置一个名字服务器。
接下来的两章分别着重介绍了SLIP和PPP的配置和使用。第7章解释了如何建立SLIP连接,并给出了一个详细的工具dip的参考。这个工具允许你自动操作大多数必要的步骤。第8章涵盖PPP以及PPP所需的的后台处理程序pppd。
第9章给出了设置一些很重要的网络应用程序的简短介绍,比如rlogin、rcp等等。这一章也介绍了服务是如何通过inetd super来管理的,以及你如何可以限制与安全相关的服务到一组(受托)可信的主机上。
接下来的两章讨论NIS,即网络信息系统(Network Information System),和NFS,即网络文件系统(Network File System)。对于象在一个局域网中的用户口令等的分布管理的信息来说,NIS是一个有用的工具。NFS允许你在你的网络中的几台主机上共享文件系统。
第12章给出了对Taylor UUCP管理的更进一步的介绍,Taylor UUCP是UUCP组件的一个免费实现。
本书的剩余章节详细讨论了电子邮件和Usenet News。第13章介绍了电子邮件的基本概念,如邮件地址看上去是怎样的,以及邮件处理系统是如何管理将你的消息送至接收者的。
第14章和第15章涵盖了smail和sendmail的设置,两个你可以使用的邮件传送代理。本书对这两者都进行了介绍,因为smail对初学者来说很容易安装,而sendmail则更具有灵活性。
第16章和第17章介绍了在Usenet中news管理的方法,以及你如何安装和使用C news,一个流行的管理Usenet news的软件包。第18章简要地叙述了对于你的本地网络如何设置一个NNTP后台程序来提供新闻阅读访问。第19章最后示出了如何配置和维护各种各样的newsreaders。 <p>
注释
[1] 上面这段话的本意,仍然在欧洲时有发生。
[2] 时间并没有对此改变多少。
[3] 当使用bash时,即GNU Bourne Again Shell,你可能需要避免使用感叹号,因为bash使用它作为它的历史字符。
[4] 在RFC-1055中对SLIP进行了讨论。头部压缩CSLIP的基本原理在RFC-1144中进行了叙述。
[5] NetBIOS是一个协议,象lanmanager以及Windows for workgroups就是基于它的。
[6] 在第9章我们将再回到这里来。
[7] 曾经有个你需要花很多钱购买的商业Unix,带有一个setuid-root的shell脚本,使用一个简单标准的诡计,该脚本程序就可允许用户获得root特权
[8] 在1988年,RTM蠕虫使得觉大多数Internet停滞,部分是通过利用一些sendmail程序的裂孔。这个漏洞早已修复。
[9] 有Gene Kim和Gene Spafford编写。
 楼主| 发表于 2002-4-24 11:08:25 | 显示全部楼层

*#!&*Linux网络管理员手册[共16章节][转帖]

&nbsp; &nbsp;
Linux网络管理员手册(2)
<p>第二章 TCP/IP网络的问题 <p>我们将转至讨论一些你将遇到的一些细节上,当你将你的Linux机器连接到TCP/IP网络时就会用到这些细节,它涉及到IP地址、主机名、以及有时是路由选择问题。这一章给出了你所需的背景资料,以用于理解你的设置需求,下一章将讨论涉及这些的一些工具。 <p>2.1 网络接口
为了隐藏可能用于网络环境的设备的差异性,TCP/IP定义了一个抽象的接口(interface),通过这个接口来访问硬件。这个接口提供了一组操作,该组操作对所有的硬件类型是一样的,并且基本上是涉及发送和接收分组。
对于每种你想用于连网的外围设备来说,必须在内核中有一个相应的接口。例如,Linux中以太网的接口称作eth0和eth1,SLIP的接口是sl0、sl1等等。这些接口名称是用于配置目的,那时你想给内核命名一个特定的物理设备。除了这别无它意。
为了对TCP/IP连网有用,一个接口必须分配一个IP地址,当与其它地方通信时这个地址起到它的鉴定识别的作用。这个地址与上面提到的接口名称是不同的;如果你将接口比作一扇门的话,那么这个地址就象是门上钉的名牌一样。
当然,可能还有其它一些设备参数需要设定;其中之一就是特定硬件能够处理的最大数据报的大小,也称为最大传输单元(Maximum Transfer Unit),或MTU。别的属性将在后面介绍。 <p>2.2 IP地址
如上章所提到的,IP网络协议所能理解的地址是一个32比特的数字。每一台机器必须分配一个对于网络环境来说唯一的一个数字。如果你运行一个不与其它网络有TCP/IP通信的本地网络,你可以依据个人的爱好来分配这些数字。然而,对于Internet上的站点来说,这些数字是由一个中心权威机构,网络信息中心(Network Information Center或NIC)来分配的。[1]
为了容易阅读,IP地址被分解成四个8比特数字称为八位位组(octets)。例如,quark.physics.groucho.edu有一个IP地址为0x954C0C04,它可以写成149.76.12.4。这个格式通常称作为点分四组表示法(Dotted quad notation)。[还有一种称呼为点分十进制表示法Dotted decimal notation—译者注]
这种表示法的另一个原因是IP地址可以分成包含在开头(左面)的八位位组中的一个网络号(network number)和包含在剩余(右面)的八位位组中的一个主机号(host number)。当IP地址遵循NIC的规则使用时,并不是为你计划要使用的每台主机分配一个地址,而是给你一个网络号,并且允许你依照你的喜好,在你的网络上给各台主机分配在该网络号范围内的所有有效的任意IP地址。
根据组成的网络规模的大小,IP地址的主机部分可大可小。为适应不同的需要,定义了几类网络,给出了IP地址的不同分割法。 <p>A类 A类由1.0.0.0到127.0.0.0的网络构成。网络号包含在第一个八位位组中。这样就提供了24比特位的主机部分,每个网络允许大约有160万台主机。 <p>B类 B类包括从128.0.0.0到191.255.0.0的网络;网络号由前两个八位位组构成。这样就可以有16320个网络,而每个网络可以有65024台主机。 <p>C类 C类网络的范围从192.0.0.0到223.255.255.0。网络号由前三个八位位组组成。可以有近200万个网络,而每个网络能容纳254台主机。 <p>D、E、F类的地址范围从224.0.0.0到254.0.0.0,用于试验用途或保留给将来使用,而没有分配给任何网络用。 <p>如果我们再参考前一章的例子,我们发现quark的地址149.76.12.4对应B类网络149.76.0.0的12.4的主机。
你可能已经注意到,上面列出来的主机部分不是每个八位位组的所有数值都可以使用的。这是因为八位位组为全0或255的主机号是留作它用的。主机部分的所有比特位为全零的地址引用为一个网络,而主机部分的所有比特位为全1的地址称为广播地址。它同时指一个网络上的所有主机。因此,149.76.255.255不是一个有效地址,而是指网络149.76.0.0上的所有主机。
还有两个网络地址0.0.0.0和127.0.0.0也是保留的。这第一个称为缺省路由(default route),后一个称为回送地址(loopback address)。缺省路由与IP路由数据报的方式有关,这将在下面讨论。
网络地址127.0.0.0保留作你的主机内部IP通信用。通常,地址127.0.0.1将分配给主机上的一个特殊接口使用,称为回送接口(loopback interface),它的行为象一个闭合电路。从TCP或UDP送来的任何IP分组都将返送给它们,就好象这个分组是刚从某个网上传过来的。这允许你不必使用一个“真正”的网络就能开发并测试网络软件。它的另一种很有用的应用是在当你想在单机上使用网络软件时。这并不象听起来那么罕有;例如,许多UUCP站点根本就没有IP连通,但仍然要运行INN新闻系统。为了要正常的运作,INN需要回送接口。 <p>2.3 地址解析
现在,你已经知道IP地址是如何形成的,你可能会觉得奇怪,它们在以太网上是如何用于编址不同的主机的。毕竟,以太网协议是用一个与IP地址完全不同的六个八位位组的数值来识别主机的,不是吗?
对。这就是为什么需要一种将IP地址映射到以太网地址的机制了。这就是所谓的地址解析协议(Address Resolution Protocol),或ARP。实际上,ARP根本不限于以太网,它也可以应用于其它类型的网络,如业余无线电爱好者等。ARP的基本概念正象人们在一个150人的人群中寻找X. Ample先生时大多数人的做法一样:他们环绕着人群,叫喊着他的名字,并确信如果他在那里的话一定会应答的。
当ARP想找出与给定IP地址相应的以太网地址时,它就利用了以太网的“广播”特性,此时一个数据报在网上同时寻址所有的站点。ARP所发送的广播数据报含有对相应IP地址的查询。每台主机将接收到的IP与自己的IP地址相比较,如果一致,就返回一个ARP响应给发出查询的主机。此时发出查询的主机就可以从响应数据报中提取发送者的以太网地址了。
当然,你会觉得惊讶,一台主机怎么能知道在全世界数不清的以太网上它能找到所期望的主机呢?并且为什么一定是以太网呢?这些问题都涉及称为路由选择的操作,也即在网络上寻找出一台主机的物理位置。这将是下一节的主题。
此时,让我们再多讨论一会ARP。一旦一台主机发现了一个以太网地址,该主机就将它存贮在ARP的缓冲中,这样主机在下一次想要发送数据报给所讨论的主机时就不要再次查询它的以太网地址了。然而,永久地保存这些信息是不明智的;例如,远程主机上的以太网卡有可能由于技术上的问题而被更换掉,此时ARP的登记项就变得无效了。为了强迫进行另一次IP地址的查询,ARP缓冲中的登记项因此在一段时间后就被丢弃。
有时候,需要找出与给定以太网地址相对应的IP地址。当一台无盘机器想从网上的一台服务器上引导时就会有这种情况,这在局域网上是常有的情形。但是,一个无盘客户实际上并没有有关自身的信息—除了知道自己的以太网址外!所以它主要要做的是广播一条请求引导服务器告诉它它的IP地址的消息。针对于此,有另一个协议,命名为反向地址解析协议(Reverse Address Resolution Protocol),或RARP。与BOOTP协议一起,它用于规定在网上引导无盘站的过程。 <p>2.4 IP路由选择
2.4.1 IP网络
当你给某人写了一封信,通常会在信封上写上完整的收信人地址,列出了国家、州和邮政编码等等。当你把信放入邮箱时,邮政服务会把它送到目的地:它将被送到指定的国家中去,该国的邮政服务会把它分发到正确的州和地区,等等。这个分级方案的优点是显而易见的:不管你在哪里发出了这封信,当地的邮递员将会大概地知道该封信要投递的方向,但并不关心这封信在送达的国家中以什么方式来投递。
IP网络的结构与之相似。整个互连网(Internet)是由许多专有网络构成,称为自治系统(autonomous systems)。每个这样的系统在其内部成员主机之间执行着各种路由选择,所以分发一个数据报的任务被简化成寻找一条到达目的主机网络的路径。这意味着,一旦数据报被传到那个特定的网络上的任何(any)主机上,网络本身会专门进行进一步的处理。 <p>2.4.2 子网(Subnetworks)
这个结构是通过前面所述的将IP地址分成主机部分和网络部分来反映出来的。默认地,目的网络得自IP地址的网络部分。因此,有同样IP网络号的主机在同一个网络上,反之也然。[2]
在网络内部使用类似的方案也同样合理,由于它本身可能有许多更小的网络组成,最小的单元可以是一个象以太网一样的物理网络。因此,IP允许你将一个IP网络分割成一些子网(subnets)。
在子网所属的IP网上,子网接管了分发数据报到某个IP地址范围的职责。对于A类、B类或C类网,它是由IP地址的网络部分确定的。然而,现在把网络部分扩展成也包括主机部分的几个比特位。被解释为子网号的这几个比特位的位数是由称为子网掩码(subnet mask),或网络掩码(netmask)的数值指定的。这同样是一个32位的数值,它指定了IP地址网络部分的位掩码。
图2.1 将B类网分成子网 <p>Groucho Marx大学的校园网就是这样一个网的例子。它的B类网络号是149.76.0.0,它的网络掩码也就是255.255.0.0。
就内部而言,GMU的校园网由几个更小的网络组成,如各个系的局域网。所以IP地址的范围被分成254个子网,149.76.1.0到149.76.254.0。例如,理论物理系的分配的子网号是149.76.12.0。校园主干网本身就是一个网络,并给予子网号149.76.1.0。这些子网号共享同一个IP网络号,而第三个八位位组用于区别它们。因此,他们将使用一个子网掩码255.255.255.0。
图2.1示出了guark的地址149.76.12.4作为一个普通的B类网和当使用子网技术时是如何有不同的解释的。
子网(正如生成子网的技术声称)仅是网络的内部分割(internal division),并没有什么用。子网是由网络的拥有者(或管理员)生成的。常常,子网的建立是为了反映现存的物理上(如两个以太网之间)的、管理上(在两个系之间)的、或地理上的分界线,并且在这些子网上的权限被授权给某些联系人。然而,这个结构仅反映出网络的内部行为,对于外部世界它是完全不可见的。 <p>2.4.3 网关
子网技术不仅有组织上的益处,它常常是一个自然的硬件分界线的结果。在一个给定的物理的(实际的)网络上,如以太网上,主机的通信范围是有限的:能够直接与之通信的主机是它所在网络上的主机。所有其它的主机仅能通过称为网关(gateways)的设备访问。网关是一台同时连接两个或多个物理网络的主机并配置成在这些网络之间交换分组。
由于IP能够很容易地识别一台主机是否在一个本地物理网络上,不同的物理网络需要属于不同的IP网络。例如网络号149.76.4.0是保留给数学系局域网上的主机的。当给quark发送一个数据报时,erdos上的网络软件立刻会从IP地址149.76.12.4上看出,目的主机在另一个不同的物理网络上,因此可以通过一个网关(缺省的是sophus)到达那里。
Sophus本身连接到两个不同的子网上:数学系和校园主干网上。它分别通过不同的接口,eth0和fddi0来访问这两个子网。现在,我们要给它分配那种IP地址呢?我们是否要给它一个在子网149.76.1.0的IP,或149.76.4.0网上的IP呢?
答案是:两个都要。当与数学系局域网上的主机通信时,sophus就使用IP地址149.76.4.1,当与主干网上的主机通信时,它将使用ID地址149.76.1.4。
因此,网关所连的每一个网络都要给网关分配一个IP地址。这些地址---及相应的网络掩码---被约束在相应的接口上,通过该接口子网可以进行访问。因此,sophus的接口与地址映射就看上去象这样的:
iface address netmask
eth0 149.76.4.1 255.255.255.0
fddi0 149.76.1.4 255.255.255.0
lo 127.0.0.1 255.0.0.0
最后一个条目描述了回送接口lo,这在上面已介绍过。 <p>图2.2显示了Groucho Marx大学(GMU)的部分网络拓扑图。同时在两个子网上的主机有两个地址。
图2.2 Groucho Marx大学(GMU)的部分网络拓扑图。 <p>一般来说,你可以忽略将地址附加到主机或它的接口之间的区别。对于仅在一个网上的主机,如erdos,你通常只需以这个以及那个地址来谈及主机,尽管严格地来说,是以太网接口有这个IP地址。然而,这种区别仅在谈论网关时显得重要。 <p>2.4.4 路由选择表
我们现在将注意力集中在当分发一个数据报到远程网络时,IP是如何选择使用一个网关的。
我们前面已经看到,当给quark发送一个数据报时,erdos检查目的地址并且发觉它不在本地网络上。Erdos因此将该数据报发送到缺省网关,sophus,它现在基本上面临同样的任务。Sophus注意到quark不在它直接连接的任何网络上,所以它必须找到另一个网关并通过该网关来转发数据报。正确的选择是到物理系的网关niels。此时,sophus需要一些信息将目的网络与适当的网关相联系。
为此,IP所使用的路由选择信息基本上是一张表,该表将各网络与到达该网络要经过的网关链接在一起。还必须提供一个捕获所有分组的表项(缺省路由);这是与网络0.0.0.0相关的网关。所有发送到未知网络的分组都是通过该缺省路由器发送的。在sophus上,这张表看上去象这样: <p>Network Gateway Interface
149.76.1.0 - fddi0
149.76.2.0 149.76.1.2 fddi0
149.76.3.0 149.76.1.3 fddi0
149.76.4.0 - eth0
149.76.5.0 149.76.1.5 fddi0
… …
0.0.0.0 149.76.1.2 fddi0 <p>路由到sophus直接连接的网络是不需要路由器的;因此它们将网关条目显示为“-”。
路由选择表可以通过各种方法来建立。对于小型局域网,在引导主机时通过手工使用路由器命令构造路由表,并将此表供给IP的做法通常是最有效的(见第五章)。对于大规模的网络,它们是通过路由选择后台服务程序在运行时刻建立并调整的;它们运行在网络的中央主机上并且与成员网络之间交换路由选择信息来确定“最佳”路由。
根据网络大小的不同,将使用不同的路由选择协议。对于在自治系统内进行的路由选择(比如Groucho Marx校园),要使用内部路由协议(internal routing protocols)。最著名的一个是RIP,即路由信息协议(或称选路信息协议),它是由BSD的routed后台程序实现的。对于在自治系统之间的路由选择,必须使用外部路由协议(external routing protocols)象EGP(外部网关协议(External Gateway Protocol)),或BGP(边界网关协议(Border Gateway Protocol));这些(以及RIP)已经在Cornell大学的gated后台程序中实现。[3] <p>2.4.5 度量值(Metric Values)
基于RIP的动态选路(或路由选择)根据“跳数”选取到达某些目的主机或网络的最佳路径,也即,一个数据报在到达目的之前所经过的网关个数。路径越短,RIP性能越好。跳数多于或等于16的很长的路径被看作是无用的,并且被舍弃。
要使用RIP来管理本地网络内部的路由信息,你必须在所有主机上运行gated。在启动引导时,gated会检测所有活动的(处于运行状态的)网络接口。如果有不止一个活动的接口(回送接口不算),就可假设主机在几个网络之间交换信息包,并且会积极地交换和广播路由信息。否则的话,主机只是被动地接收任何RIP更新信息,并且更新本地路由表。
当在广播本地路由表中的信息时,gated从与路由表条目关联的称之为度量值(Metric value)的数值中计算路径的长度。这个度量值是系统管理员在配置路由时设定的,并且应该反映出这个路由的实际代价。因此,到主机直接连接的子网的路由的度量一定是零,而通过两个网关的路由的度量应该是2。然而,当你不使用RIP或gated时,就不必为度量而烦恼。 <p>2.5 互连网控制报文协议
IP有一个相伴的协议我们至今还没有讨论,这就是互连网控制报文协议(Internet Control Message Protocol)(ICMP),用于内核中的网络代码与其它主机进行出错报文及其它的通信。例如,假设你又在erdos上并且想远程登录(telnet)到quark上的12345端口,但是并没有进程在侦听那个端口。当第一个TCP信息包到达quark的这个端口时,主机内的网络层将其识别出并且立刻给erdos返回一个ICMP报文,指出“端口不可达”。
有相当多ICMP可以理解的报文,其中许多涉及到出错的情况。然而,有一个非常有趣的报文称为重定向报文(Redirect message)。它是由路由选择(选路)模块在检测到有其它主机正使用它作为一个网关时产生的,尽管可能存在一个更短的路由。例如,在主机引导后,sophus的路由选择表可能并不完整,含有到数学系网络的路由和到FDDI主干网的路由,并且缺省路由是指向Groucho 计算中心的网关(gcc1)。因此,任何发送到quark的信息包将被送至gcc1而不是送到物理系的网关niels。当接收到这样一个数据报时,gcc1将注意到这是一个不良的路由,并且会将这个信息包转发到niels,同时给sophus返回一个ICMP重定向报文告诉它这个更好的路由。
现在,除了最基本的路由外,这好象是避免手工设置其它路由的聪明方法。然而,这里要给出警告,如果要依赖于RIP或ICMP重定向报文的动态选路方案,并不总是一个好主意。ICMP重定向以及RIP在验证某个选路信息是否需要权限方面很少提供或几乎不提供选择。这使得怀有恶意的无用之人能够中断你的整个网络的通信,或者更糟。由于这个原因,有些网络代码的版本将影响网络路由的重定向报文看作仅是主机路由的重定向。 <p>2.6 域名系统
2.6.1 主机名解析
如前所述,TCP/IP网络中的编址是围绕着32比特的数字的,然而,想多记住几个也是很难的。因此,通常主机都用“普通”的名字命名,如gauss或strange。这时,找出与名字相关的IP地址就是程序的职责了。这个过程称为主机名解析(host name resolution)。
一个想要找出给定主机名的IP地址的应用程序不一定要提供自己的例程来查找主机以及IP地址。相反地,它依赖于显然是做这个工作的几个库函数,称为gethostbyname(3)和gethostbyaddr(3)。传统上,这些以及一些相关的过程被组合成一个独立的库,称为解析库(resolver library);在Linux上,这些是标准libc的部分。通俗地说,这个函数的集合因而被称为“解析器”(the resolver)。
如今,在一个象以太网一样的小网上,或者甚至是一族以太网上,维护一张映射主机名到地址的表并不是十分困难的事。该信息通常被存放在文件/etc/hosts中。当增加或移走主机,或重新分配地址时,你所要做的就是更新所有主机上的hosts文件。很明显,当网络不仅仅是由少数几台机器组成时,这将成为繁重的负担。
针对这个问题的一个解决方案是NIS,即有Sun Microsystems开发的网络信息系统(Network Information System),通俗地称为YP,或者黄页(Yellow Pages)。NIS在主主机上将hosts文件(以及其它信息)存储在一个数据库里,客户可以从中检索所需的信息。不过,这个方法只适应中等大小的网络如局域网,因为它涉及到集中地维护整个主机数据库,并且把它分发到所有服务器上。
在互连网上,地址信息最初也是存储在一个HOSTS.TXT数据库中的。这个文件原是由网络信息中心(Network Information Center),即NIC,来维护的,并且所有参与站点都需要下载并安装。当网络增长时,这种方案带来了几个问题。除了涉及定期安装HOST.TXT的额外管理方面的开销外,分发这个库的服务器负荷变得太高了。更为严重的问题是所有的名字必须在NIC登记,它必须确定没有重名存在。
这就是为什么在1984年采用了一个新的名字解析方案,即域名系统(Domain Name System)。DNS是由Paul Mockapetris设计的,同时能解决这两个问题。 <p>2.6.2 进入DNS
DNS用域的层次结构来组织主机名。一个域是在某些方面相关的站点的一个集合---由于他们组成了一个特有的网络(例如,校园内的所有机器,或BITNET上的所有主机),因为它们都属于某个机构(就象美国政府),或者因为它们只是在地理位置上比较靠近。例如,大学被(组合)分组在edu域,每个大学或学院使用一个独立的子域(subdomain),在子域下面包含它们的主机。Groucho Marx大学可以给予groucho.edu域,数学系的局域网指定为maths.groucho.edu。系部网络上的主机将有这个域名附加在它们的主机名后;所以erdos被认为是erdos.maths.groucho.edu。这被称为全资域名(fully qualified domain name),或FQDN,它在世界范围内唯一地标识出该主机。 <p>图2.3 部分域名空间。 <p>图2.3示出了名字空间的一部分。这棵树的根的入口是用一个点(dot)来表示的,它被很恰当的称作根域(root domain),并且包含了所有其它域。为了指出一个主机名是一个全资域名,而不是一个与某个(隐含的)本地域相关的名字,有时会写上一个附加点。这表示这个名字的最后的组成部分是根域。
依赖它在层次结构中的位置,一个域可以被称为是顶层、第二层、或第三层的。还可以再划分出分层,但很好这样做。你会常看到以下几个顶层域: <p>edu (大部分在美国) 教育机构如大学等。 <p>com 商业机构、公司。 <p>org 非商业机构。常常是私有UUCP网络在这个域中。 <p>net 网络上的网关以及其它的管理主机。 <p>mil 美国军事机构。 <p>gov 美国政府机构。 <p>uucp 具官方称,以前用作无域名的UUCP名字的所有站点名,已被移入该域。 <p>技术上来说,以上的头四个属于Internet的美国部分,但你可能在这几个域中还是能见到不是美国的站点。Net域尤其是这样。然而,mil和gov是美国专有的。
在美国以外的地方,每个国家通常在两字符国家代码(在ISO-3166中定义)后面使用一个她自己命名的顶层域。例如,芬兰(Finland)使用fi域,fr由法国(France)使用,de由德国(Germany)使用,au由澳大利亚(Australia)使用,cn由中国(China)使用等等。在这个顶层域下面,每个国家的NIC可以自由地以他们想要的方式组织主机名。例如,澳大利亚有一个与国际顶层域相似的次层域,命名为com.au,edu.au,等等。其他国家,如德国,不使用这一额外层,而是使用直接引用运行一特定域的机构的稍长些的名字。例如,象ftp.informatik.uni-erlangen.de这样的主机名并非少数。由此可见德国人的效率如何了。
当然,这些国家的域并不意味着在该域下的主机实际上一定位于那个国家之中;这仅仅说明这台主机是在那个国家的NIC注册登记的。一个瑞典(Swedish)的厂商可能在澳大利亚有一分支机构,但他的所有主机仍然注册为se顶层域。
现在,以域名的层次结构来组织名字空间很好地解决了名字的唯一性问题;利用DNS,一台主机的名字只需在它的域中是唯一的,就可以在世界范围内有一个与所有其它主机不同的名字了。此外,全资名称是很容易记忆的。就其本身而言,这些已是将大的域分割成几个子域的很好的理由了。
但是,DNS甚至为你比这做得更多:它允许你将子域权限授权给它(子域)的管理者。例如,在Groucho 计算中心的维护者可以为每个系部创建一个子域;在上面我们已经遇见了maths和physics子域了。当他们发现物理系的网络太大了,而且从外界来看混乱而难以管理(总之,物理学家是一类不受拘束的人),他们就可以简单地将physics.groucho.edu域的控制权交给这个网络的管理员。这样,他们就可以自由地使用他们喜欢的无论什么样的主机名了,并且可以以各种方式在他们的网络中分配IP地址了,而不需要外界的干涉。
在本小节结束时,我们还要说一下,名字空间可以分成区(zones),每个区根于一个域。请注意区与域的细微差别:域groucho.edu包括Groucho Marx大学的所有主机,而区仅包括计算中心直接管理的主机,例如那些在数学系的主机。在物理系的主机就属于一个不同的区,也即physics.groucho.edu。在图2.3中,区的开始是在域名的右侧用小圆圈标出的。 <p>2.6.3 用DNS进行名字查找
第一眼看上去,所有这些域和区的麻烦似乎使得名字解析成为一件非常复杂的事情了。毕竟,如果没有中心权威控制什么名字分配给哪台主机的话,那么推知它将是一个多么粗陋的程序啊?!
现在讨论有关DNS的真正精华(自然,坦白,直率)的部分了。如果你想找出erdos的IP地址,那么,DNS会说,去问管理它的人,他们会告诉你。
实际上,DNS是一个巨大的分布式数据库。它是依靠所谓的名字服务器来实现的,名字服务器为一个给定的域或一组域提供信息。对于每一个区,起码有两个、最多有几个的名字服务器,在那个区的主机上掌握着所有的权威信息。为了得到erdos的IP地址,你所要做的只是联系groucho.edu区的名字服务器,名字服务器将返回你所期望的数据。
你可能会想,说起来容易做起来难。那么我怎样知道如何达到Groucho Marx大学的名字服务器呢?如果你的计算机没有配备一个地址解析程序,DNS也能提供这个能力。当你的应用程序想要在erdos上查找信息时,它就会与本地名字服务器联系,该名字服务器会为它处理一个迭代查询。它首先向根域的名字服务器发出一个查询,询问erdos.maths.groucho.edu的地址。根名字服务器注意到这个名字不属于它的管理权限范围内,而是属于edu域下的某个。因此,它告诉你与edu区的名字服务器联系以取得更详细的信息,并且给了所有一张edu的名字服务器及其地址的列表。此时,你的本地名字服务器将继续执行并查询那些edu的名字服务器之一,例如a.isi.edu。和根名字服务器同样的方式,a.isi.edu知道groucho.edu运行于他们自己的区里,并且使你指向他们的服务器。现在,本地名字服务器将自己的查询发送到这些服务器之一上,这将最终认可这个属于它的区的名字,并且返回相应的IP地址。
现在,看上去为了查找一个小小的IP地址为产生许多的通信量,但是,如果我们仍然使用HOSTS.TXT的话,所产生的数据传送量要比上述方法大的多。但是这个方案还有需要改进的地方。
为了改善将来查询的响应时间,名字服务器将在其本地缓冲中存储所获得的信息。所以当下次你的本地网络上有任何人想要查找在groucho.edu域上主机的地址时,你的名字服务器就不用再次经历整个过程,而是会直接到groucho.edu名字服务器上。[4]
当然,名字服务器并不会永远保留这个信息的,而是会在一定时间后放弃的。这个到期间隔时间称为存活期(time to live),或TTL。DNS数据库中的每一数据都有相应责任区的管理员指定的TTL。 <p>2.6.4 域名服务器
拥有一个区内所有主机信息的名字服务器被称为该区授权的(authoritative),并且有时称之为主名字服务器(master name servers)。对该区内主机的任何查询都将最终绕回到这些主名字服务器之一上。
为了提供与一个区一致的描述,它的主服务器必须很好地同步。这是通过使他们其中之一成为主要(最初、原始)的(primary)服务器来达到的,它从数据文件中装入区信息,并且使别的服务器成为次要(第二位)的(secondary)服务器,并从主要服务器中周期性地传入区数据。
有几个名字服务器的一个原因是为了分散工作负荷,其它的原因是为了有容余备份。当一个名字服务器机器毫无准备地出了故障,如崩溃了或失去了网络连接,所有的查询都将回送到其它的服务器上。当然,这个方案并不会保护你免受服务器故障而产生对所有DNS请求的错误应答,例如,由于服务器程序本身的软件错误。
当然,你也可以运行一个没有为任何域授权的名字服务器。[5] 不过这类服务器也是有用的,因为它还是可以为运行于本地网络上的应用程序管理DNS查询的,并缓冲所得信息。因此,它被称为只缓冲(caching-only)服务器。 <p>2.6.5 DNS数据库
通过上面我们已经知道,DNS不仅仅是只处理主机的IP地址,而且还交换名字服务器上的信息。实际上,DNS数据库可以有许多不同类型条目。
DNS数据库上的一条信息称为一个资源记录(resource record),或简写成RR。每一条记录都有一种与之关联的类型,描述了它所表示的数据,以及一个指明它所适用的网络类型的类。后者用于适应(或调节)不同编址方案的需要,象IP地址(IN类)、或Hesiod网络的地址(在MIT使用)、以及其它一些。原型资源记录类型是A记录,它将一个全资域名与一个IP地址相联合。
当然,一台主机可以有不止一个名字。然而,其中一个名字必须指定为正式的,或者是正规主机名(canonical host name),而其它的名字只是前者的别名。它们之间的区别在于正规主机名是与一个A记录关联的,而其它名字只有一个指向正规主机名的CNAME类型的记录。
这里我们将不讨论所有的记录类型,而是留在后面的章节中讨论。这里只给出一个简短的例子。图2.4显示出了装入physics.groucho.edu区的名字服务器中的域名数据库的一部分。 <p>&#59;
&#59; Authoritative Information on physics.groucho.edu
@ IN SOA {
niels.physics.groucho.edu.
hostmaster.niels.physics.groucho.edu.
1034 &#59; serial no
360000 &#59; refresh
3600 &#59; retry
3600000 &#59; expire
3600 &#59; default ttl
}
&#59;
&#59; Name servers
IN NS niels
IN NS gauss.maths.groucho.edu.
gauss.maths.groucho.edu. IN A 149.76.4.23
&#59;
&#59; Theoretical Physics (subnet 12)
niels IN A 149.76.12.1
IN A 149.76.1.12
nameserver IN CNAME niels
otto IN A 149.76.12.2
quark IN A 149.76.12.4
down IN A 149.76.12.5
strange IN A 149.76.12.6
...
&#59; Collider Lab. (subnet 14)
boson IN A 149.76.14.1
muon IN A 149.76.14.7
bogon IN A 149.76.14.12
... <p>图2.4 物理系named.hosts文件的摘录。 <p>除了A和CNAME记录以外,在该文件的顶部还可以看到一条特殊的记录,延伸了几行。这是SOA资源记录,意思是授权的开始(Start of Authority),它保留着服务器授权的区的常用信息。例如,它包括所有记录缺省的存活期信息。
注意,例子文件中所有不以点结尾的名字将被解释成是相对于groucho.edu域的。用于SOA记录的特别名字“@”是指域名本身。
从上面我们已经知道,groucho.edu域的名字服务器必需知道有关物理系的区,这样它们就可以将查询传给它们的名字服务器了。这常常是通过一对记录来完成的:给出服务器的FQDN的NS记录、以及一个关联地址和那个名字的A记录。由于这两个记录一起控制着名字空间,它们常被称为粘合记录(glue records)。它们是仅有的记录实例,在该记录中父辈区保存着下属区中主机的信息。指向physics.groucho.edu的名字服务器的粘合记录见图2.5所示。 <p>&#59;
&#59; Zone data for the groucho.edu zone.
@ IN SOA {
vax12.gcc.groucho.edu.
hostmaster.vax12.gcc.groucho.edu.
233 &#59; serial no
360000 &#59; refresh
3600 &#59; retry
3600000 &#59; expire
3600 &#59; default ttl
}
....
&#59;
&#59; Glue records for the physics.groucho.edu zone
physics IN NS niels.physics.groucho.edu.
IN NS gauss.maths.groucho.edu.
niels.physics IN A 149.76.12.1
gauss.maths IN A 149.76.4.23
... <p>图2.5 GMU的named.hosts文件的摘录。 <p>2.6.6 逆向查找(Reverse Lookups)
除了查找属于一个主机的IP地址以外,有时也需要找出一个与地址相应的正规主机名来。这称为逆向映射(reverse mapping),被一些网络服务用于验证客户的身份。当使用单个hosts文件时,逆向查找只是简单地包括在文件中搜索拥有指定IP地址的主机。有了DNS,对名字空间进行一次彻底的搜索当然就不可能了。取而代之的是,已经创建了一个特殊的域,in-addr.arpa,它以reverted dotted-quad表示法包括所有主机的IP地址。例如,与IP地址149.76.12.4相应的名字是4.12.76.149.in-addr.arpa。连接这些名字到它们的正规主机名的资源记录类型是PTR。
建立一个授权的区通常意味着给予它的管理员分配地址给名字的完全控制。由于他们手头上常常有一个或更多个IP网络或子网,在DNS区与IP网络之间是一个一对多的映射。例如,物理系是由子网149.76.8.0、149.76.12.0、149.76.14.0组成的。
作为结果,必须在in-addr.arpa域中随同物理区一起建立新的区并且委派该系的网络管理员为代表:8.76.149.in-addr.arpa、12.76.149.in-addr.arpa、以及14.76.149.in-addr.arpa。否则的话在碰撞实验室(Collider Lab)安装一台新主机就需要与他们的上级域联系,将这个新的地址加入他们的in-addr.arpa区文件中。
子网12的区数据库见图2.6所示。他们父辈区数据库中相应的粘合记录见图2.7所示。 <p>&#59;
&#59; the 12.76.149.in-addr.arpa domain.
@ IN SOA {
niels.physics.groucho.edu.
hostmaster.niels.physics.groucho.edu.
233 360000 3600 3600000 3600
}
2 IN PTR otto.physics.groucho.edu.
4 IN PTR quark.physics.groucho.edu.
5 IN PTR down.physics.groucho.edu.
6 IN PTR strange.physics.groucho.edu. <p>图2.6 子网12的named.rev文件的摘录。 <p>&#59;
&#59; the 76.149.in-addr.arpa domain.
@ IN SOA {
vax12.gcc.groucho.edu.
hostmaster.vax12.gcc.groucho.edu.
233 360000 3600 3600000 3600
}
...
&#59; subnet 4: Mathematics Dept.
1.4 IN PTR sophus.maths.groucho.edu.
17.4 IN PTR erdos.maths.groucho.edu.
23.4 IN PTR gauss.maths.groucho.edu.
...
&#59; subnet 12: Physics Dept, separate zone
12 IN NS niels.physics.groucho.edu.
IN NS gauss.maths.groucho.edu.
niels.physics.groucho.edu. IN A 149.76.12.1
gauss.maths.groucho.edu. IN A 149.76.4.23
...
图2.7 网络149.76的named.rev文件的摘要。 <p>如此的一个重要结论是,只能以IP网络的超集来建立区,并且,更严重的是,这些网络的网络掩码必须以字节为界。Groucho Marx大学的所有子网的掩码都是255.255.255.0,据此,可以为每个子网建立一个in-addr.arpa区。然而,如果网络掩码是255.255.255.128,那么为子网149.76.12.128建立区是不可能的,因为没有办法告知DNS 12.76.149.in-addr.arpa域已被分成了两个授权的区,两个区的主机名范围分别是1到127,和从128到255。 <p>
注释
[1] 通常,IP地址是由你出资的IP连接提供者那里分配给你的。然而,通过给hostmaster@internic.net发一个邮件,你也可以为你的网络直接向NIC申请一个IP地址。
[2] 然而,自治系统稍微更通用些,他们可以由多于一个IP网络组成。
[3] 许多人认为routed已停用。由于geted也支持RIP,因此最好选用它。
[4] 如果它不这样,那么DNS就会象其它方法一样的糟糕,因为每次的查询都将包括根名字服务器。
[5] 唔,几乎是这样。名字服务器至少应该为localhost以及127.0.0.1的反向查找提供名字服务。
 楼主| 发表于 2002-4-24 11:09:09 | 显示全部楼层

*#!&*Linux网络管理员手册[共16章节][转帖]

&nbsp; &nbsp;
Linux网络管理员手册(3)
<p>第三章 配置网络硬件 <p>
3.1 设备、驱动程序等等
直到现在,我们已经讨论了许多有关网络接口以及一般TCP/IP问题,但是并没有真正地包括当内核中的“网络代码”访问一个硬件时会确切地发生什么事情。对此,我们将简要地讨论一下有关接口和驱动程序的概念。
当然,首先是硬件本身,例如一块以太网卡:这是一块环氧树脂板,上面散布着许多有着糊涂数字的很小的芯片,这块板插在你的PC机的一个插槽中。这就是我们通常所称的设备。
为了让你能够使用这块以太网卡,你的内核中必须含有一些特殊函数,这些函数知道如何访问这个设备的特定方法。这些就是所谓的设备驱动程序。例如,Linux有几种以太网卡牌子的设备驱动程序,它们在功能上很相似。它们以“Becker系列驱动程序”而知名,与它们的作者同名,唐纳德贝克(Donald Becker)。另一个例子是处理连接至并行口的D-Link 袖珍适配器的D-Link驱动程序。
但是,当我们说一个驱动程序“处理”一个设备是什么意思呢?让我们回到上面讨论的以太网板卡上。驱动程序必须能够与外围设备板上的某些逻辑电路通信:它必须往板卡上发送命令和数据,而板卡应该能够传递任何收到的数据给驱动程序。 <p>图3.1 驱动程序、接口、以及硬件之间的关系。 <p>在PC机中,通信是通过映射到板卡上的寄存器等的I/O存储器(内存)进行的。内核发送到板卡上的所有命令和数据都要经过这些寄存器。I/O存储器通常是用给定的开始地址或基地址(base address)来描述的。以太网板卡的典型基地址是0x300,或0x360。
通常,你不用担心有关基地址之类的任何硬件问题,因为内核会在引导时试图检测到板卡上基地址的位置。这称为自动探测(autoprobing),它意味着内核读取几个存储器位置并且将读取的数据与如果安装了某个以太网卡所应有的数据作比较。然而,有些以太网卡不能够自动地被检测出来;当使用其它生产厂商的不是完全按照标准板卡复制的便宜的以太网板卡时有时就会碰到这种情况。同样,在引导时,内核将只试图检测一块以太网设备。如果你使用了不止一块网卡,你就必须明确地将这块网卡告知内核。
你必须告诉内核的另一个这样的参数是中断请求通道(interrupt request channel)。当硬件部件需要得到照料时,常常中断内核的操作,例如,当数据来到时、或者一个特殊情况发生时。在一台PC机中,中断可以发生在15个中断通道之一上,编号从0、1、以及3到15。分配给一个硬件部件的中断号被称为是中断请求号(interrupt request number),或IRQ。[1]
正如第二章中所述,内核是通过一个所谓的接口访问一个设备的。接口提供了一个对于所有硬件类型都一样的抽象的函数(功能)集,比如发送或接收一个数据报。
接口是通过名字识别的。这些名字是在内核里定义的,而不是在/dev目录下的设备文件中定义的。对于以太网接口来说,典型的名字有eth0、eth1等等。对设备的接口分配通常依赖于配置设备次序;例如,第一块安装的以太网卡将成为eth0,下一个将成为eth1,等等。这个规则的一个例外是SLIP接口,它是动态分配的;也即,无论何时只要建立了一个SLIP连接,就为该串行端口分配一个接口。
图3.1中给出的图片试图显示出硬件、设备驱动程序以及接口之间的关系。
当引导时,内核会显示出检测到什么设备,以及它安装了什么接口。下面是一个典型引导屏幕的摘录:
.
.
This processor honours the WP bit even when in supervisor mode. Good.
Floppy drive(s): fd0 is 1.44M
Swansea University Computer Society NET3.010
IP Protocols: ICMP, UDP, TCP
PPP: version 0.2.1 (4 channels) OPTIMIZE_FLAGS
TCP compression code copyright 1989 Regents of the University of California
PPP line discipline registered.
SLIP: version 0.7.5 (4 channels)
CSLIP: code copyright 1989 Regents of the University of California
Dl0: D-Link DE-600 pocket adapter, Ethernet Address: 00:80:C8:71:76:95
Checking 386/387 coupling… Ok, fpu using exception 16 error reporting.
Linux version 1.1.11 (okir@monad) #3 Sat May 7 14:57:18 MET DST 1994 <p>这表明内核是在TCP/IP激活的状态下编译的,并且包括了SLIP、CSLIP和PPP的驱动程序。倒数第三行说明检测到一个D-Link袖珍适配器,并作为接口dl0安装了。如果你有一块不同类型的以太网卡,内核通常将打印出以eth0开始的一行信息来,接下来是所检测到的卡的类型。如果已经安装了一块以太网卡,但是没有看到任何这样的消息,这表示内核不能正确地检测出你的网卡。这将在稍后的小节中加以讨论。 <p>3.2 内核的配置
大多数的Linux版本带有引导启动盘,它可以在所有普通PC机类型的硬件上使用。这表明在那些盘片上的内核,配置进了所有种类的驱动程序,其中一些你永远不会用到,但是它们却会浪费宝贵的系统内存,因为部分内核是不能被交换出去的。因此,你通常将配置你自己的内核,只包括那些你实际需要或想要的驱动程序。
当运行一个Linux系统时,你应该熟悉内核的建立。这个工作的基本原理在Matt Welsh的“安装与入门”手册中作出了解释,这本手册同样也是文档计划系列中的一本。因此,在本节中,我们将只讨论那些影响网络的配置选项。
当运行make config时,你首先将被问及一些普通配置,例如你是否需要内核数学仿真,等等。这些询问之一是问你是否要TCP/IP网络支持。你必须用y作答以得到一个支持连网的内核。 <p>3.2.1 Linux 1.0及以上版本的内核选项
在普通选项部分完成以后,配置将继续进行询问你各种特性,如SCSI驱动程序等等。随后列出了与网络支持有关的问题。由于正在进行中的研制开发,确切的配置选项集是在不停的变动中。大多数1.0到1.1内核版本所提供的一个典型的选项列表看上去象这样(注解用斜体给出): <p>*
* Network device support
*
Network device support? (CONFIG_ETHERCARDS) [y] <p>不管方括号中宏名字(macro name)是什么,如果你想要使用任何类型的连网设备的话,你就必须用y回答这个问题,而不管这是否是以太网、SLIP、或PPP。当用y回答这个问题时,对以太网类型设备的支持是自动激活的。对其它网络驱动程序类型的支持必须分别进行激活: <p>SLIP (serial line) support ? (CONFIG_SLIP) [y]
SLIP compressed headers (SL_COMPRESSED) [y]
PPP (point-to-point) support (CONFIG_PPP) [y]
PLIP (parallel port) support (CONFIG_PLIP) [n] <p>这些问题涉及到Linux支持的各种链路层协议。SLIP使得你能够在串行线路上传输IP数据报。压缩首部选项提供了对CSLIP的支持,一种将TCP/IP首部压缩成只有三个字节的技术。这个内核选项不会自动打开CSLIP,这仅仅为它提供所需的内核函数。
PPP是另外一种在串行线路上传输网络通信量的协议。它比SLIP更灵活,而且并不限于IP,一旦开发完成也将支持IPX。由于PPP的支持只是在最近才完成,这个选项可能没有出现在你的内核中。
PLIP提供了在并行端口连接上发行IP数据报的方法。它主要是用于与运行DOS的PC机进行通信。
下面的问题涉及到各个供应商的以太网卡。随着更多的驱动程序开发出来,你很可能看到更多的问题被加入这部分。如果你想建立一个能用于许多不同机器上的内核,你可以激活不止一个驱动程序。 <p>NE2000/NE1000 support (CONFIG_NE2000) [y]
WD80*3 support (CONFIG_WD80x3) [n]
SMC Ultra support (CONFIG_ULTRA) [n]
3c501 support (CONFIG_EL1) [n]
3c503 support (CONFIG_EL2) [n]
3c509/3c579 support (CONFIG_EL3) [n]
HP PCLAN support (CONFIG_HPLAN) [n]
AT1500 and NE2100 (LANCE and Pcnet-ISA) support (CONFIG_LANCE) [n]
AT1700 support (CONFIG_AT1700) [n]
DEPCA support (CONFIG_DEPCA) [n]
D-Link DE600 pocket adaptor support (CONFIG_DE600) [y]
AT-LAN-TEC/RealTek poket adaptor support (CONFIG_ATP) [n]
*
* CD-ROM drivers
*
… <p>最后,在文件系统部分中,配置脚本将询问你是否需要支持NFS,网络文件系统。NFS可以让你输出文件系统到几个主机上,这使得文件显现出好象它们是在主机的一个普通硬盘上一样。 <p>NFS filesystem support (CONFIG_NFS_FS) [y] <p>
3.2.2 Linux 1.1.14及以上版本的内核选项
从Linux 1.1.14开始,(其中加入了对IPX的alpha支持),配置过程稍有改变。在普通选项部分中现在会问你是否需要通用的网络支持。这问题后立刻就是几个各种连网选项问题。 <p>*
* Networking options
*
TCP/IP networking (CONFIG_INET) [y] <p>为了使用TCP/IP网络,你必须用y回答这个问题。然而,如果你回答n,你将仍能够编译出支持IPX的内核。 <p>IP forwarding/gatewaying (CONFIG_IP_FORWARD) [n] <p>你必须激活这个选项,如果你的系统将在两个以太网之间、或在任何以太网与SLIP链路等之间作为网关运行的话。尽管缺省地激活这个选项并无害处,你也许想要禁用这个选项以配置主机成为一个所谓的防火墙(firewall)。防火墙是连接两个或多个网络的主机,但并不在网络之间路由通信量。它们通常是用于为公司网络的用户以对内部网最小的危险性提供Internet的访问。用户将被允许登录到防火墙并且使用Internet服务,但公司的机器将受到从外界攻击的保护,因为任何进入的连接都不能通过防火墙。 <p>*
* (it is safe to leave these untouched)
*
PC/TCP compatibility mode (CONFIG_INET_PCTCP) [n] <p>这个选项用于弥补与某些PC/TCP版本的不兼容性,一个用于基于DOS的PC机上的TCP/IP商业版本。如果你激活这个选项,你将仍然能够与正常的机器通信,但在慢连接上性能可能将受到影响。 <p>Reverse ARP (CONFIG_INET_RARP) [n] <p>这个功能将激活RARP,逆向地址解析协议。RARP被用于无盘客户以及X终端,即用于在引导时查询它们的IP地址。只有在你计划想要为这些客户服务时才激活这个选项。最新的网络工具包(net-0.32d)中包括一个小工具名字为rarp,它允许你将系统加到RARP缓冲中。 <p>Assume subnets are local (CONFIG_INET_SNARL) [y] <p>当通过TCP传送数据时,内核必须在递送给IP之间将数据流分割成几个信息包。对于通过本地网络,如以太网,就能到达的主机,将使用大的信息包,而对于要通过很长距离连接的主机则使用稍小一些的信息包。[2] 如果你不激活SNARL,内核将假设只有实际上有接口连接的网络才是本地的。然而,如果你考虑Groucho Marx大学的B类网络,那么整个B类网络是本地的,但是,大多数主机只有一个或两个子网接口。如果你激活SNARL,内核将会假设当谈及校园网上的主机时所有的子网都是本地的并且都使用大的信息包。
如果你确实想使用最大包长度更小一些的包来传送数据到特殊的主机(例如,因为数据要经过SLIP连接),你可以使用route的mtu选项来做到,这在本章结束部分将概要讨论之。 <p>Disable NAGLE algorithm (normally enabled) (CONFIG_TCP_NAGLE_OFF) [n] <p>Nagle规则一个启发式的避免发送特别小的IP包,也成为微型报(tinygrams)。微型报通常是由交互式的网络工具创建的,它通常只传送单个击键,比如象telnet或rsh。微型报在低带宽的连接上,如SLIP,可能会变得特别浪费。Nagle算法试图在某些情况下暂时抑制TCP数据的传输来避免这个问题。你只有在遇到严重的信息包丢失问题时才禁用Nagle算法。 <p>The IPX protocol (CONFIG_IPX) [n] <p>这激活了对IPX的支持,--用于Novell网络的传输协议。这个功能仍在开发中,至今并没有什么用。使用它的好处是某一天你可以与基于IPX的DOS实用程序交换数据,并且通过一个PPP链接在基于Novell的网络之间路由通信量。对Novell网络高层协议的支持还没有眉目,因为这些协议的说明书只有付出可怕的高价并且在不能泄露的协议下才能得到。
从1.1.16内核开始,Linux支持另外一种驱动程序类型,虚拟[伪](dummy)驱动程序。下面的问题出现在设备驱动程序节的开始部分。 <p>Dummy net driver support (CONFIG_DUMMY) [y] <p>虚拟驱动程序实际上并没有做很多事情,但对于单机(不连网的)或是SLIP主机来说是很有用的。它基本上是一个伪装的回送接口。要有这类接口的原因是在有SLIP而没有以太网的主机上,你要有一个一直负担你的IP地址的接口。这将在第五章的虚拟接口一小节中进行进一步的讨论。 <p>3.3 Linux网络设备一览
Linux内核支持许多各种设备类型的硬件驱动程序。这一节给出了现有驱动程序族的一个简要概述,以及它们所使用的接口名称。
在Linux中,接口有许多标准名称,现列在下面。许多驱动程序支持多个接口,在这种情况下,接口被编上了号,就如eth0、eht1等等。 <p>lo 本地回送接口。它用于测试目的,以及几个网络程序。它工作起来象一个闭合电路,任何发送给它的数据报将被立即返回给主机的网络层。在内核中总有一个回送设备,并且有几个或多个几乎是没有意义的。 <p>ethn 第n个以太网卡。这是大多数以太网卡的普通接口名。 <p>dln 这些接口访问D-Link DE-600袖珍适配器,是另一种以太网设备。它有一个特别之处,就是DE-600是通过并行口驱动的。 <p>sln 第n个SLIP接口。SLIP接口以他们被分配给SLIP的次序,与串行线路相关;例如,配置成SLIP的第一条串行线路成为sl0,等等。内核最多支持四个SLIP接口。 <p>PPn 第n个PPP接口。正如SLIP接口。一个PPP接口是与一条转换成PPP模式的串行线路相关联的。目前,最多支持四个接口。 <p>plipn 第n个PLIP接口。PLIP在并行线上传输IP数据报。同时可以支持三个PLIP接口。它们在系统引导启动时由PLIP驱动程序分配,并且被映射到并行端口上。
对于将来可能要加进来的其它接口驱动程序,象ISDN、或AX.25,将引进其他名称。IPX的驱动程序(Novell的网络协议),以及AX.25(用于业余无线电爱好者)正处于开发阶段,仍处于alpha阶段。
在下面的部分中,我们将讨论使用上述驱动程序的细节。 <p>3.4 以太网的安装
目前的Linux网络代码支持各种牌子的以太网卡。绝大多数的驱动程序是由Danald Becker(becker@cesdis.gsfc.nasa.gov)编制的,他为基于国家半导体-8390芯片的网卡编制了一族的驱动程序;这些已经作为Becker系列驱动程序而知名。还有几个D-Link的产品的驱动程序,在其中,D-Link的袖珍适配器允许你通过一个并行端口访问一个以太网。这个驱动程序是由Bj&amp;oslash&#59;rn Ekwall (bj0rn@blox.se)编制的。DEPCA驱动程序是由David C. Davies(davies@wanton.lkg.dec.com)编制的。 <p>3.4.1 以太网电缆
如果你是平生第一次安装以太网的话,这里有关电缆连接的几句话也许是比较合适的。以太网连网对电缆是十分挑剔的。电缆的两端必须用50欧姆的电阻端接,而且不能有任何分支(也即,三根电缆连成星型)。如果你使用细同轴电缆和T型BNC接头,这些接头必须直接旋在网卡的接头上;你不能在其中插入一段电缆。
如果你连接到粗电缆网上,你必须通过一个收发器将主机连在网上(有时称作以太网附件单元)。你可以直接将收发器插入网卡的15针AUI端口上,但也可以使用一屏蔽电缆。 <p>3.4.2 支持的板卡
在以太网HOWTOS中有已支持板卡的一个完整的列表,由Paul Gortmaker每月投递到comp.os.linux.announce上来。[3]
下面是Linux所支持的广为所知的板卡一张列表。在HOWTO中列表的实际长度大约有这个的三倍长。然而,即使你在这张列表中找到了你的网卡,还是要首先检查HOWTO文档;因为有时候它包括对这些网卡操作的重要的详细资料。一个相关的场合是某些基于DMA的以太网卡使用与Adaptec 1542 SCSI控制器的缺省DMA通道相同的DMA,此时该以太网卡会将信息包数据往你的硬盘上乱写一气,使你神经紧蹦!&#61516&#59; <p>3Com EtherLink 3c503和3c503/16两者都支持,同样也支持3c507和
3c509。也支持3c501,但它太慢了,不值得去购买。
Novell Eagle NE1000和NE2000,以及各种各样的仿制品。也支持NE1500
和NE2100。
Western Digital/SMC WD8003和WD8013(与SMC Elite和SMC Elite
Plus相同)两者都支持,同样支持新的SMC Elite 16 Ultra。
Hewlett Packard HP 27252,HP 27247B,和HP J2405A。 <p>D-Link DE-600袖珍适配器,DE-100,DE-200,和DE-220-T。对
DE-650-T还有一个补丁程序,这是一个PCMCIA卡[4]。 <p>DEC DE200(32K/64K),DE202,DE100,和DEPCA rev E。 <p>Allied Teliesis AT1500和AT1700。 <p>要在Linux中使用这些网卡中的一块,你可以从主要Linux发行版中使用一个预编译的内核。通常这些驱动程序都被编译进了内核。就长远观点来说,最好配置你自己的内核并且仅将你实际所使用的驱动程序编译进内核。 <p>3.4.3 以太网卡的自动检测(探测)
在引导时,以太网程序代码将试图定位你的网卡并确定它的类型。网卡是以下面的地址和顺序进行检测的。
Board Addresses probed for
WD/SMC
SMC 16 Ultra
3c501
3c503 <p>NEx000
HP <p>DEPCA 0x300, 0x280, 0x380, 0x240
0x300, 0x280
0x280
0x300, 0x310, 0x330, 0x350, 0x250,
0x280, 0x2a0, 0x2e0
0x300, 0x280, 0x320, 0x340, 0x360
0x300, 0x320, 0x340, 0x280, 0x2C0,
0x200, 0x240
0x300, 0x320, 0x340, 0x360 <p>自动检测代码存在两个局限性。第一,它不能够正确地识别出所有的网卡。尤其是对于那些非常便宜的刻隆(仿制)出来的大路货板子会识别不出来。有些WD80x3板子也检测不出来。第二个问题是内核此时不能自动检测多于一块的网卡。这是一个特色,因为内核假设你想控制哪一块卡被分配哪一个接口。
如果你正在使用多块网卡,或者自动检测没有检测出你的网卡,你必须把网卡的基地址和名称明确地告知内核。
在Net-3中,你可以有两种不同的方案来完成这个操作。一个方法是在内核原代码的包括所有有关驱动程序信息的drivers/net/Space.c文件中更改或增加信息。只有你是很熟悉网络代码时才推荐使用这个方法。更好的方法是在系统引导时给内核提供这些信息。如果你用lilo启动你的系统,你可以在lilo.conf中通过使用append选项指定这些参数来传递给内核。为了通知内核有关一个以太网设备,你可以传递以下的参数: <p>ether=irq, base_ addr, param1, param2, name <p>前四个参数是数字型的,而最后一个是设备名。所有数字型的值都是可选的;如果省略或被置零,内核将会试着去探测这些值,或使用一缺省值。
第一个参数设置分配给设备的IRQ。默认地,内核将自动探测设备的IRQ通道。3c503驱动程序有一个特殊的特性,它可以从5、9、3、4中断中选择一个未用的IRQ,并配置网卡使用这个中断。
Base_addr参数给出网卡的I/O基地址;零值表示要内核探测列于上面的地址。
剩余的两个参数对不同的驱动程序有不同的用途。对于共享内存的板子,如WD30x3,它们指定共享内存区域的起始和终了地址。其它的网卡通常使用param1来设置要显示的调试信息的级别。值1到7表示逐步增加显示信息的长度,而8却是关闭所有信息的显示;0表示使用缺省值。3c503使用param2来选择内部收发器(默认的)或一个外部收发器(置为1)。前者使用板上的BNC接头;后者使用板上的AUI端口。
如果你有两块以太网卡,你可以让Linux自动检测一块,而用lilo来传递第二块板的参数给内核。然而,你必须确信驱动程序没有意外地首先发现第二块板子,否则的话另一块网卡将完全不会被登记了。可以通过给lilo加上一个reserve选项,该选项明确地告知内核避免检测由第二块网卡所占用的I/O空间。
例如,为了让Linux将第二块以太网卡作为eth1安装在0x300,你应该将下面的参数传给内核: <p>reserve=0x300, 32 ether=0, 0x300, eth1 <p>reserve选项确定当检测某个设备时,没有设备驱动程序会访问这个板子的I/O空间。你也可以使用内核参数来覆盖对eth0的自动探测。 <p>Reverse=0x340, 32 ether=0, 0x340, eth0 <p>为了完全关闭自动检测,你可以指定base_addr为-1: <p>ether=0, -1, eth0 <p>
3.5 PLIP驱动程序
PLIP代表并行线路IP(Parallel Line IP),并且当你只想连接两台机器时,这是一个廉价的方法。它使用一个并行端口和一个特殊的电缆,能达到10kBps至20kBps的速率。
PLIP最初是由Crynwr公司开发的。它的设计是相当直率的(ingenuous)(或者说是有创造性的):长期以来,PC机上的并行端口只用来作为单向打印机端口;也即,8根数据线只能用来从PC机向外设发送数据,而不是反向使用。PLIP通过使用端口的五根状态线作为输入来达到目的,这限制了它只能以半个字节(half bytes)来传输所有的数据。这个操作模式称为模式零PLIP。今天,这些单向端口不再被广泛使用了。因此,还有一个PLIP扩展称为模式1,它使用了全8比特的 接口。
目前,Linux只支持模式0。不象早期版本的PLIP代码,它现在试图与Crynwr的PLIP实现、以及NCSA telnet中的PLIP驱动程序相兼容。[5] 为了用PLIP连接两台机器,你需要一根特殊的电缆,在某些商店里作为“Null Printer”或“Turbo Laplink”出售的电缆。然而,你可以很容易地自己做出一根来。附录A示出了如何制作。
Linux的PLIP驱动程序几乎是无数人的工作结果。它目前由Niibe Yutaka维护。如果把它编译进内核,它就会为每个可能的打印机端口设置一个网络接口,plip0相应于并行端口lp0、plip1相应于lp1等等。目前接口到端口的映射是这样的: <p>Interface I/O Port IRQ
plip0
plip1
plip2 0x3BC
0x378
0x278 7
7
5 <p>
如果你已经将你的打印机配置成了不同的方式,你就必须改变在Linux 内核原代码drivers/net/Space.c中的值,并建立一个新内核。
然而,这个映射并不是说你就不能象通常一样使用这些并行端口了。仅当相应的接口被配置成那样,它们才会被PLIP驱动程序访问。 <p>
3.6 SLIP和PPP驱动程序
SLIP(串行线路IP)(Serial Line IP),和PPP(点对点协议)(Point-to-Point Protocol)是一种在串行线路链接上传输IP-信息包的广泛使用的协议。许多机构提供SLIP和PPP拨号访问到互连网上的机器中,这样,为个人提供了IP连通性(这是用别的方法很难做到的)。
为了运行SLIP或PPP,无需修改硬件;你可以使用任何一个串行端口。由于串行端口的配置是与TCP/IP连网无关的,因此将在独立的章节中专门讨论之。详细信息请参见第四章。 <p><p>注释 <p>[1] IRQs 2和9是相同的,因为PC机有两个层叠的中断处理器,每个处理器有八个IRQs;第二个处理器连接在第一个处理器的IRQ-2上。
[2] 这是为了避免具有很小最大包长度的连接产生的碎片。
[3] 可以用gpg109@rsphysse.anu.edu.au联系到Paul。
[4] 它可以从tsx-11.mit.edu的packages/laptops上得到,连同其它一些与便携机有关的软件。
[5] NCSA telnet是DOS的一个流行程序,在以太网上或PLIP上运行TCP/IP,并且支持telnet和FTP。
 楼主| 发表于 2002-4-24 11:09:54 | 显示全部楼层

*#!&*Linux网络管理员手册[共16章节][转帖]

&nbsp; &nbsp;
Linux网络管理员手册(4)

第四章 设置串行硬件 <p>
有这样的传言,在网络世界中有这样一些人,他们只有一台PC机并且钱去花在一根T1-互连网连接上。然而,为了进行他们的新闻(news)和邮件(mail)的日常工作,他们说是用公共电话网络,依靠SLIP连接、UUCP网络、和[电子]公告牌系统(bulletin board systems BBS’s)来施行的。
本章打算帮助所有那些依靠modem来维持他们的连接的人。然而,有许多细节本章将不会加以讨论,例如,如何为拨入配置你的modem。所有这些话题都会包括在Greg Hankins的即将发表的HOWTO系列中,[1] 它将定期地投递到comp.os.linux.announce上。 <p>4.1 Modem连接的通信软件
Linux有许多通信软件包,其中许多是终端程序(terminal programs),用以让一个用户拨接到另一台计算机上,就好象她正坐在一个普通的终端面前一样。传统的拨号终端程序是kermit。然而,这个软件有些简单。现已有许多支持电话号码薄的、含有拨号和登录远程计算机系统脚本语言等等的更适用的程序。这种软件之一是minicom,它与先前DOS用户可能很习惯的某些终端程序相近似。也有一些基于X的通信软件包,例如,seyon。
同样,也有许多基于Linux的BBS软件包,用于那些想运行[电子]公告牌系统的人。这些软件包有些可以在sunsite.unc.edu的/pub/Linux/system/Network中找到。
除终端程序以外,还有一些非交互式地使用串行连接的软件,用于你的计算机收发数据。这种技术的优点在于能够比某些需要在线阅读邮件的mailbox程序和查找有趣文章而浏览公告牌所需的时间,花费更少的时间来自动下载几十KB的数据。另一方面来讲,因为你常常得到的一些无用信息的装入,需要更多的磁盘存储空间。
这类通信软件的摘要[体现]是UUCP。这是从一台主机拷贝文件到另一台、在远程主机上执行程序等的一个程序组。它常用于在私人网络中传送mail或news。能运行在Linux下的Ian Taylor的UUCP软件包将在后面章节中进行讨论。其它非交互式的通信软件是,例如,用于闻名于Fidonet。也有象ifmail这样的Fidonet应用程序的端口。
SLIP,串行线路互连网协议,相对来说有些属于中间类型的,它允许交互式的或非交互式的使用。许多人使用SLIP拨号上到他们的校园网络或一些其他的公共SLIP网络服务器上来运行FTP会话等等。然而SLIP同样也能用于网到网的固定的和半固定的连接,尽管这实际上只对使用ISDN的才感兴趣。 <p>4.2 串行设备概述
UNIX内核为访问串行设备所提供的设备[驱动程序]典型地称为ttys。这是Teletype &#8482&#59;的缩写,它曾经是UNIX早期主要终端生产厂商之一。现今这个术语用于指任何字符型数据终端。贯穿本章,我们都将使用该术语专指内核设备[驱动程序]。
区别三种类型的ttys:(虚拟)控制台、伪终端(类似于一个双向的管道,用于象X11这样的应用程序)、以及串行设备。后一种也称作ttys,因为它允许在一个串行连接上进行交互式的会话操作;而不管它是固定布线连接的终端,还是通过电话线的一个远程主机。
Ttys有许多可配置的参数,这些参数可以使用系统调用ioctl(2)来设置。这些参数中的许多只对串行设备有用,因为它们需要有非常大的灵活性来处理各种类型的连接。
最突出的线路参数是线路速率和奇偶性。但是同样还有大小写字符的转换标志、回车转换成换行等等。tty驱动程序也可以支持各种线路规范(line disciplines),它使得设备驱动程序的表现完全不同。例如,Linux的SLIP驱动程序是按照特殊的线路规范实现的。
关于如何测试线路速度有些含糊不清。正确的术语是比特率,这是与用每秒比特数(或简写作bps)测量的线路传输速度相关的。有时你听会到人们以波特率(Baud rate)来谈到它,这并不是很正确的。然而,这两个术语是不可互换的。波特率指的是某些串行设备的物理特性,也即发出脉冲的时钟速率。比特率则更恰当地表示了两点之间的一个已知连接的当前状态,也即每秒钟传输的平均比特数。知道这两个值通常是不同的很重要,因为大多数设备在每个电脉冲中起码多编码了一个比特。 <p>4.3 访问串行设备
正象UNIX系统中的所有设备一样,串行端口是通过与设备相关的位于/dev目录中的特定文件进行访问的。有两种与串行驱动程序相关的设备文件,而且对于每一个端口,都有这两种的一个设备文件。根据设备所访问的文件,设备的表现将有所不同。
第一种用于当端口用作拨入时;它有一个主号码4,并且文件被命名为ttyS0、ttyS1等等。第二种用于当端口用作拨出时;文件被称为cua0等等,并且有个主号码5。
次号码对两种类型是同样的。如果你在端口COM1到COM4中的一个上面连了个modem的话,那么它的次号码就是COM端口号加63。如果你的设置与此不同,例如,当使用一块支持多串行线的板子时,请参阅Serial Howto。
假设你的modem在COM2上。这样,它的次号码将是65,对于是拨出时主号码将是5。将会有一个设备文件cua1有这些号码。对/dev目录中的串行ttys进行列表。第五列和第六列应该分别显示主号码和次号码: <p>$ ls -l /dev/cua*
crw-rw-rw- 1 root root 5, 64 Nov 30 19:31 /dev/cua0
crw-rw-rw- 1 root root 5, 65 Nov 30 22:08 /dev/cua1
crw-rw-rw- 1 root root 5, 66 Oct 28 11:56 /dev/cua2
crw-rw-rw- 1 root root 5, 67 Mar 19 1992 /dev/cua3 <p>如果没有这样的设备,你就必须创建一个:作为超级用户,键入 <p># mknod –m 666 /dev/cua1 c 5 65
#chown root.root /dev/cua1 <p>有些人建议做一个符号联接/dev/modem到你的modem设备,这样临时用户不需要记住这个不太直觉的cua1。然而,你不能在一个程序中使用modem名称,而在另一个程序中使用实际的设备文件名。这是因为这些程序使用所谓的锁定文件(lock file)来通知该设备已被占用。按照惯例,cua1的锁定文件,例如,是LCK..cua1。给同一个端口使用不同的设备文件意味着程序将不能识别出其它的锁定文件,并且大家同时使用这个设备。结果,两个应用程序都完全不能工作。 <p>4.4 串行硬件
目前Linux支持许多种类型的使用RS-232标准的串行板卡。RS-232是目前PC世界串行通信中最通用的标准了。它使用了一些电路来传输单个比特数据和进行同步。另外一些连线可以用于载波信号(用于modems)以及握手信号。
尽管硬件握手信号仅是供选用的,但是很有用的。它使得两个站点的任何一方都能通知对方它是否已准备好接收更多的数据,或者另一个站点是否将要暂停直到接收方已经处理完接收到的数据。用于此目的的连线分别称为“Clear to Send”(CTS)和“Ready to Send”(RTS),它说明了硬件握手信号的俗称,也即“RTS/CTS”。
在PC机中,RS-232接口通常是由UART芯片驱动的,该芯片源自于国家半导体公司的16450芯片,或它的一个新版本NSC16550A。[2] 有些牌子(多数显著的内置modems装配有Rockwell芯片集)也使用完全不同的芯片集,这些芯片被编程成好象它们就是16550芯片。
16450与16550的主要不同之处在于后者有一个16字节的FIFO缓冲区,而前者只有1个字节的缓冲区。这使得16450适合于速度最高为9600 Baud,而更高的速度需要一个与16550兼容的芯片。除了这些芯片以外,Linux还支持8250芯片,该芯片是PC-AT的原始芯片。
在缺省配置情况下,内核检查四个标准的串行端口COM1至COM4。次号码64到67将被分配给这些端口,正如上面所述。
如果你要正确地配置你的串行端口,你应该安装Ted Tso的setserial命令以及rc.serial脚本。这个脚本应该在系统引导启动时从/etc/rc中调用。它使用setserial配置内核的串行设备。一个典型的rc.serial脚本看上去象这样: <p># /etc/rc.serial - serial line configuration script.
#
# Do wild interrupt detection
/sbin/setserial -W /dev/cua* <p># Configure serial devices
/sbin/setserial /dev/cua0 auto irq skip test autoconfig
/sbin/setserial /dev/cua1 auto irq skip test autoconfig
/sbin/setserial /dev/cua2 auto irq skip test autoconfig
/sbin/setserial /dev/cua3 auto irq skip test autoconfig <p># Display serial device configuration
/sbin/setserial -bg /dev/cua* <p>请参阅setserial附带的文档对其有关参数的解释。
如果你的串行卡没有被检测出来,或者setserial –bg命令显示出设置不正确,你必须通过明确地给出正确的参数值来进行强行的配置。报导称配备有Rockwell芯片的内置modems的用户会碰到这个问题。例如,如果UART芯片被检测出是NSC16450,而实际上它是NSC16550时,你就必须将被错置端口的配置命令改成 <p>/sbin/setserial /dev/cua1 auto irq skip test autoconfig
uart 16550 <p>对COM端口、基地址、以及IRQ的设置有相似的选择操作。请参阅setserial的手册页。
如果你的modem支持硬件握手的话,你必须确信激活了它。令人感到奇怪的是,多数通信程序缺省地并没有试图激活它;因而你必须手工地设置它。这最好使用stty命令在rc.serial脚本中进行操作: <p>$ stty crtscts &lt; /dev/cua1 <p>要检查硬件握手是否起作用,使用 <p>$ stty –a &lt; /dev/cua1 <p>这将给出那个设备所有标志的状态;如果标志前带有一个减号,如-crtscts,表示这个标志被关闭了。 <p><p>注释
[1] 可以用gregh@cc.gatech.edu联系到。
[2] 也有一个NSC16550,但它的FIFO从没有正常工作过。

 
 楼主| 发表于 2002-4-24 11:10:59 | 显示全部楼层

*#!&*Linux网络管理员手册[共16章节][转帖]

Linux网络管理员手册(5) &nbsp;<p>第五章 配置TCP/IP网络 <p>
在本章中,我们将讨论在机器上设置TCP/IP网络所要经历的所有步骤。我们将从IP地址的分配开始,逐步描述TCP/IP网络接口的配置过程,并且介绍几个在解决网络安装问题时非常有用的工具。
本章所述的大多数工作通常你只需要做一次。而后,仅当你要向网络中增加新系统时,或者当你完全重新配置你的系统时,你才会接触许多配置文件。然而,有些用于配置TCP/IP的命令必须在系统每次引导时都要执行之。这通常是通过在系统的/etc/rc脚本中调用它们来做的。
一般地,这个过程的网络专有部分包括在称为rc.net或rc.inet的脚本中。有时,你也会看到名为rc.inet1和rc.inet2的两个脚本文件,前一个用于初始化网络的核心部分,而后者启动基本的网络服务和应用程序。在本章下面,我将注重讨论后者的概念。
下面,我将讨论执行rc.inet1的作用结果,而应用程序将在后面章节中讨论。在读完本章以后,你将建立起在计算机上正确配置TCP/IP的一个命令顺序。然后,你应该替换计算机上rc.inet1里的任何例子命令、确信rc.inet1在系统引导时被执行,并重新引导你的机器。随着你中意的Linux版本而来的网络rc脚本会给你一个很好的例子。 <p>5.1 安装proc文件系统
有些Net-2版本的配置工具要依赖proc文件系统来与内核进行通信。这是一个使用像文件系统似的机制以允许对内核运行时信息进行访问的接口。当加载时,你可以象使用任何其它文件系统一样地列出文件、或显示它们的内容。典型的项包括含有系统平均负载的loadavg文件、或显示当前核心内存以及交换使用情况的meminfo。
对于此,网络代码添加了net目录。它含有许多文件,这些文件显示象内核ARP表格、TCP连接状态,以及路由[选择]表。许多网络管理工具从这些文件中取得它们的信息。
Proc文件系统(或者也以procfs而著称)通常在系统引导时被加载到/proc目录上。最好的办法是将下面几行增加到/etc/fstab之中: <p># procfs mont point:
none /proc proc defaults <p>并且从你的/etc/rc脚本中执行“mount /proc” 。
缺省地,现在procfs被配置进大多数的内核中。如果procfs不在你的内核中,你会得到象这样的消息:“mount: fs type procfs not supported by kernel”(“加载:内核不支持文件系统类型procfs”)。你就必须重新编译内核并且在问及procfs支持时回答“yes”。 <p>5.2 安装执行文件
如果你正在使用一个打包之前的(未打包的)Linux发布版本,它将很可能包括主要的网络应用程序以及实用工具和附带的一组例子文件。你可能必须得到和安装新工具的唯一情况是当你安装了一个新的内核版本。由于它们有时在内核的网络层中含有更改的情况,你将需要更新基本配置工具。这起码包括重新编译,但有时也可能需要获得最新的执行文件组。这些通常和内核一起发行,以文档的形式打包并切称为net-XXX.tar.gz,这里XXX是版本号。与Linux 1.0相匹配的是0 .32b,在本书写作时的最新内核(1.1.12及以后)需要0.32d。
如果你想自己编译并且安装标准TCP/IP网络应用程序的话,你可以从许多Linux FTP服务器上获得原程序。这些是或多或少从Net-BSD或其它原程序经过大量修正的程序版本。其它的应用程序,比如Xmosaic、xarchie、或Gopher以及IRC客户程序必须分别地获得。其中大多数程序如果按照说明编译,则与盒装版本的一样。
官方的Net-3的FTP站点是sunacm.swan.ac.uk,镜象站点在sunsite.unc.edu下的system/Network/sunacm。最新的Net-2e补丁程序以及执行程序在ftp.aris.com。Matthias Urlichs的起源于BSD网络代码的程序在ftp.ira.uka.de.in /pub/system/linux/上有。 <p>5.3 另一个例子 <p>在本书的余下部分,让我介绍一个新的例子,这个例子要比Groucho Marx大学的例子简单,并且可能更加接近你实际要遇到的问题。考虑虚拟酿酒厂(Virtual Brewery),一个小型的酿造—正如名称指出的那样--虚拟啤酒的公司。为了更有效地管理好他们的生意,虚拟酿酒人想要将他们的计算机连网,这些正好都是运行bright and shiny 1.0(明亮与闪耀1.0)的PC机。
在同一楼层上恰好穿过大厅的地方,有一家工作与之相近的葡萄酿酒厂。他们有一个自己的以太网。很自然地,一旦他们的网络开始正常运作时,这两家公司就想将他们的网络连接起来。作为第一步,他们想要设置一台用于在这两个子网之间转发数据报的网关主机。接下来,他们也想有一个与外界世界联系的UUCP链接,通过这个连接,他们就能交换邮件和news了。最后,他们也希望安装一个SLIP连接以便有时能连接到Internet上。 <p>5.4 设置主机名(hostname)
绝大多数情况下—如果不是全部的话,网络应用程序要依赖于合理地设置本地主机名。这通常是在引导过程通过执行hostname命令来完成的。如要将主机名设置成name的话,它的调用如 <p># hostname name <p>使用一个与任何域名都无关的任意的主机名也是常有的事。例如,虚拟酿酒厂的主机可能叫做vale.vbrew.com、vlager.vbrew.com等等。这些是它们正式的、全资域名。它们的本地主机名将是这个名字的第一部分,如vale。然而,由于本地主机名常常用来查找主机的IP地址,你就必须确信解析库能够查找到该主机的IP地址。这通常意味着你必须将这个名字写入/etc/hosts中(见下面)。
有些人建议使用domainname命令来设置内核意义上的域名为FQDN的余下部分。这样的话,你可以组合hostname和domainname的输出来再次得到FQDN。然而,这最多对了一半。Domainname一般用来设置主机的NIS域,这可能与你的主机所属的DNS域完全不同。NIS将在第十章中讨论。 <p>5.5 分配IP地址
如果在你的主机上为单机操作配置连网软件(例如,为了能够运行INN网络新闻软件),你可以安全地跳过本节,因为你只需要为回送(loopback)接口分配一个接口,它总是127.0.0.1。
而对于象以太网那样的真实网络来说,事情就有一些复杂。如果你想将你的主机连接到一个现成的网络上,你就必须要求该网的管理员给你一个这个网络的IP地址。当整个网络都是由你自己来设定时,你就必须按如下描述自己来分配IP地址。
在一个本地网络内的主机通常应该有相同的逻辑IP网络地址。因此,你必须分配一个IP网络地址。如果你有几个物理网络,你或者必须给它们分配不同的网络号(网络地址),或者使用子网技术将你的IP地址范围分割成几个子网。
如果你的网络没有连接到Internet上,你可以自由地选择任何(合法的)网络地址。你只须确信选择了A类、B类或C类中的一种,否则的话事情可能会工作得不正常。然而,如果你打算近期连接Internet,你现在就得获取一个正式的(官方的)IP地址。进行的最佳方法是是请求你的网络服务提供商帮助你。如果你想获取一个网络地址只是因为万一某天你可能连上Internet,从hostmaster@internic.net要一张网络地址申请表。
为了操作几个以太网(或其它网络,一旦有了驱动程序),你必须将你的网络分隔成子网。注意,只有当你有多个广播网络(broadcast network)时,你才需要应用子网技术;点对点的连接不算在内。例如,如果你有一个以太网,并且有一个或多个SLIP链接到外部世界,你无需分割你的网络。其理由将在第7章中给出。
作为一个例子,酿酒厂的网络管理人员向NIC申请了一个B类网络号,得到191.72.0.0。为适应两个以太网,她决定使用主机部分的8个比特作为额外的子网比特位。主机部分剩余的8个比特,允许每个子网有254台主机。然后,她将子网号1给了酿酒厂、子网号2给了葡萄酒厂。这样他们的网络地址分别为191.72.1.0和191.72.2.0。子网掩码是255.255.255.0。
在两个网络之间的网关vlager,在它们两边都分配给它主机号1,这分别给了它IP地址191.72.1.1和191.72.2.1。图5.1 示出了这两个子网和网关。
注意,在这个例子中,我使用了一个B类网络来使得事情简单化;而一个C类网络将更现实些。有了新的网络代码,子网的分割并不限于字节边界,所以,即使是一个C类网络也可以分割成几个子网。例如,你可以使用2比特的主机部分作为网络掩码,就可得到四个可能的子网,每个子网可以有64台主机。[1] <p>5.6 编写hosts和networks文件
在把你的网络分成子网以后,你应该使用/etc/hosts文件为某些简单的主机名解析作些准备。如果你不打算使用DNS或NIS来作地址解析,你就必须将所有的主机名写入hosts文件中。 <p>
图5.1 虚拟酿酒厂和虚拟葡萄酒厂—两个子网。 <p>即使你在正常操作期间想运行DNS或NIS,你仍然会将一些主机名写入/etc/hosts文件中。一个原因是,即使没有网络接口正在运行,你还是会想有一些名字解析功能,例如,在系统引导期间。这不但是为了方便,而且也允许你在rc.inet脚本中使用符号主机名。这样,当更改IP地址时,你只需将更新过的hosts文件拷贝到所有机器上并且重新启动机器即可。而无需去分别编辑大量的rc文件。通常,你应该将所有本地主机名和地址放入hosts,加入用到的任何网关和NIS服务器的名称和地址。[2]
同样,在最初的测试阶段,你应该确信你的解析器只使用到hosts文件中的信息。你的DNS或NIS软件可能附带有样本文件,当使用这些文件时就可能产生奇怪的结果。为了让所有的应用程序在查找一个主机的IP地址时只使用/etc/hosts文件,你必须编辑/etc/host.conf文件。用井字符注释掉以关键字order开始的所有行,并插入一行 <p>order hosts <p>解析器库的配置将在第六章中详细讨论。
Hosts文件中每一行包含一项,每项由一个IP地址、一个主机名、和任选的该主机的一个别名列表组成。各个域用空格或制表符分开,并且地址域必须从第一列开始。任何以井字符开始的行都看作是注释行,被忽略掉。
主机名可以是全资的、或者是与本地域相关的。对与vale来说,你通常可以往hosts文件中输入全资名vale.vbrew.com,以及vale名本身,这样该主机就有正式名和短小的本地名两个名字了。
这是虚拟酿酒厂的hosts文件样式的一个例子。其中包括了两个特别的名字,vlager-if1和vlager-if2,它给出了vlager所用的两个接口的地址。 <p>
#
# Hosts file for Virtual Brewery/Virtual Winery
#
# IP local fully qualified domain name
#
127.0.0.1 localhost
#
191.72.1.1 vlager vlager.vbrew.com
191.72.1.1 vlager-if1
191.72.1.2 vstout vstout.vbrew.com
191.72.1.3 vale vale.vbrew.com
#
191.72.2.1 vlager-if2
191.72.2.2 vbeaujolais vbeaujolais.vbrew.com
191.72.2.3 vbardolino vbardolino.vbrew.com
191.72.2.4 vchianti vchianti.vbrew.com <p>正如对待主机的IP地址一样,有时对于网络号你也可能想使用一个符号名称。因此,hosts文件有一个相伴的称为/etc/networks的文件,用于映射网络名到网络号以及反之。在虚拟酿酒厂,我们可以安装一个象下面的networks文件:[3] <p># /etc/networks for the Virtual Brewery
brew-net 191.72.1.0
wine-net 191.72.2.0 <p>5.7 IP的接口配置
在如前章里解释那样设置好你的硬件以后,你必须让内核的网络软件知道这些设备。有几个命令是用于配置网络接口和初始化路由选择表的。这些任务通常是在系统每次启动引导时由rc.inet1脚本来做的。做这些任务的基本工具称为ifconfig(这里“if”表示接口的意思interface),和route。
Ifconfig用于使得一个接口能够被内核的网络层访问。这包括IP地址的分配和其它参数的指派、激活接口—也以“起用”(“taking up”)而知名。这里激活表示内核将通过接口发送和接收IP数据报。调用它的最简单的办法是 <p>ifconfig interface ip-address <p>它分配IP地址ip-address给接口interface并激活它。所有其它的参数都设置成缺省值。例如,缺省的子网掩码是从IP地址的网络类型中获得的,如255.255.0.0是B类地址的掩码。Ifconfig将在本章末给予详细的讨论。
Route允许你对内核的路由表进行增加或删除路由的操作。它可以象这样调用 <p>route [add|del] target <p>这里add和dell是决定增加还是删除到目的(target)网络或主机的路由。 <p>5.7.1 回送(loopback)接口
最早被激活的接口是回送接口(loopback interface): <p># ifconfig lo 127.0.0.1 <p>有时,你也会看到使用伪主机名localhost替代IP地址的用法。Ifconfig将在hosts文件中查找这个名字,在hosts文件中应该有一项申明localhost是127.0.0.1的主机名: <p># Sample /etc/hosts entry for localhost
localhost 127.0.0.1 <p>要查看一个接口的配置,你要用接口名作为参数调用ifconfig: <p>$ ifconfig lo
lo Link encap Local Loopback
inet addr 127.0.0.1 Bcast [NONE SET] Mask 255.0.0.0
UP BROADCAST LOOPBACK RUNNING MTU 2000 Metric 1
RX packets 0 errors 0 dropped 0 overrun 0
TX packets 0 errors 0 dropped 0 overrun 0 <p>如你所见,lookback接口被赋予255.0.0.0掩码,这是因为127.0.0.1是一个A类地址。该地址没有一个广播地址集,但这在loopback中并没有什么用。然而,如果你在主机上运行了rwhod后台服务程序的话,你就必须设置loopback设备的广播地址,以便rwho能够正确地运行。如何设置广播地址会在下面的“关于ifconfig”一节中描述。
现在,你几乎可以启动运行你的米你-“网络”了。最后所缺的是路由选择表里的一项,该项将告诉IP,它可以使用这个接口作为到达目的127.0.0.1的路由。这是通过键入下面的命令来完成的 <p># route add 127.0.0.1 <p>再次,你可以使用localhost来代替这个IP地址。
接下来,你要检查是否每样事情正常工作着,例如通过使用ping来检查。ping是声纳设备的网络等价物[4] 用于验证一个给定的地址是否真正能达到,并且测量发送一个数据报到给定地址然后返回到主机的延迟时间。所需的时间常称为来回程时间。 <p># ping localhost
PING localhost (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp seq=0 ttl=32 time=1 ms
64 bytes from 127.0.0.1: icmp seq=1 ttl=32 time=0 ms
64 bytes from 127.0.0.1: icmp seq=2 ttl=32 time=0 ms
^C
--- localhost ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0/0/1 ms <p>当如上调用ping时,它将继续不停地发送信息包,除非被用户中断掉。上面的^C标记出我们按Ctrl-C的地方。
上面这个例子显示出127.0.0.1的信息包正确地发送了出去并且一个应答几乎是瞬时就返回到ping的。这表示你已经成功地设置好第一个网络接口。
如果你从ping得到的输出信息与不象上面所示的,你就碰到问题了。查看出错信息看看是否它指出了某些文件没有正确地被安装。查看你所使用的ifconfig和route执行文件是否与你运行的内核版本兼容,并且,最重要的是检查所编译的内核是网络使能的(激活的)(你可以从是否存在/proc/net目录看出)。如果你得到出错信息说“网络不可达,”那么你很可能用错了route命令。请确信你使用了与给ifconfig相同的地址。
上面所描述的步骤对于在单机上使用网络应用程序来说已足够了。在将上面的几行添加到rc.inet1并确信这两个rc.inet脚本都已在/etc/rc中执行以后,你可以重新引导你的机器并且试验各种应用程序。例如,“telnet localhost”将会建立一个到你主机的telnet连接,给你一个登录提示画面。
然而,loopback接口是有用的,不仅是在网络书本中作为一个例子,或作为开发期间的一个测试台,而且实际上在正常操作时也被用于某些应用程序。[5] 因此,不管你的机器是否连接到一个网络上,你总是必须要配置它的。 <p>5.7.2 以太网接口
配置一个以太网接口与配置loopback接口非常相象。它只是在你使用子网技术时需要稍多的参数。
在虚拟酿酒厂,我们已经将IP网络分割成了C类子网,这个IP网络原是一个B类网络。为了使得接口能够识别这个变化,ifconfig的参数应该看上去象这样: <p># ifconfig eth0 vstout netmask 255.255.255.0 <p>它将vstout(191.72.1.2)IP地址分配给了eth0接口。如果我们已经省略了网络掩码,那么ifconfig将推论出该IP地址类的掩码来,它将会已有255.255.0.0这样的网络掩码。现在,一个快速查看显示出: <p># ifconfig eth0
eth0 Link encap 10Mps Ethernet HWaddr 00:00:C0:90:B3:42
inet addr 191.72.1.2 Bcast 191.72.1.255 Mask 255.255.255.0
UP BROADCAST RUNNING MTU 1500 Metric 1
RX packets 0 errors 0 dropped 0 overrun 0
TX packets 0 errors 0 dropped 0 overrun 0 <p>你可以看出,ifconfig自动地将广播地址(上面的Bcast域)设置成常用的值,即将主机的网络号的主机部分的所有比特位置为1。同样,消息传输单元(message transfer unit)(内核为该接口生成的最大以太网帧的大小)已被设置成最大值1500字节。所有这些值都可以用特定的选项覆盖掉,这将在下面讨论之。
同loopback的情况非常相似,你现在必须安装一个路由选择项,它会通知内核有关通过eth0能够到达的网络。对于虚拟酿酒厂来说,你应该按如下调用route <p># route add –net 191.72.1.0 <p>起先,这看上去有点象变魔术,因为并不清楚route是如何探测到要通过哪个接口进行路由。然而,窍门是很简单的:内核检测已配置的所有接口并且将目的地址(此时为192.72.1.0)与接口地址的网络部分相比较(也即将接口地址和网络掩码进行逐位与)。只有eth0接口与之匹配。
现在,-net选项是干什么用的呢?使用这个选项是因为route既可以处理路由到网络也可以处理路由到单机的情况(正如上面你已看到有关localhost的情况)。当给出的地址是用点分四组表示法表示时,route通过查看主机部分比特位来试图猜测它是个网络号还是个主机地址。如果地址的主机部分是零的话,route假定它表示一个网络,否则的话route把它当作一个主机地址。因此,route会认为192.72.1.0是一个主机地址而不是一个网络号,因为它并不知道我们使用了子网技术。因此,我们必须给出-net标志,明确地告之route它代表一个网络。
当然,上面的route命令键入时很冗长,并且很容易输错。一个更简便的方法是使用我们已经在/dev/networks中定义的网络名字。这使得这个命令非常易读;而且也可以将-net标志省略掉了,因为route现在知道191.72.1.0表示一个网络。 <p># route add brew-net <p>现在既然我们已经完成了基本的配置步骤,我们要确信该以太网接口确实能正常运行。从你的以太网络上任选一台主机,例如vlager,并键入 <p># ping vlager
PING vlager: 64 byte packets
64 bytes from 191.72.1.1: icmp seq=0. time=11. ms
64 bytes from 191.72.1.1: icmp seq=1. time=7. ms
64 bytes from 191.72.1.1: icmp seq=2. time=12. ms
64 bytes from 191.72.1.1: icmp seq=3. time=3. ms
^C <p>----vstout.vbrew.com PING Statistics----
4 packets transmitted, 4 packets received, 0% packet loss
round-trip (ms) min/avg/max = 3/8/12 <p>如果你看不到任何象这样的输出,那么,很明显有地方出了问题。如果你碰到不正常的包丢失速率,这意味着是个硬件问题,如坏的或丢失了终端头等等。如果你一点也没收到任何信息包,你应该用netstat来检查接口配置。Ifconfig的信息包统计信息会告诉你接口是否发送了任何信息包。如果你也可以访问那台远程的主机,你也应该过去检查它的接口的统计信息。用这种方法,你就可以正确地确定这些信息包是在哪丢失的。另外,你应该用route显示选路(路由选择)信息,来看看两台主机的路由项目是否正确。当不使用任何参数调用route时,会打印出整个内核选路表(-n选项只是使得它用点分四组表示法打印出地址来,而不是用主机名): <p># route -n
Kernel routing table
Destination Gateway Genmask Flags Metric Ref Use
127.0.0.1 * 255.255.255.255 UH 1 0
191.72.1.0 * 255.255.255.0 U 1 0 <p>  这些域的详细含义将在下面的“使用netstat检查”一节中给出。Flag列包含每个接口标志的一个列表。U对于活动的接口总是置位的,H是指目的地址表示一台主机。如果H标志是为一个作为网络路由器的路由器置位的,那么你就必须为route命令指定-net选项。为了测试你加入的一个路由器是否被使用,检查倒数第二列中的Use域在ping的对话期间会增加。 <p>5.7.3 通过网关进行路由
在前一节中,我只描述了在单个以太网上设置一台主机的情况。然而经常性地,一个人会遇到网络通过网关连接到另一个网络的情况。这些网关可能只是简单地连接两个或多个以太网络,但也可能提供到外部世界的Internet连接。为了使用一个网关的服务,你必须在网络层提供额外的选路信息。
例如,虚拟酿酒厂和虚拟葡萄酒厂的以太网络是通过这样的一个网关,也即主机vlager,连在一起的。假设vlager早已被配置好,我们只需在vstout的选路表中添加另一个项,这个项告诉内核,它可以通过vlager到达葡萄酒厂网络上的所有主机。适当的route“咒语”显示如下;关键字gw告诉route下一个参数表示一个网关。 <p># route add wine-net gw vlager <p>当然,你所希望对话的葡萄酒厂网络上的任何主机必须有一个酿酒厂网络的相应选路项,否则的话,你将只能将数据从vstout发送到vbardolino,但后者的任何响应都将丢失(go into the great bit bucket)。
这个例子只描述了一个网关,它在两个隔离的以太网之间交换信息包。现在假设,vlager也有一个到Internet的连接(例如,通过一个另外的SLIP连接)。那么我们希望除了到达酿酒厂的数据报,到达任何其他网络的数据报都将交由vlager处理。这可以通过使vlager成为vstout缺省的路由器来做到。 <p># route add default gw vlager <p>网络名default是0.0.0.0的缩写,它表示缺省路由器。你无需把这个名字添加到/etc/networks中,因为它内建于route中。
当你ping一台隔着一个或几个网关的主机时看到很高的包丢失率,这可能意味着网络很拥挤。包丢失并不主要是技术上不足的原因,如由于转发主机暂时的超负荷运行,使得它们延迟甚至丢失了输入的数据报。 <p>5.7.4 配置网关
配置一台机器使其在两个以太网之间交换信息包是非常直接明了的。假设我们回到vlager上,它配备了两块以太网卡,每块网卡连接一个网络。全部你所要做的是分别配置这两个接口,给它们各自的IP地址,并且就这些了!
将两个接口的信息按如下方式添加到hosts文件中是非常有用的,我们也有唾手可得的名字: <p>191.72.1.1 vlager vlager.vbrew.com
191.72.1.1 vlager-if1
191.72.2.1 vlager-if2 <p>设置这两个接口的命令序列也就成为: <p># ifconfig eth0 vlager-if1
# ifconfig eth1 vlager-if2
# route add brew-net
# route add wine-net <p>5.7.5 PLIP接口
当使用PLIP链接来连接两台机器时,事情就与使用以太网的稍微有些不同。前者是所谓的点对点的链接,因为相对于通信网络来说,它们只包括两台主机(“点”)。
作为一个例子,我们考虑虚拟酿酒厂的某个员工的膝上型电脑(笔记本电脑),它通过PLIP与vlager连接。笔记本电脑本身叫做vlite,并且只有一个并行端口。在引导期间,这个端口将被注册为plip1。为了激活这个连接,你必须使用下列命令配置这个plip1接口:[6] <p># ifconfig plip1 vlite pointopoint vlager
# route add default gw vlager <p>第一个命令配置这个接口,告诉内核这是个点对点的链接,远端一边的地址是vlager。第二个命令安装缺省路由器,vlager用作网关。在vlager上,需用一个类似的ifconfig命令来激活连接(路由器启用是不需的): <p># ifconfig plip1 vlager pointopoint vlite
这里有趣的一点是vlager上的plip1接口不需要有一个独立的IP地址,而同样是地址192.72.1.1。[7]
现在,我们已经配置好了从笔记本电脑到酿酒厂网络的路由;还缺的是酿酒厂的任何主机到vlite的路由的方法。一个特别笨的方法是在指定vlager为网关的各个主机的选路表中增加一特别的到vlite的路由项。 <p># route add vlite gw vlager <p>在面对临时路由的一个更好的选择是使用动态路由。这样做的一个方法是使用gated,一个路由后台服务程序,它需要你安装在网络上的每台主机上来动态地发布选路信息。然而,最简单的方法是使用代理(proxy)ARP(地址解析协议),使用代理ARP,vlager将通过发出自己的以太网地址来响应任何对vlite的ARP请求。这个的作用是所有到vlite的信息包都送至vlager,然后vlager将信息包转发到笔记本电脑。我们将在“检查ARP表”一节中再讨论代理ARP。
以后发行的Net-3将包含一个称为plipconfig的工具,它允许你设置所使用的打印机端口的IRQ。今后,这将由更通用的ifconfig命令来代替。 <p>5.7.6 SLIP和PPP接口
尽管SLIP和PPP链接只是简单的象PLIP一样的点对点连接,但对它们有很多要讨论的。通常,建立一个SLIP连接包括通过modem拨号到远程站点,并设置串行线路成SLIP模式。PPP使用同样的方式。设置SLIP或PPP所需的工具将在第七章和第八章中描述。 <p>5.7.7 哑(Dummy)接口
哑接口实在是有一些特殊的,但却是非常有用的。它的主要好处是,对于独立的主机以及那些仅有的IP网络连接是通过拨号连接才有的机器。实际上,后者在大多数时间也是一台独立的主机。
令独立主机进退维谷的是它们只有一个网络设备是激活的,即回送(loopback)接口,该接口通常分配了地址127.0.0.1。然而在某些情况下,你需要将数据发送到“正式的”的本地主机IP地址上去。例如,考虑笔记本电脑vlite,假设此时它没有连接任何的网络。Vlite上的一个应用程序现在可能需要发送一些数据到同一个主机的另一个应用程序中。在/etc/hosts中查看vlite,找到它的IP地址是191.72.1.65,所以这个应用程序试图往这个地址发送数据。由于回送接口是该机器上目前唯一活动的接口,所以内核就根本不知道该地址实际上就是自己的!作为结果,内核就会丢弃这个数据报,并且给应用程序返回一个出错信息。
这里就是哑设备需要起作用的地方。它通过简单地作为回送接口的一个密友来解决这个难题。对于vlite的情况,你只须简单地给它地址191.72.1.65并且加入一个指向它的主机路由。此时,到191.72.1.65的每个数据报都将在本地投递了。正确的调用是: <p># ifconfig dummy vlite
# route add vlite <p>5.8 关于ifconfig
ifconfig还有比我们在上面所讨论的更多的参数。它通常的调用是: <p>ifconfig interface [[-net|-host] address [parameters]] <p>interface是接口名字,address是分配给该接口的IP地址。它可以是一个点分四组表示的IP地址;或者是一个ifconfig可以在/etc/hosts和/etc/networks中查到的名字。-net和-host选项分别迫使ifconfig将地址作为网络号或主机地址来对待。
如果ifconfig只带一个接口名来调用,它就显示出该接口的配置。当不待任何参数来调用,它就显示你目前已设置的所有接口的配置;-a选项迫使ifconfig同时也显示不活动的接口。对以太网接口eth0的一个调用样本可能看上去象这样: <p># ifconfig eth0
eth0 Link encap 10Mbps Ethernet HWaddr 00:00:C0:90:B3:42
inet addr 191.72.1.2 Bcast 191.72.1.255 Mask 255.255.255.0
UP BROADCAST RUNNING MTU 1500 Metric 0
RX packets 3136 errors 217 dropped 7 overrun 26
TX packets 1752 errors 25 dropped 0 overrun 0 <p>MTU和度量域显示出该接口的当前MTU和度量值。传统上,度量值被用于某些操作系统计算路由的代价。Linux还没有使用这个值,但为了兼容性而定义了它。
RX和TX行显示出有多少个包已被无错地接收和发送了、发生了多少个错误、有多少个包丢失了(通常是由于内存不足)、有多少个包由于超限而丢失了。接收器超限发生通常是由于到来的包的速率快于内核可以对最后一个中断的响应。Ifconfig所打印出的标志值或多或少与它的命令行选项的名字相对应;它们将在下面给出解释。
下面是ifconfig所能识别的参数的一个列表,相应的标志名在括号中给出。简单地打开一个特性的选项同样也能在该选项的前面加上一短划(-)再来关闭这个特性。 <p>Up
这标记一个接口为“up”,也即可以访问IP层。在命令行上给出地址时,就隐含了该选项。它也可以用于重新使能被down选项临时关闭的接口。(这个选项与标志UP RUNNING相对应。)
down
这标记一个接口为“down”,也即不可以访问IP层。这有效地禁止了通过该接口的任何通信。注意,这并不删除自动使用该接口的所有选路项。如果你要永远地停掉该接口,你应该删除这些路由项并且提供可能的其它选路信息。
Netmask mask
这指派了用于该接口的一个子网掩码。它可以以一个前面加有0x的十六进制的32比特数给出,或以点分四组十进制数给出。
Pointopoint
这个选项只用于包含两台主机的点对点IP链接。例如,这个选项需要被用于SLIP或PLIP接口的配置。(如果设置了一个点对点的地址,ifconfig会显示POINTOPOINT标志。)
broadcast address
广播地址通常是通过将网络号的主机部分所有比特位置位产生的。有些IP实现使用一个不同的方案;这个选项是用于适应那些特殊的环境。(如果设置了一个广播地址,ifconfig就显示一个BROADCAST标志。)
metric number
这个选项可用于为一个接口建立的选路表项分配一个度量值。这个度量用于路由信息协议(Routing Information Protocol RIP)为网络建立选路表。[8] ifconfig所用的缺省的度量值是零。如果你没有运行一个RIP后台程序,你一点也不需要这个选项;如果你用了,你也很少需要改变度量的值。
Mtu bytes
这设置最大传输单元(Maximum Transmission Unit),这是接口能够在一次传输中处理的最大8比特组的数目。对于以太网,MTU的缺省值是1500;对于SLIP接口,它是296。
arp
这个选项特别用于象以太网或无线电包的广播型网络的。它启动ARP的使用,地址解析协议,来侦测连接到网络上的主机的物理地址。对于广播型网络,它总是缺省启用的。
-arp
在这个接口上禁止ARP的使用。
Promisc
将接口置为混合模式。在一个广播型网络上,这使得该接口接收所有的包,而不管它们是否是到达其它主机的信息包。这使得可以使用包过滤器等来分析网络交通流量,也称为以太网侦听。通常,这是查出用其它方法难以克服的网络问题的一个很好的技术。而另一方面,这也使得攻击者从你的网络流量中得到密码并且做其它肮脏的事。针对这类攻击的一个保护措施是不要让任何人可以随便将他们的计算机插入你的以太网中。另一个选择是使用安全认证协议(secure authentication protocols),如Kerberos、或SRA登录组件。[9] (这个选项与标志PROMISC相对应。)
-promisc
禁止混合模式。
Allmulti
组播[多址通信,多点传送]地址是对无需在一个子网上的的一组主机的广播。目前,内核不支持组播地址。(这个选项对应于标志ALLMULTI。)
-allmulti
禁止组播地址。 <p>5.9 使用netstat检查
下面,我们转过来讨论一个对检查网络配置和行为很有用的工具。它称为netstat并且实际上是几个工具的汇总。我们将在下面几节中讨论它的每一个功能。
5.9.1 显示路由选择表
当使用-r标志调用netstat时,它以我们在上面已经用route做过的方式显示内核选路表。在vstout,它产生: <p># netstat -nr
Kernel routing table
Destination Gateway Genmask Flags Metric Ref Use
127.0.0.1 * 255.255.255.255 UH 1 0
191.72.1.0 * 255.255.255.0 U 1 0
191.72.2.0 191.72.1.1 255.255.255.0 UGN 1 0 <p>-n选项使得netstat以点分四组IP数的方式打印出地址,而不是用主机名或网络名。当你想避免在网络上查找地址时这是特别有用的(例如,对于一个DNS或NIS服务器)。
Netstat输出的第二列示出了选路选项指向的网关。如果没用到网关,就只打印一个星号。列三显示出路由的“一般性”。当给定一个IP地址而要找出适当的路由,内核查询选路表的所有项,在与路由的目的地址比较之前将该地址与genmask进行位与(bitwise AND)。
第四列显示了描述路由的各种标志: <p>G 路由使用了网关。
U 所用的接口已启动。
II 通过路由只能到达单个主机,例如,loopback项127.0.0.1就是这种情况。
D 如果该表项是由一个ICMP重定向消息产生的,就设置该标志(见2.5节)。
M 如果该表项被一个ICMP重定向消息修改过,就设置该标志。 <p>Netstat输出的Ref列显示了对这个路由的参考数,也即,有多少个其它的路由(例如,通过网关)依赖于这个路由的存在。最后两列显示出了选路表项已被使用的次数,以及数据报通过其分发的接口。 <p>5.9.2 显示接口统计信息
当带-I标志调用时,netstat将显示当前配置的网络接口的统计信息。如果再另加上一个-a标志,它将打印出内核中存在的所有接口,不仅是那些目前已经配置了的。在vstout上,netstat的输出看上去象这样: <p>$ netstat -i
Kernel Interface table
Iface MTU Met RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flags
lo 0 0 3185 0 0 0 3185 0 0 0 BLRU
eth0 1500 0 972633 17 20 120 628711 217 0 0 BRU <p>MTU和Met域那个接口的当前MTU和度量值。RX和TX列显示有多少信息包是无错接收和发送的(RX-OK/TX-OK)、出错的(RX-ERR/TX-ERR)、丢失了多少包(RX-DRP/TX-DRP)、以及有多少包是由于超限而丢失的(RX-OVR/TX-OVR)。
最后一列显示出该接口被设置的标志。这些是当你用ifconfig显示接口配置的长标志名字的一字符版本。
B
一个广播地址已被设置。
L
这个接口是一个回送(loopback)接口。
M
所有的包都将被接收(混合模式)。
N
避免包尾。
O
对于该接口,ARP被禁止。
P
这是一个点对点连接。
R
接口正在运行。
U
接口被起用。 <p>5.9.3 显示连接状态
netstat支持一组选项来显示主动的或被动的套接字。选项-t、-u、-w和-x显示主动的TCP、UDP、RAW或UNIX套接字连接。如果你另外增加-a标志,那么,等待连接的(例如,正在倾听的)套接字也被显示出来了。这将给出你的系统上目前运行着的所有服务器的一张列表。
在vlager上调用netstat –ta产生: <p>$ netstat -ta
Active Internet connections
Proto Recv-Q Send-Q Local Address Foreign Address (State)
tcp 0 0 *:domain *:* LISTEN
tcp 0 0 *:time *:* LISTEN
tcp 0 0 *:smtp *:* LISTEN
tcp 0 0 vlager:smtp vstout:1040 ESTABLISHED
tcp 0 0 *:telnet *:* LISTEN
tcp 0 0 localhost:1046 vbardolino:telnet ESTABLISHED
tcp 0 0 *:chargen *:* LISTEN
tcp 0 0 *:daytime *:* LISTEN
tcp 0 0 *:discard *:* LISTEN
tcp 0 0 *:echo *:* LISTEN
tcp 0 0 *:shell *:* LISTEN
tcp 0 0 *:login *:* LISTEN <p>这显示出大多数的服务器只是简单地在等待输入连接。然而,第四行显示从vstout来的一个SMTP连接,第六行告知你有一个输出的到vbardolino的telnet连接。[10]
使用-a标志将显示出各类的所有套接字。 <p>5.10 检查ARP表
在某些情况下,观察甚至改动内核的ARP表的内容是很有用的,例如,当你怀疑重复使用的Internet地址是某些间歇性的网络问题的原因时。arp工具就是为此类事情而编制的。它的命令行选项是 <p>arp [-v] [-t hwtype] -a [hostname]
arp [-v] [-t hwtype] -s hostname hwaddr
arp [-v] -d hostname [hostname...] <p>所有的hostname参数可以是符号主机名或是以点分四组表示的IP地址。
第一个调用显示指定IP地址或主机的ARP项,或者如果没有给出hostname时显示所有已知的主机的ARP项。例如,在vlager上执行arp会产生 <p># arp -a
IP address HW type HW address
191.72.1.3 10Mbps Ethernet 00:00:C0:5A:42:C1
191.72.1.2 10Mbps Ethernet 00:00:C0:90:B3:42
191.72.2.4 10Mbps Ethernet 00:00:C0:04:69:AA <p>它显示出了vlager、vstout和vale的以太网地址。
使用-t选项你可以限制显示信息为指定的硬件类型的。这可以是ether、ax25、或者是pronet,分别表示10Mbps的以太网、AMPR-AX.25、和IEEE-802.5令牌环网。
-s选项用于永久性地将hostname的以太网地址加入到ARP表中。Hwaddr参数指定硬件地址,它缺省地指的是以太网地址、由冒号分隔的六个十六进制字节指定。使用-t选项,你也可以为其它类型硬件设置硬件地址。
有一个问题,它可能需要你手工地将一个IP地址加入到ARP表中,是当由于某些原因对远端主机的ARP请求失败了的时候,例如当它的ARP驱动程序有错或网络上有另外一台主机错误地使用了那个主机的IP地址。ARP表中硬配置的IP地址也是一个(非常强烈的)方法来保护你自己免受你的以太网上其它主机冒充别人的主机。
使用-d开关调用arp将删除与给定主机相关的所有ARP项。这可以用于迫使该接口重新尝试获处理中的IP地址的以太网地址。这在当错误配置的系统已经广播了错误的ARP信息时很有用(当然,你要首先重新配置这个出错的主机)。
选项-s也可以用于实现代理(proxy)ARP。这是一个特殊的技术,这里一个主机,比如说gate,通过假装这两个地址引用同一台主机gate,而为另一台名为fnord的主机担当一个网关。它是通过公布一个指向自己(gate)以太网接口的fnord的ARP项。现在,当一台主机发出一个对fnord的ARP请求时,gate将返回一个包含自己以太网地址的响应。此时,发出请求的主机将会送出所有的数据报到gate,gate将有责任地转发这些数据报到fnord。
这些带拐弯的处理有时是需要的,例如,当你想从一个不能很好地理解路由的TCP实现的DOS机器上访问fnord时。当你使用代理ARP时,对于DOS机器看来,fnord好象救灾本地子网上,所以它就不需要知道如何路由通过一个网关了。
代理ARP的另一个非常有用的应用是,当你的主机之一对于某些主机只是临时充当一个网关时,例如,通过一个拨号链接。在前一个例子当中,我们已经遇到了偶尔通过PLIP?/td&gt; &nbsp;
 
 楼主| 发表于 2002-4-24 11:11:55 | 显示全部楼层

*#!&*Linux网络管理员手册[共16章节][转帖]

&nbsp; &nbsp;
Linux网络管理员手册(6)
<p>第六章 名字服务和解析器配置 <p>正如第二章所述,TCP/IP网络可以依赖于不同的方案来将名字转换成地址。如果不利用名字空间被分裂成区的好处的话,最简单的方法是用存储于/etc/hosts中的主机表。这仅对由一个管理员管理的小型局域网有用,而且这个局域网要与外界没有IP通信。hosts文件的格式早已在第5章中描述过。
作为选择,你可以使用BIND—伯克里互连网名字域服务(Berkeley Internet Name Domain Service)--来解析主机名到IP地址。配置BIND可能很是繁杂,但是一旦你完成它,那么网络拓扑的变化很容易做到。在Linux上,正如在许多其它UNIX样的系统中,名字服务是通过一个称为named的程序提供的。在启动时,它将一组主要文件装入缓冲中,等待从远程或本地用户进程来的请求。设立BIND有不同的方法,并且不是所有的方法都需要你在每个主机上都运行名字服务器的。
虽然本章可以叙述的更详细一些,但却只是给出了如何操作一个名字服务器的粗略概况。如果你计划在不只是一个小型局域网并且可能有一个Internet连接的环境下使用BIND,你应该针对BIND取得一本好书,例如Crichet Liu的“DNS和BIND”(见[AlbitzLiu92])。对于当前的信息,你也可以查阅包括在BIND原程序中的发行注释(release notes)。还有一个DNS问题新闻组(newsgroup)称为comp.protocols.tcp-ip.domains。 <p>6.1 解析器库
当谈及“解析器”,我们并不是指任何特殊的应用程序,而是指解析器库(resolver library),是一个能在标准C库中找到的函数的集合。主要的例程是gethostbyname(2)和gethostbyaddr(2),它们查寻属于一个主机的所有的IP地址,并且反之也然。它们可以被配置成只是简单地在hosts中查询信息、请求名字服务器的一个数、或使用NIS的hosts数据库(Network Information Service)。其它的应用程序,象smail,可能包括这些中的任何不同的驱动程序,并且需要特别的照料。 <p>6.1.1 host.conf文件
控制你的解析器设置的主要文件是host.conf。它存储于/etc中并且告知解析器使用哪个服务、以及用什么顺序。
Host.conf中的选项必须出现在不同的行上。各个域要用空格(空格或制表符)隔离。一个“#”号表示一个注释行。
有以下一些选项: <p>order
这确定了解析服务试验的顺序。有效的选项是:bind用于请求名字服务器、hosts用于在/etc/hosts中查找、nis用于NIS查寻。可以指定其中的任何一个或所有。它们出现在一行上的顺序决定了各个相关服务试验的顺序。
multi
以on或off做为选项。这决定了在/etc/hosts中的一个主机是否可以有几个IP地址,它通常指的是作为“多宿主的”。这个标志对DNS或NIS请求是没有作用的。
nospoof
就如前章所解释的,DNS通过使用in-addr.arpa域,允许你找到属于一个IP地址的主机名。名字服务器提供一个假主机名的企图被称为“哄骗”(“spoofing”)。为了防止这个做法,解析器可以配置成检查是否一个原始IP地址实际上是与一个获得的主机名相关的。如果不是,这个名字将被丢弃并且返回一个出错。这个行为是通过设置nospoof为on来打开的。
alert
这个选项使用on或off作为参数。如果它被打开,任何哄骗企图(见上面)将导致解析器将信息写进syslog日志文件中。
trim
这个选项将一个域名作为参数,在查寻之前它将被从主机名中删去。这对于hosts项是很有用的,那里你可能只想指定无本地域的主机名。附带有本地域名的一个主机的查寻将被移去本地域,这样就使得在/etc/hosts中的查找获得成功。 <p>Vlager的一个样本文件显示如下: <p># /etc/host.conf
# We have named running, but no NIS (yet)
order bind hosts
# Allow multiple addrs
multi on
# Guard against spoof attempts
nospoof on
# Trim local domain (not really necessary).
trim vbrew.com. <p>6.1.2 解析器环境变量
host.conf中的设置可以通过使用环境变量来覆盖。这些环境变量是 <p>RESOLV_HOST_CONF
这指定读一个文件而不是读/etc/host.conf。
RESOLV_SERV_ORDER
覆盖host.conf中给出的顺序选项。服务器以hosts、bind、以及nis顺序给出,用空格、逗号、冒号、或分号来分隔。
RESOLV_SPOOF_CHECK
确定对待哄骗的方法。可以用off来完全禁止它。值warn和warn off启用哄骗检查,但分别打开或关闭日志。值*启用哄骗检查,但留下在host.conf中定义的日志选项。
RESOLV_MULTI
值on或off可用于覆盖host.conf中的multi选项。
RESOLV_OVERRIDE_TRIM_DOMAINS
这个环境变量指定了一个修整域的列表,它覆盖host.conf中给出的修整域。
RESOLV_ADD_TRIM_DOMAINS
这个环境变量指定了一个修整域的列表,它对host.conf中的修整域作了增加。 <p>6.1.3 配置名字服务器查寻—resolv.conf
当配置解析器库以使用BIND名字服务进行主机查找,你也必须告知它使用哪个名字服务器。对此有一个独立的文件,称为resolv.conf。如果这个文件不存在或是空的,那么解析器就假设名字服务器在你本地的主机上。
如果在你的本地主机上运行一个名字服务器,就象在下面一节中解释的那样,你必须单独地设置它。如果你在本地网络上并且有机会使用一个现存的名字服务器的话,这将总是一种推荐的做法。
resolv.conf中最重要的选项是nameserver,它给出了要使用的名字服务器的IP地址。如果你通过几次给出nameserver选项指定了几个名字服务器,那么它们会以给出的顺序试用。因此,你应该首先给出最可靠的服务器。目前,至多支持三个名字服务器。
如果没有给出nameserver选项,那么解析器试图连接本地主机上的名字服务器。
其它两个选项,domain和search涉及到如果BIND不能用第一个请求解析主机名时附加在主机名上的缺省域。search选项指定了一个试用的域名列表。列表项是用空格或制表符分开的。
如果没有给出search选项,就会通过使用域名本身从本地域名以及直至root的父域中建立一个搜寻列表。本地域名可以使用domain语句给出;如果一个也没有给出,那么解析器就通过系统调用getdomainname(2)来获取。
如果这使得你感到混淆,考虑虚拟酿酒厂的resolv.conf样本文件: <p># /etc/resolv.conf
# Our domain
domain vbrew.com
#
# We use vlager as central nameserver:
nameserver 191.72.1.1 <p>当解析名字vale时,解析器将查询vale,并且vale.vbrew.com和vale.com都会失败。 <p>6.1.4 解析器的稳固性
如果你在一个大型网络中运行一个局域网,你无疑地应该使用主要名字服务器如果它们存在的话。这样做的优点是它们会有丰富的缓冲,因为所有的请求都转发给了它们。然而,这个方案也有缺点:当一把火毁坏了我校的主干网电缆时,我们系的LAN就做不了什么工作了,因为解析器不再能到达任何名字服务器了、在X-终端上不再能登录了、也没了打印等等。
尽管校园主干网在火中焚毁不是常有的事,但我们必须针对这种情况采取防范措施。
一种选择是设置一个从本地域解析主机名的本地名字服务器,并且转发对其它主机名的所有请求到主服务器上去。当然,这只适用于你运行在自己的后台程序时。
另一种选择是,你可以在你的/etc/hosts中维护一个你的域或LAN的一个备份主机表。然后,在/etc/host.conf中要包含“order bind hosts”使得解析器在主名字服务器不在时后退到hosts文件。 <p>6.2 运行named
在大多数UNIX机器上提供域名服务的程序通常称为named(发音为name-dee)。这是一个最初为BSD开发的用于为客户提供名字服务的服务器程序,其它的名字服务器程序也可能是这样的。目前在多数Linux安装中所使用的版本好象是BIND-4.8.3。现在BIND-4.9.3正处于Beta测试阶段,不久就会有了。
本节需要对域名系统工作原理有一些理解。如果下面的讨论你一点也看不懂,你可以重新阅读第2章,那里有关于DNS的更多的信息。
named通常在系统引导时启动的,并且一直运行到机器再次关闭为止。它从一个称为/etc/named.boot的配置文件中以及各种包含域名到地址映射数据的文件等中取得信息。后者称为区域文件(zone files)。这些文件的格式和语义将在下一节中描述。
要运行named,只需在提示符下简单地键入 <p># /usr/sbin/named <p>named将启动,读取named.boot文件以及其中指定的任何区域文件。它将它的进程id以ASCII写入/var/named.pid中、如有需要就从主服务器中下载任何区域文件,并且开始在端口53侦听DNS请求。[1] <p>6.2.1 named.boot文件
named.boot文件通常很小并且只包括指向含有区域信息的主文件的指针、以及指向名字服务器的指针。该boot文件中的注释行以一个分号开始一直延续到下一个新行开始。在我们详细讨论named.boot的格式之前,我们将看一下图6.1中给出的vlager的样本文件。[2]
&#59;
&#59; /etc/named.boot file for vlager.vbrew.com
&#59;
directory /var/named
&#59;
&#59; domain file
&#59;---------------------------------------------------
cache . named.ca
primary vbrew.com named.hosts
primary 0.0.127.in-addr.arpa named.local
primary 72.191.in-addr.arpa named.rev
图6.1 vlager的named.boot文件。 <p>这个例子中的cache和primary命令将信息装入named。这个信息是从第二个参数指定的主文件中取得的。它们含有DNS资源记录的文本表示,下面我们来看看。
在这个示例中,我们把named配置成三个域的主要(primary)名字服务器,就如该文件末尾的primary语句指出的那样。其中第一个primary语句指示named作为vbrew.com的主服务器,并从named.hosts文件中取得区域数据。directory关键字告诉它所有的区域文件位于/var/named目录中。
cache是非常特殊的项并且实际上应该在所有运行名字服务器的机器上存在。它的功能有两个:它指示named激活它的缓冲,并从指定的缓冲文件中(在该示例中是named.ca)装入根名字服务器提示(root name server hints)。我们将在下面回过来讨论名字服务器提示。
下面是用于named.boot中的非常重要的选项的一张列表: <p>directory 它指定了区域文件存储的目录。文件名可以用与该目录相关的形式给出。通过重复使用directory可以指定几个目录。根据Linux文件系统标准,这应该是/var/named。
primary 它将一个域名(domain name)和一个文件名(file name)作为参数,宣布了对命名的域的本地服务器的授权。作为一个主要服务器,named从主文件中装入区域信息。一般地,在每个.boot文件中总是有至少一个primary项,即用于网络127.0.0.0的逆向映射,该网络是本地回送(loopback)网络。
secondary 这个语句将域名(domain name)、地址列表(address list)和一个文件名(file name)作为参数。它为指定的域宣布本地服务器为二级主服务器。一个二级服务器同样也掌有该域的授权数据,但它不是从文件中得到的,而是试着从主服务器中下载来的。因此至少一个主服务器的IP地址必须在named的地址列表中给出。本地服务器将联系每个主服务器直到它成功地将区域数据库传输过来,这个区域数据库然后被保存在第三个参数指定的备份文件中。如果主服务器一个都没有响应,就从备份文件中取回区域数据。此后,named将试图定期刷新区域数据。这将在下面连同SOA资源记录类型一起讨论。
cache 它将域(domain)和文件名(file name)作为参数。这个文件包含了根服务器提示,它是一个指向根名字服务器的一张列表。只有NS和A记录将被识别。domain参数通常是根域名“.”。对named来说这个信息是绝对至关重要的:如果.boot文件中没有cache语句,named将完全不会产生一个本地缓冲。如果下一个服务器请求不在本地网上,这将严重地降低性能以及增加网络负荷。更为严重的是,named将不能到达任何根名字服务器,因而,除了那些它授权的,它将不能解析任何地址。这个规则的一个例外是使用转发服务器(cf. 下面的forwarders选项)。
forwarders 这个语句将一个地址列表(address list)作为参数。这个列表中的IP地址指定了在named不能从本地缓冲中解析一个查询时可能会查询的名字服务器的一个列表。它们会被顺序地试用直到其中一个服务器对查询作出响应。
slave 该语句使得名字服务器成为一个从服务器。也即,它本身将永不执行递归查询,但只是将查询转发到forwarders语句指定的服务器上。 <p>还有两个选项,sortlist和domain,我们在这里将不对它们进行讨论。另外,还有两个可以用于区域数据库文件中的指令。它们是$INCLUDE和$ORIGIN。因为它们很少用到,这里我们将同样不对它们进行描述。 <p>6.2.2 DNS数据库文件
named包括的主文件,如named.hosts,总有一个域与它们相关联,称之为origin。这是一个用cache和primary命令指定的域名。在一个主文件中,允许你指定与该域相关的域和主机名。在配置文件中的一个名字如果以一个点结尾就被认为是绝对的(absolute),否则的话它被认为是与orgin相关的。orgin本身可以用“@”来引用。
一个主文件中包含的所有数据被分裂成资源记录(resource records),或简称RRs。它们构成DNS中的最小的信息单元。每一资源记录有一个类型。例如,A记录将一个主机名映射到一个IP地址、一个CNAME记录将一个主机的别名与它的正式主机名相关联。作为一个示例,请观看115页是的图6.3,它显示了虚拟酿酒厂的named.hosts主文件。
主文件中的资源记录表示法共享一个通用的格式,它是 <p>[domain] [ttl] [class] type rdata <p>各域用空格或制表符分开。如果一个左大括号在第一个新行之前,一个项可以连续跨过几行,并且最后一个域后跟一个右大括号。在分号和新行之间的任何信息都被忽略。 <p>domain 条目所适用的域名。如果没有给出域名,那么该RR假定应用于前一个RR的域。
ttl 为了迫使解析器在一段时间后放弃(废弃)信息,每个RR有一个相应的“存活期”(“time to live”),或简称ttl。ttl域用秒来指定从服务器取得的信息有效的时间。它是一个最多八位的十进制数。如果没有给出ttl值,那么它的值缺省为前面SOA记录的最小域的值。
class 这是一个地址类,正如IP地址的IN,或Hesiod类中对象的HS。对于TCP/IP网络来说,你必须使它为IN。如果没有给出class域,就假定使用前一个RR的类。
type 它描述了RR的类型。最普通的类型是A、SOA、PTR以及NS。下一节描述了RR的各种类型。
rdata 它保存与RR相关的数据。这个域的格式依赖于RR的类型。下面对每种RR进行单独的描述。 <p>下面是用于DNS主文件的RR的一个不完整列表。还有许多RR的类型,我们将不作讨论。它们是试验性的,并且通常很少有用。 <p>SOA 它描述了一个授权区域(SOA是指“Start of Authority”)。它表示紧跟在SOA RR后面的记录包含有对该域的授权信息。每一个用primary语句包括的主文件在此区域必须含有一个SOA记录。资源数据含有以下几个域: <p>orign 这是该域的主要名字服务器的规范主机名。它通常用一个完全的名字给出。
contact 这是维护该域的负责人的email地址。用一个点替换掉了“@”字符。例如,虚拟酿酒厂域的负责人是janet,那么这个字段域将含有janet.vbrew.com。
serial 这是一个用单个十进制数表示的区域文件的版本号数。每当区域文件中的数据改变时,这个数值将增加。
这个序列(serial)号值是用于次要名字服务器识别何时区域信息改变了。为了保持最新,次要服务器在一定间隔时间后就请求主要服务器的SOA记录,并且将该序列号值与缓冲的SOA记录的序列号值相比较。如果数值改变了,次要服务器就从主要服务器将整个区域数据库传输过来。
refresh 它指定了次要服务器将等待检查主要服务器的SOA记录的一个以秒计的间隔时间,同样地,这是一个最多八位的十进制数。通常网络的拓扑结构不会经常性地改变,所以对于大型网络来说,这个数应该指定为大约一天左右。
retry 这个数值确定了一个间隔时间,它是一个请求或一个区域刷新失败时次要服务器将重试与主要服务器联系的间隔时间。它不应该太小,否则一个临时的服务器失败或网络问题将导致次要服务器浪费网络资源。一个小时、或者一个半小时,可能是一个好的选择。
expire 它以秒指定了一个时间值,在这个时间过后,如果服务器还不能联系到主要服务器的话,它最终将丢弃所有的区域数据。这个时间值通常应该很大。Graig Hunt([GETST 92])推荐为42天。
minimum 这是对于没有明确指定ttl的资源记录的一个缺省的ttl值。这需要其它的名字服务器在一段时间后丢弃RR。然而,它与次要服务器开始试图更新区域信息所等待的时间无关。Minimum应该是一个很大的值,尤其是对于网络拓扑结构几乎不变的局域网。一个大约是一周或一个月的值大概是一个很好的选择。对于单个RR可能经常改变的情况,你仍可以给它们一个不同的ttl值。 <p>A 这将一个IP地址与一个主机名相关联。资源数据域包含点分四组表示的地址。对于每一台主机,只能有一个A记录。用于这个A记录的主机名被认为是正式的或规范的主机名。所有其它主机名都是别名,并且必须使用一个CNAME记录映射到这个规范的主机名上。
NS 这指向一个从属区域的主名字服务器。对于为什么要有NS记录的解释,请参见3.6节。资源数据域包含名字服务器的主机名。为了解析这个主机名,另外需要一个A记录,即给出名字服务器IP地址的所谓的粘合记录。
CNAME 它将一个主机的别名与它的正规(或规范)主机名相关联。规范主机名就是主文件为其提供一个A记录的主机名;别名只是通过一个CNAME记录简单地联结到规范主机名上,但它们本身没有任何其它的记录。
PTR 这个类型的记录用于将in-addr.arpa域中的名字与主机名相关联。这用于IP地址到主机名的逆向映射。所给出的主机名必须是规范主机名。
MX 这个RR对于一个域申明了一个邮件交换器(mail exchanger)。有邮件交换器的原因将在第13章的“互连网上的邮件路由”一节中讨论。MX记录的句法是
[domain] [ttl] [class] MX preference host <p>host 为domain命名邮件交换器。每个邮件交换器有一个整数preference(优先权)与之关联。一个想要将邮件分发到domain的邮件传输代理会试用所有针对这个域的MX记录的主机,直到成功为止。具有最低优先权值的将首先试用,然后按着优先权值的增大顺序试用其它主机。
HINFO 这个记录提供了有关系统硬件和软件的信息。它的句法是 <p>[domain] [ttl] [class] HINFO hardware software <p>hardware(硬件)字段确定主机所使用的硬件。存在特别的约定来指定它。在“Assigned Numbers”(RFC 1340)中给出了一张有效名字的列表。如果字段中含有任何空格字符,就必须用双引号括住。Software(软件)字段指定系统所用的操作系统软件。同样,应该选用“Assigned Numbers”RFC中的有效名字。 <p>6.2.3 编写主文件
图6.2、6.3、6.4和6.5给出了在酿酒厂vlager上的一个名字服务器的样本文件。考虑到所讨论网络的特性(单个局域网),这个例子是非常直观的。如果你的要求更复杂些,并且你运行不了named,参见Cricket Liu和Paul Albitz([AlbitzLiu92])的“DNS and BIND”。
图6.2示出的named.ca缓冲文件显示出一个根名字服务器的样本提示记录。一个典型的缓冲文件通常描述了大约一打左右的名字服务器。你可以使用本章末描述的nslookup工具获得根域的当前名字服务器的列表。[3]
&#59;
&#59; /var/named/named.ca Cache file for the brewery.
&#59; We&quot;re not on the Internet, so we don&quot;t need
&#59; any root servers. To activate these
&#59; records, remove the semicolons.
&#59;
&#59; . 99999999 IN NS NS.NIC.DDN.MIL
&#59; NS.NIC.DDN.MIL 99999999 IN A 26.3.0.103
&#59; . 99999999 IN NS NS.NASA.GOV
&#59; NS.NASA.GOV 99999999 IN A 128.102.16.10 <p>图6.2 named.ca文件
&#59;
&#59; /var/named/named.hosts Local hosts at the brewery
&#59; Origin is vbrew.com
&#59;
@ IN SOA vlager.vbrew.com. (
janet.vbrew.com.
16 &#59; serial
86400 &#59; refresh: once per day
3600 &#59; retry: one hour
3600000 &#59; expire: 42 days
604800 &#59; minimum: 1 week
)
IN NS vlager.vbrew.com.
&#59;
&#59; local mail is distributed on vlager
IN MX 10 vlager
&#59;
&#59; loopback address
localhost. IN A 127.0.0.1
&#59; brewery Ethernet
vlager IN A 191.72.1.1
vlager-if1 IN CNAME vlager
&#59; vlager is also news server
news IN CNAME vlager
vstout IN A 191.72.1.2
vale IN A 191.72.1.3
&#59; winery Ethernet
vlager-if2 IN A 191.72.2.1
vbardolino IN A 191.72.2.2
vchianti IN A 191.72.2.3
vbeaujolais IN A 191.72.2.4 <p>图6.3 named.hosts 文件
&#59;
&#59; /var/named/named.local Reverse mapping of 127.0.0
&#59; Origin is 0.0.127.in-addr.arpa.
&#59;
@ IN SOA vlager.vbrew.com. (
joe.vbrew.com.
1 &#59; serial
360000 &#59; refresh: 100 hrs
3600 &#59; retry: one hour
3600000 &#59; expire: 42 days
360000 &#59; minimum: 100 hrs
)
IN NS vlager.vbrew.com.
1 IN PTR localhost. <p>图6.4 named.local文件 <p>
&#59;
&#59; /var/named/named.rev Reverse mapping of our IP addresses
&#59; Origin is 72.191.in-addr.arpa.
&#59;
@ IN SOA vlager.vbrew.com. (
joe.vbrew.com.
16 &#59; serial
86400 &#59; refresh: once per day
3600 &#59; retry: one hour
3600000 &#59; expire: 42 days
604800 &#59; minimum: 1 week
)
IN NS vlager.vbrew.com.
&#59; brewery
1.1 IN PTR vlager.vbrew.com.
2.1 IN PTR vstout.vbrew.com.
3.1 IN PTR vale.vbrew.com.
&#59; winery
1.2 IN PTR vlager-if1.vbrew.com.
2.2 IN PTR vbardolino.vbrew.com.
3.2 IN PTR vchianti.vbrew.com.
4.2 IN PTR vbeaujolais.vbrew.com. <p>图6.5 named.rec文件 <p>6.2.4 验证名字服务器的设置
有一个很好的工具用于检查名字服务器设置的操作。它称为nslookup,即可以交互式地使用,也可以从命令行上使用。在后一种情况下,你只需象这样简单地调用它 <p>nslookup hostname <p>它将对hostname查询resolv.conf中指定的名字服务器。(如果这个文件指定了多个服务器,nslookup将随机地选择一个)。
然而,交互模式则更令人兴奋。除了能查询单个的主机,你可以查询DNS记录的任何类型,并且传输一个域的整个区域信息。
当不加参数地调用,nslookup将显示它所用的名字服务器,并且进入交互模式。在’&gt;’提示符下,你可以键入任何想要查询的域名。缺省地,它请求类A记录,这些是包含与域名相关的IP地址的。
你可以通过发出“set type=type”来改变这个类型,这里type是上面6.2节中描述的资源记录名,或ANY。
例如,你可以与它进行下面的对话: <p>$ nslookup
Default Name Server: rs10.hrz.th-darmstadt.de
Address: 130.83.56.60 <p>&gt; sunsite.unc.edu
Name Server: rs10.hrz.th-darmstadt.de
Address: 130.83.56.60 <p>Non-authoritative answer:
Name: sunsite.unc.edu
Address: 152.2.22.81 <p>如果你试者去查询一个没有相应IP地址的名字,但DNS数据库中能找到其它的记录,nslookup将返回一个错误信息说“No type A records found”(“没有类型A记录发现”)。然而,你可以通过发出“set type”命令来查询不是类型A的其它记录。例如,要得到unc.edu的SOA记录,你要发出: <p>&gt; unc.edu
*** No address (A) records available for unc.edu
Name Server: rs10.hrz.th-darmstadt.de
Address: 130.83.56.60 <p>&gt; set type=SOA
&gt; unc.edu
Name Server: rs10.hrz.th-darmstadt.de
Address: 130.83.56.60 <p>Non-authoritative answer:
unc.edu
origin = ns.unc.edu
mail addr = shava.ns.unc.edu
serial = 930408
refresh = 28800 (8 hours)
retry = 3600 (1 hour)
expire = 1209600 (14 days)
minimum ttl = 86400 (1 day) <p>Authoritative answers can be found from:
UNC.EDU nameserver = SAMBA.ACS.UNC.EDU
SAMBA.ACS.UNC.EDU internet address = 128.109.157.30 <p>以同样的方式你可以查询MX记录,等等。使用一个ANY类型将返回与一个给出的名字关联的所有资源记录。
&gt; set type=MX
&gt; unc.edu
Non-authoritative answer:
unc.edu preference = 10, mail exchanger = lambada.oit.unc.edu
lambada.oit.unc.edu internet address = 152.2.22.80 <p>Authoritative answers can be found from:
UNC.EDU nameserver = SAMBA.ACS.UNC.EDU
SAMBA.ACS.UNC.EDU internet address = 128.109.157.30 <p>除了调试,nslookup的一个实际应用是为named.ca文件获取根名字服务器的当前列表。你可以通过查询与根域相关的所有NS类型记录来做到: <p>&gt; set typ=NS
&gt; .
Name Server: fb0430.mathematik.th-darmstadt.de
Address: 130.83.2.30 <p>Non-authoritative answer:
(root) nameserver = NS.INTERNIC.NET
(root) nameserver = AOS.ARL.ARMY.MIL
(root) nameserver = C.NYSER.NET
(root) nameserver = TERP.UMD.EDU
(root) nameserver = NS.NASA.GOV
(root) nameserver = NIC.NORDU.NET
(root) nameserver = NS.NIC.DDN.MIL <p>Authoritative answers can be found from:
(root) nameserver = NS.INTERNIC.NET
(root) nameserver = AOS.ARL.ARMY.MIL
(root) nameserver = C.NYSER.NET
(root) nameserver = TERP.UMD.EDU
(root) nameserver = NS.NASA.GOV
(root) nameserver = NIC.NORDU.NET
(root) nameserver = NS.NIC.DDN.MIL
NS.INTERNIC.NET internet address = 198.41.0.4
AOS.ARL.ARMY.MIL internet address = 128.63.4.82
AOS.ARL.ARMY.MIL internet address = 192.5.25.82
AOS.ARL.ARMY.MIL internet address = 26.3.0.29
C.NYSER.NET internet address = 192.33.4.12
TERP.UMD.EDU internet address = 128.8.10.90
NS.NASA.GOV internet address = 128.102.16.10
NS.NASA.GOV internet address = 192.52.195.10
NS.NASA.GOV internet address = 45.13.10.121
NIC.NORDU.NET internet address = 192.36.148.17
NS.NIC.DDN.MIL internet address = 192.112.36.4 <p>nslookup完整的命令集可以通过nslookup中的help命令得到。 <p>6.2.5 其它有用工具
还有几个工具能帮助你完成作为一个BIND管理员的任务。这里我将概要地描述其中的两个。请查阅这些工具的文档来获取如何使用它们的信息。
hostcvt通过将你的/etc/hosts文件转换成named的主文件来帮助你进行初始BIND配置。它产生前向(A)和逆向映射(PTR)条目,并且管理别名等。当然,它不可能为你做整个工作,正如你仍想要,例如,调整SOA记录的超时值、增加MX记录等等这类工作。不过,它仍能帮助你节约几片阿司匹林。hostcvt是BIND原代码的一部分,但是你也能在几个Linux FTP服务器上找到作为一个独立的软件包的。
在设置好你的名字服务器以后,你可能想测试一下你的配置。做这件事的理想的(并且,就我所知而言)唯一的工具是dnswalk,一个基于perl的软件包,它通览你的DNS数据库,查找常见的错误并且验证信息的一致性。近来,dnswalk已在comp.sources.misc上发布,并且将会在所有对该组存档的FTP站点上存储(如果你不知道靠近你的任何这样的站点,ftp.uu.net将是一个可靠的地方)。 <p>注释
[1] 在Linux的FTP站点上有各种named执行文件,每个的配置稍有不同,有些将它们的pid文件放在/etc中,有些将pid文件存储在/tmp或/var/tmp中。
[2] 注意,这个例子中的域名是以无轨迹点给出的。Named的早期版本好象将轨迹点当作错误看待,并且悄无声息地舍弃了该行。BIND-4.9.3据称以修正。
[3] 注意,如果没有安装任何根服务器提示,你就不能向你的名字服务器查询根服务器。Catch-22!为了避免这个难题,你可以或者使得nslookup使用一个不同的名字服务器,或者你可以使用图6.2中的样本文件作为一个起点,然后获取一张有效服务器的完全列表。
 楼主| 发表于 2002-4-24 11:12:30 | 显示全部楼层

*#!&*Linux网络管理员手册[共16章节][转帖]

&nbsp; &nbsp;
Linux网络管理员手册(7)
<p>第七章 串行线路IP <p>
串行线路协议SLIP和PPP为资金缺乏者提供Internet连接。除了需要一个modem和一块配有FIFO缓冲的串行板(卡)外,不再需要其它的硬件了。使用它并不比使用一个邮箱复杂,并且不断增长的私人机构以可以接受的价格为大家提供拨号上网IP。
Linux有SLIP和PPP两种驱动程序。SLIP已存在相当长的时间了,并且工作的很稳定。PPP驱动程序是由Michael Callahan and Al Longyear最近开发的。PPP将在下一章中讨论。 <p>7.1 一般需求
要使用SLIP或PPP,你当然必须配置一些如前章所讨论的那些基本网络特性。起码,你必须设置回送(loopback)接口,并且提供名字解析。当连接到Internet上时,你当然要用到DNS。最方便的方法是将某个名字服务器的地址写入resolv.conf文件中;SLIP链接一旦被激活,就会查询这个服务器。名字服务器离你拨入的地方越近越好。
然而,这个方法并不是最佳的,因为所有的名字查找仍然都要通过你的SLIP/PPP链接。如果你担心这样做所耗费的带宽,你也可以设置一个只缓冲(caching-only)名字服务器。它并不真的服务于一个域,而只是作为你的主机所产生的所有DNS查询的一个中继。这个方案的优点在于它建立了一个缓冲,大多数的查询只需往串行线路上发送一次。一个只缓冲服务器的named.boot文件看上去象这样: <p>&#59; named.boot file for caching-only server
directory /var/named <p>primary 0.0.127.in-addr.arpa db.127.0.0 &#59; loopback net
cache . db.cache &#59; root servers <p>除了这个name.boot文件,你也还需要设置db.cache文件,其中含有有效根名字服务器的一张列表。这些在解析器的配置一章中的最后讨论。 <p>7.2 SLIP操作
拨号(上网)IP服务器通常使用特殊的用户帐号提供SLIP服务。在登陆进这样一个帐号以后,你不会进入普通的shell程序;而是执行一个程序或shell脚本,激活串行线路的服务器SLIP驱动程序并且配置适当的网络接口。然后你需要在链接的你这端做同样的工作。
在某些操作系统上,SLIP驱动程序是用户空间程序;在Linux下,它是内核的一部分,这使得它更快一些。然而,这需要将串行线路明确地转换成SLIP模式。这是通过特殊的tty线路规程,SLIPDISC,来做到的。当tty为普通线路规程(DISCO)时,它将使用普通的read(2)和write(2)调用只与用户进程交换数据,而SLIP驱动程序不能从tty读取或写进数据。在SLIPDISC规程里,规则正好相反:现在任何用户空间进程从tty的读取和写入被阻止,此时,从串行端口来的所有数据将被直接地传递到SLIP驱动程序。
SLIP驱动程序本身可以识别SLIP协议的多种变化。除了普通的SLIP,它也能理解CSLIP,这在输出的IP包上执行所谓的Van Jacobson头压缩。[1] 这显著地改进了交互式会话的吞吐量。另外,对于这些协议的每一种有六比特的版本。
将串行线路转换为SLIP模式的一种简单方法是通过使用slattach工具。假设你的modem连在/dev/cua3上,并且成功地登录上SLIP服务器。然后执行: <p># slattach /dev/cua3 &amp; <p>这将cua3的线路规程转换成SLIPDISC,并把它连接到SLIP网络接口之一。如果这是你的第一次激活的SLIP链接,该线路将连至sl0;第二个将连至sl1,以此类推。目前的内核同时支持多达八个SLIP链接。
Slattach所选择的缺省的压缩封装是CSLIP。你可以使用-p开关来选择任何其它的模式。要使用常规的SLIP(无压缩的),可以使用 <p># slattach -p slip /dev/cua3 &amp; <p>其它的模式有cslip、slip6、cslip6(SLIP的六比特版本)、以及适应性SLIP(adaptive SLIP)的adaptive。后者让内核找出远端所用的是那一种SLIP压缩封装类型。
注意,你必须使用与你的对等点同样的压缩封装。例如,如果cowslip使用CSLIP,你也必须使用它。如果选择不匹配,那么将会出现ping到远程主机将收不到任何返回信息包的现象。如果其它的主机ping你,那么在你的控制台上也会出现象“不能建立ICMP头”(“Can’t build ICMP header”)的信息。避免这些问题的一种方法是使用适应性SLIP。
实际上,slattach并不仅仅允许你使能SLIP,同样也可以激活串行线路的其它协议,如PPP或KISS(另一个由无线电爱好者使用的协议)。详细信息,请参考slattach(8)再线手册。
在将线路转至SLIP驱动程序以后,你必须配置这个网络接口。再一次,我们使用标准的ifconfig和route命令来做这个配置。假设从vlager,我们拨号到一个名为cowslip的服务器。那么你要执行 <p>#ifconfig sl0 vlager pointopoint cowslip
# route add cowslip
# route add default gw cowslip <p>第一个命令将接口配置成到cowslip的点对点链接,而第二、第三个命令增加到cowslip的路由以及使用cowslip作为一个缺省的网关。
当拆卸一个SLIP链接时,你首先必须使用带del选项的route命令移去所有通过cowslip的路由,将接口关闭,并向slattch发送一个hangup信号。然后,你必须再次使用你的终端程序挂断modem: <p># route del default
# route del cowslip
# ifconfig sl0 down
# kill -HUP 516 <p>7.3 使用dip
现在来看,上面讲的是非常简单的。然而,你也许想使上面的步骤自动地执行,这样你就可以只调用一个简单的命令来执行上面给出的所有步骤了。这也就是dip所要做的。[2] 在写作这本手册时它的当前发行版本是3.3.7。它已被许多人大大地修改过了,所以它已不再是原来的dip程序了。这些不同的开发变化有希望在今后的版本中合并。
Dip为简单的脚本语言提供了一个解释器,它能为你处理modem,将线路转变为SLIP模式,并配置接口。这是非常基本的和有局限性的,但对于大多数情况已足够有效了。某天一个新的dip版本将能适用于更为广泛的语言。
为了配置SLIP接口,dip需要root权限。现在可以临时使用dip将uid置为root,因此所有的用户能够拨号到某个SLIP服务器而不需要给这些用户root权限。这是非常危险的,因为用dip设置假的接口和默认路由可能会严重地破坏网络的路由。更糟的是,这将给你的用户连接到任何SLIP服务器的能力,并在你的网络上带来危险的攻击。所以如果你想允许你的用户建立一个SLIP连接,就为每个期望的SLIP服务器写一个小的包装程序,并且让这些包装程序调用包括建立连接用的特定脚本的dip。那么,这些程序就可以安全地置成root的uid。[3] <p>7.3.1 一个简单的脚本程序
图7.1列出了一个简单的脚本程序。通过用脚本程序的名字作为参数调用dip,它可以用于连接cowslip: <p># dip cowslip.dip
DIP: Dialup IP Protocol Driver version 3.3.7 (12/13/93)
Written by Fred N. van Kempen, MicroWalt Corporation. <p>connected to cowslip.moo.com with addr 193.174.7.129
# <p>当激活了SLIP并连接到cowslip以后,dip将从终端上脱开并运行于后台。此时你就可以在SLIP连接上使用通常的网络服务了。要想终止连接,只需用-k选项调用dip。这使用/etc/dip.pid [4]中记录的进程id dip给dip进程发送了一个挂断信号: <p># kill –k <p>在dip的脚本语言中,前加美元符号的关键字表示变量名。Dip有一个预定义的变量集,将在下面列出。例如,$remote和$local含有与SLIP连接有关的本地以及远程主机的主机名。 <p># Sample dip script for dialing up cowslip <p># Set local and remote name and address
get $local vlager
get $remote cowslip <p>port cua3 # choose a serial port
speed 38400 # set speed to max
modem HAYES # set modem type
reset # reset modem and tty
flush # flush out modem response <p># Prepare for dialing.
send ATQ0V1E1X1 r
wait OK 2
if $errlvl != 0 goto error
dial 41988
if $errlvl != 0 goto error
wait CONNECT 60
if $errlvl != 0 goto error <p># Okay, we&quot;re connected now
sleep 3
send  r n r n
wait ogin: 10
if $errlvl != 0 goto error
send Svlager n
wait ssword: 5
if $errlvl != 0 goto error
send hey-jude n
wait running 30
if $errlvl != 0 goto error <p># We have logged in, and the remote side is firing up SLIP.
print Connected to $remote with address $rmtip
default # Make this link our default route
mode SLIP # We go to SLIP mode, too
# fall through in case of error <p>error:
print SLIP to $remote failed. <p>图7.1 一个dip脚本样本 <p>样本脚本程序中的头两句是get命令,这是dip设置变量的方法。这里,本地和远程主机名分别设置成了vlager和cowslip。
接下来的五句用来设置终端线路和modem。Reset向modem发送了一个复位串;对于Hayes兼容的modem,这是个ATZ命令。下一个语句刷出modem的响应,以使得接下来的几行中的登录会话能够正常的工作。这个对话是非常直观的:它简单地拨出cowslip的号码41988,并且使用口令hey-jude登录进Svlager帐号。Wait命令使得dip等待给出的字符串作为它的第一个参数;作为第二个参数的秒数使得在这些秒数之后如果还没有收到这样的字符串时使等待超时。散布在登录过程中的If命令检查执行命令时是否有错。
在登录后最后执行的命令是default --它使得SLIP连接成为所有主机的缺省路由,和mode –它在线路上激活SLIP模式并且为你配置接口和路由选择表。 <p>7.3.2 dip参考
尽管dip被广泛地使用着,但它至今没有很好的文档。因此在这一节,我们将给出大部分dip命令的参考。你可以使用测试模式调用dip来得到所有命令的一个概观,并且进入帮助命令。要找出一个命令的句法,你可以不加任何参数地键入它;当然这对不用参数的命令是没有效的。 <p>DIP&gt; help
DIP knows about the following commands: <p>databits default dial echo flush
get goto help if init
mode modem parity print port
reset send sleep speed stopbits
term wait <p>DIP&gt; echo
Usage: echo on|off
DIP&gt; <p>下面,所有显示有DIP&gt;提示符的例子示出了如何在测试模式下输入一个命令,以及该命令所产生的输出。没有这个提示符的示例将作为脚本引用。 <p>modem命令 <p>dip提供了许多配置你的串行线路和modem的命令。有些是显而易见的,如port—它选择一个串行口,以及speed、databits、stopbits和parity,这些是用来设置通常的线路参数的。
modem命令用来选择一个modem类型。目前,所支持的唯一类型是HAYES(需大写)。你必须给dip提供一个modem类型,否则的话,它将拒绝执行dial和reset命令。reset命令给modem发送一复位字符串;所用的字符串依赖于选择的modem类型。对于Hayes兼容modem,它是ATZ。
flush命令用于刷新modem迄今为止所发出的所有响应。否则的话跟在reset后面的会话脚本可能会混淆,因为它会读取早些命令的OK响应。
init命令用于在拨号之前向modem选择发送一条初始化串。Hayes modem的缺省值是“ATE0 Q0 V1 X1”,它启动命令的回应和长结果代码,并且选择盲拨号(对拨号音不作检查)。
dial命令最终向modem发出初始化串并且向远程系统拨号。Hayes modem的缺省dial命令是ATD。 <p>echo和term <p>echo命令是用作调试目的的,当echo on时,就会使得dip在控制台上回显发送给串行设备的所有命令信息。通过调用echo off可以再次关闭回显。
dip同样允许你暂时离开脚本模式并进入终端模式。在这种模式下,你可以象任何其它常用的终端程序那样使用dip,写至串行线路并从串行线路读取信息。要离开这种模式,键入Ctrl-]。 <p>get命令 <p>get命令是dip设置变量的方法。最简单的形式是将变量设置成一个常数,正如用于上面例子中的一样。然而,你也可以通过指定关键字ask代替一个值来提示用户输入: <p>DIP&gt; get $local ask
Enter the value for $local: <p>第三种方式是试着从远程主机取得这个值,这在某些情况下是非常有用的:有些SLIP服务器不允许你在SLIP连接上使用自己的IP地址,而是在你拨入时从一个地址池中取得一个分配给你,显示出一些信息通知你有关给你分配的地址。如果该信息看上去象这样“Your address: 193.174.7.202”,那么下面一段dip代码将让你获取地址: <p>… login ….
wait address: 10
get $locip remote <p>print命令 <p>这个命令是向dip启动的控制台上回显文字。任何dip变量都可以用于print命令中,如 <p>DIP&gt; print Using port $port at speed $speed
Using port cua3 at speed 38400 <p>变量名
dip只认识一组预定义的变量。变量名总是以美元符号开头并且必须用小写字符。
$local和$locip变量含有本地主机的名字和IP地址。设置主机名使得dip将规范主机名存入$local,同时将相应的IP地址存入$locip。设置$locip也类似于设置$local。
$remote和$rmtip变量对远程主机名和地址做同样的事情。$mtu含有连接的MTU值。
这五个变量是仅有的能够使用get命令直接进行赋值的。主机的其它变量只能通过相应的命令来设置,但可以用于print语句;这些是$modem、$port和$speed。
通过$errlvl变量你可以获得上一条命令执行的结果。一个0错误号表示成功,而非零值表示有错。 <p>if和goto命令
if命令相对于平常所称的if来说更是一个条件分支。它的语法是 <p>if var op number goto label <p>这里表达式必须是与变量$errlvl、$locip、和$rmtip之一的一个简单的比较关系。第二个操作数必须是一个整数;运算符op可以是==、!=、&lt;、&gt;、&lt;=、以及&gt;=之一。
goto命令使得脚本跳转至label标号后继续执行。一个标号必须是一行中头一个记号,并且必须紧跟一个分号。 <p>send、wait和sleep
这些命令在dip中帮助实现简单的会话脚本。 send将它的参数输出到串行线路上。它不支持变量,但是支持所有C-风格的反斜杠字符序列如 n和 b。发音字符(~)用作回车/换行的缩写。
wait将一个单词作为参数,扫描串行线路上的所有输入直到识别出这个单词。这个单词中不能含有任何空格。作为选项,你可以给wait一个超时值作为第二个参数;如果在该期间内没有收到期望的单词,命令将返回并置$errlvl值为1。
sleep语句可以用来等待一段时间,例如耐心地等待登录序列的完成,再次,间隔时间是以秒计的。 <p>mode和default
这些命令用于将串行线路转换至SLIP模式和配置接口。
mode命令是dip在进入后台执行前最后执行的命令。除非出错,否则这个命令没有返回。
mode将一个协议作为参数。目前dip只能识别SLIP和CSLIP作为有效的名字。然而当前版本的dip不能识别适应性SLIP。
当在串行线路上激活SLIP以后,dip执行ifconfig将接口配置成点对点连接,并且调用route将路由设置至远程主机。
另外,如果脚本在mode之前先执行default,dip也会使得缺省路由指向SLIP连接。
7.4 运行于服务器模式
设置你的SLIP客户是最艰难的部分。相反地,也即配置你的主机作为SLIP服务器,就很容易了。
一种方法是以服务器模式使用dip,可以通过以diplogin方式调用它来完成。它的主要配置文件是/etc/diphosts,它将登录名与分配给这台主机的地址相关联。另一种方法是,你也可以使用sliplogin,这是一个源自于BSD的工具,具有更灵活的配置方案,能在主机连接和脱开时让你执行shell脚本。目前这是个Beta版本。
这两个程序都需要你为每个SLIP客户设置一登录帐号。例如,假设你为在dent.beta.com的Arthur Dent提供SLIP服务,你可以通过在你的passwd文件中增加下面一行来建立一个名为dent的帐号: <p>dent:*:501:60:Arthur Dent&quot;s SLIP account:/tmp:/usr/sbin/diplogin <p>此后,你要使用passwd工具设置dent的口令。
现在,当dent登录时,dip将作为一个服务器启动。为了查出他确实允许使用SLIP,dip将查找/etc/diphosts中的用户名。这个文件详细列出了每个SLIP用户的访问权限和连接参数。dent的样本条目就象这样: <p>dent::dent.beta.com:Arthur Dent:SLIP,296 <p>冒号分隔的第一个字段是用户登录用的名字。第二个字段可以含有一个另加的口令(见下面)。第三个字段是拨号的主机名或IP地址。下一个字段是没有任何特殊意义的信息字段(至今)。最后一个字段描述了连接参数。这是一个用逗号分隔的列表,指定协议(目前只有SLIP或CSLIP),后跟MTU。
当dent登录时,diplogin从diphosts文件中抽取出他的有关信息,并且,如果第二个字段不空的话,提示输入一个“外部安全口令”。用户输入的字符串将与diphosts中的相应口令(未加密的)相比较。如果它们不匹配的话,这个登录企图将被拒绝。
否则的话,diplogin通过将串行线路转换成CSLIP或SLIP、并且设置接口和路由来处理。这个连接将保持建立状态直到用户断开并且modem撤消连线为止。此时,diplogin将线路返回到普通线路规程并且退出。
diplogin需要超级用户特权。如果你没有让dip运行setuid为root,那么你应该使得diplogin是dip的一个独立的拷贝,而不是一个简单的连接。然后,diplogin能够安全地被setuid,而不会影响dip本身的状态。 <p><p>注释
[1] 在RFC1441中描述了Van Jacobson头压缩。
[2] dip意思是Dialup IP。它是由Fred van Kempen编制的。
[3] diplogin 也能够(并且必须)运行setuid。见本章最后一节。
[4] 对于使用三字符的首字母缩写词的更多的回文乐趣,参见新闻组alt.tla。
 楼主| 发表于 2002-4-24 11:13:07 | 显示全部楼层

*#!&*Linux网络管理员手册[共16章节][转帖]

&nbsp; &nbsp;
Linux网络管理员手册(8)

第八章 点对点协议 <p>
8.1 揭开P字母 <p>正像SLIP一样,PPP是在串行连接上发送数据报的协议,但却改进了前者的几个不足之处。它让通信的双方在开始时协商诸如IP地址和最大数据报大小等选项,并且为客户提供授权(权限)。对于每个这样的功能,PPP都有一个独立的协议。下面,我们将概要地讨论PPP的这些基本创建框图。这里的讨论远不是完整的;如果你想对PPP知道的更多些,极力推荐你阅读RFC-1548中它的规格说明,以及许多相关的RFCs。[1]
PPP的最底层是高级数据链路控制协议(High-Level Data Link Control Protocol),缩写为HDLC,[2] 它定义了单个PPP帧的分界,并提供了16比特的检查和。相对于非常原始的SLIP包装来说,一个PPP帧能够容纳除IP以外的其它协议,如Novell的IPX、或Appletalk。PPP通过在基本的HDLC帧上加上一个协议字段来做到这功能,这个字段用于识别帧所携带的包的类型。
LCP,链路控制协议(the Link Control Protocol),用于HDLC的上层,用于协商适合于数据链路的选项,如指出链路的一边同意接收的最大数据报大小的最大接收单元(MRU)。
在PPP连接的配置阶段重要的一步是客户授权(权限)。尽管不是强制的,但对于拨号线路几乎是必要的。通常,被呼叫的主机(服务器)通过验证客户是否知道某个秘密的键值来要求客户认证自己。如果呼叫者不能给出正确的秘密键值,连接就中断了。使用PPP,授权工作是双方面的;也即,呼叫者也可以要求服务器认证自己。这些认证过程对于双方是完全独立的。对于不同的认证类型有两个协议,我们将在下面更进一步地讨论。它们被命名为口令认证协议(Password Authentication protocol),或PAP和质询握手认证(Challenge Handshake Authentication Protocol),或CHAP。
路由通过数据链路的每一个网络协议,如IP、Appletalk等等,使用相应的网络控制协议(Network Control Protocol)(NCP)被动态地配置。例如,要通过链路发送IP数据报,PPP的双方首先必须协商双方使用的IP地址。用于此目的的控制协议是IPCP,即互连网协议控制协议(Internet Protocol Control Protocol)。
除了通过链路发送标准的IP数据报,PPP也支持IP数据报的Van Jacobson头压缩。这是一项将TCP包头缩小到仅有三个字节的技术。它也用于CSLIP,并且常常通俗地称为VJ头压缩。是否使用压缩同样可以在开始时通过IPCP协商来决定。 <p>8.2 Linux上的PPP
在Linux中,PPP的功能被分成了两个部分,一个是位于内核的低级的HDLC驱动程序部分,另一部分是处理各种控制协议的用户空间的pppd后台程序。Linux的PPP当前发行版是linux-ppp-1.0.0,包含有内核PPP模块、pppd、和一个用于拨号至远程系统的称为chat的程序。
PPP内核驱动程序是由Michael Callahan编制的。pppd源自于为Sun和386BSD机器的一个免费PPP实现,它是由Drew Perkins和其他人编制的,并且由Paul Mackerras维护。是由Al Longyear[3] 移植到Linux上的。chat是由Karl Fox编制的。[4]
正如SLIP,PPP是通过一个特殊的线路规程来实现的。要以PPP连接使用某个串行线路,你首先要象往常那样通过modem建立一个连接,随后将线路转换成PPP模式。在这种模式下,所有的进入的数据都传给了PPP驱动程序,该驱动程序检查传入的HDLC帧的有效性(每个HDLC帧带有一个16比特的检验和),并且解开并分发它们。目前,它能够处理IP数据报,可选地使用Van Jacobson头压缩。为了支持IPX,PPP驱动程序也将被扩展成能处理IPX包。
内核的驱动程序是由pppd,PPP后台程序,协助工作的,在实际的网络通信能在链路上进行之前,它执行必要的整个初始化和认证过程。pppd的行为可以使用一些选项来调整。由于PPP非常复杂,不可能在一章中解释所有的东西。因此本书不打算涵盖pppd的所有方面,而只是给你一个介绍。详细信息,请参考在线手册页和pppd原始发行版中的READMEs,它将帮助解决在这章中没有讨论过的大多数问题。如果在阅读了所有的文档之后你的问题还没有得到解决,你应该到新闻组comp.protocols.ppp寻求帮助,在那里你可以接触到包括pppd开发者的大多数人。 <p>8.3 运行pppd
当你想通过一个PPP连接连到Internet上,你必须设置好基本的网络功能,如回送设备和解析器。这两者已在前面章节中讨论过了。还有些有关在串行链路上使用DNS的解释;请参考SLIP一章中对此的描述。
作为一个使用pppd如何建立一个PPP连接的入门例子,假设你再次在vlager。你已经拨号到PPP服务器,c3po,并且登录进ppp帐号。c3po已经启动它的PPP驱动程序。在退出用于拨号的通信程序以后,你执行下面的命令: <p># pppd /dev/cua3 38400 crtscts defaultroute <p>这会将串行线路cua3转换到PPP模式并建立一个到c3po的IP连接。用于串行端口的传输速度将是38400bps。crtscts选项打开端口的硬件握手功能,这对于高于9600bps的速度是绝对必要的。
在启动之后pppd所做的首件事情是使用LCP与远端协商几种连接特性,通常,pppd所试用的缺省的选项集将能工作,所以我们不打算在这里考虑这些。我们将在后面几节中再回过来详细讨论LCP。
此时,我们也假设c3po不需要从我们这边取得任何认证,所以配置阶段成功地完成了。
然后pppd将使用IPCP,IP控制协议,与它的对等点协商IP参数。由于上面我们没有对pppd指定任何特殊的IP地址。它将试着使用通过解析器查找本地主机名获得的地址。此后,两者将向对方宣告他们的地址。
通常,这些缺省设置并没有什么错误。即使你的机器是在一个以太网上,你可以对以太网和PPP接口使用同一个IP地址。当然,pppd允许你使用不同的地址,或者请求对方使用某个特定的地址。这些选项将在以后章节中描述。
在通过了IPCP设置阶段以后,pppd将准备你的主机的网络层来使用PPP连接。它首先配置PPP网络接口作为一个点对点连接,对第一个活动的PPP连接使用ppp0,对第二个使用ppp1,依次类推。下一步,它将设置一个指向链路另一端主机的路由表条目。在上面示出的例子中,pppd将使得缺省网络路由指向c3po,因为我们已给它defaultroute选项。[5] 这使得所有到不在本地网络上主机的数据报都被发送到c3po。pppd还支持几个不同的路由选择方案,这将在本章后面详细讨论。 <p>8.4 使用选项文件
在pppd分析它的命令行参数之前,为了查找缺省选项它扫描几个文件。这些文件可能含有有效的命令行参数,它们分布在任意的行上。注释语句是由“#”开头的。
第一个选项文件是/etc/ppp/options,当pppd启动时总会扫描它。使用它设置一些全局缺省值是个好主意,因为它允许你阻止你的用户做某些危及安全的事情。例如,要使得pppd要求对方某种授权认证(PAP或CHAP),你应该在该文件中加入auth选项。用户覆盖不了这个选项,所以与不在我们的授权数据库中的任何系统建立一个PPP连接变成不可能的事。
在/etc/ppp/options文件以后读取的其它选项文件,是用户主目录中的.ppprc。它允许每个用户指定她自己的缺省选项集。
一个样本/etc/ppp/options文件可以是象这样的: <p># Global options for pppd running on vlager.vbrew.com
auth # require authentication
usehostname # use local hostname for CHAP
lock # use UUCP-style device locking
domain vbrew.com # our domain name <p>这些选项的头两个用于权限认证并且将在下面给出解释。lock关键字使得pppd遵守标准的UUCP设备锁定方法。根据这个惯例,每个访问串行设备的进程,如/dev/cua3,在UUCP spool目录中创建一个名为LCK..cua3的锁定文件,用于指示该设备正在使用。这是避免任何其它程序如minicom或uucico去打开PPP正在使用的串行设备。
在全局配置文件中提供这些选项的原因是如上显示的那些选项是不能被覆盖掉的,因而提供了一个合理的安全级。然而,请注意有些选项可以在后面被覆盖掉;这样的一个例子是connect串。 <p>8.5 使用chat拨出
在上例中让你感到不便的事情之一是在你能够启动pppd之前必须手工地建立连接。不象dip,pppd对于拨号至远程系统以及登录没有自己的脚本语言,而是需要依赖于某些外部程序或shell脚本来做这些事。要执行的命令可以用connect命令行选项给予pppd。pppd将重定向该命令的标准输入和输出到串行线路上。针对此一个有用的程序是expect,是由Don Libes编写的。它有一个基于Tcl的非常强大的语言,并且是针对此类应用明确地设计出来的。
pppd软件包带有一个同样称为chat的程序,是用于指定UUCP-风格的会话脚本的。基本上说,一个会话脚本是由我们期望从远程系统收到的交互式的字符串序列以及我们所发送的应答字符串序列。我们将分别称之为期望字符串和发送字符串。这是从一个典型会话脚本中的摘录: <p>ogin: b1ff ssword: s3kr3t <p>这告诉chat等待远程系统发送来登录提示,并且返回登录名b1ff。我们只是等待ogin: 所以登录提示是大写还是小写没什么关系,也不用管它是否完全正确。接下来的又是一个期望字符串它使得chat等待口令输入提示,并且随后发出你的口令。
这基本上,上面是chat脚本所要做的。当然,拨号到一个PPP服务器的完整脚本也必须包括适当的modem命令。假设你的modem使用Hayes命令集,并且服务器的电话号码是318714。那么与c3po创建一个连接的完整的会话请求是 <p>$ chat -v &quot;&quot; ATZ OK ATDT318714 CONNECT &quot;&quot; ogin: ppp word: GaGariN <p>根据定义,头一个字符串必须是期望字符串,但是在我们启动modem之前,modem是不会发出任何东西的,所以我们通过指定一个空串来跳过第一个期望字符串。然后我们继续发出ATZ,即Hayes兼容modem的复位命令,并等待它的响应(OK)。下一个串向chat发送出一个拨号命令和电话号码,并且期望得到CONNECT消息的响应。接下来又是一个空串,因为我们现在还不想发送出任何信息,而是等待登录提示的出现。余下的chat脚本所做的工作完全象我们上面描述的一样。
-v选项使得chat将所有的活动记录在syslog后台程序的local2中。[6]
在命令行上写出会话脚本会承担一定的风险,因为用户可以使用ps命令观察进程的命令行。你可以将会话脚本放入一个文件,比如说是dial-c3po,来避免这个风险。通过给chat一个-f选项后跟这个文件名,你可以使得chat从该文件中读取脚本取而代之从命令行读取。现在完整的pppd命令就象这样: <p># pppd connect &quot;chat -f dial-c3po&quot; /dev/cua3 38400 -detach   
crtscts modem defaultroute <p>除了指定拨号脚本的connect选项,我们在命令行上多加了两个选项:-detach—告知pppd不要从控制台分离并且变成为后台进程。Modem关键字使得pppd在串行设备上执行某些modem专用的动作,就如在拨号之前和之后挂断线路。如果你不使用这个关键字,pppd将不会监视端口的DCD线,因而将不会检测是否远端出呼意料地挂断了。
上面给出的例子是非常简单的;chat允许有更为复杂的会话脚本。一个非常有用的特性是指定中止含有错误的的会话。典型的中止字符串是象消息BUSY、或NO CARRIER,这是当所拨的号码是忙音、或没有提起电话时,你的modem产生的。为了使得chat迅速地识别出这些中止字符串,而不是等到超时,你可以使用ABORT关键字在脚本的开头指定它们: <p>$ chat -v ABORT BUSY ABORT &quot;NO CARRIER&quot; &quot;&quot; ATZ OK ... <p>以同样的方式,你可以通过插入TIMEOUT选项来改变会话部分中的超时值。详细资料,请参见chat(8)的手册页。
有时,你也想有条件地执行会话脚本的一部分。例如,当你没有接收到远端的登录提示时,你可能想发送一个BREAK,或一个回车键。你可以通过给期望字符串附加一个子脚本来做到。它是由一系列的发送和期望字符串组成,正象整个脚本本身,它是用连字号分开的。每当附加的期望字符串没有及时收到时,该子脚本就会被执行。在上面的例子中,我们要象下面那样修改会话脚本: <p>ogin:-BREAK-ogin: ppp ssword: GaGariN <p>现在,当chat没有收到远程系统发送的登录提示时,子脚本就被执行,首先发送一个BREAK,然后再次等待登录提示的出现。如果现在提示出现时,脚本就会象往常那样继续,否则的话,它将带错而终止。 <p>8.6 调试你的PPP设置
缺省地,pppd将把任何警告和出错消息记录到syslog的daemon设施中。你必须往syslog.conf中增加一个条目,以使得这些消息重定向到一个文件中,或者甚至到控制台上,否则的话syslog就会轻易地丢弃这些消息。下面这个条目将所有的消息送到/var/log/ppp-log: <p>daemon.* /var/log/ppp-log <p>如果你的PPP设置不能立刻工作,查看这个日志文件会给你什么地方出错的一点提示。如果这没有什么帮助,你可以使用debug选项打开额外的调试输出信息。这使得pppd将所有发送和接收的控制数据包的内容记录到syslog中。所有的消息将传入daemon设施中。
最后,最猛烈的方法是通过使用选项kdebug调用pppd,以激活内核层的调试。在该选项之后是下面数值的比特位或运算的数值:1表示一般调试消息,2 表示打印所有传入的HDLC帧的内容,4 是使得驱动程序打印出所有传出的HDLC帧。要捕获内核的调试消息,你必须或者运行读取/proc/kmsg文件的syslogd后台程序,或者是klogd后台程序。这两者都将内核的调试信息定向到syslog的kernel设施中。 <p>8.7 IP配置选项
在连接配置期间,IPCP是用于协调几个IP参数的。通常,每个端点都会发出一个IPCP配置请求包,指出它想要改变哪些缺省值,改成什么值。在接收方,远端依次检查每个选项,并且或者同意改变或者拒绝。
关于pppd将尝试协调哪些IPCP选项,pppd给了你许多的控制权。你可以通过命令行选项来调节这些选项,我们将在下面讨论它们。 <p>8.7.1 选择IP地址
在上面的例子中,我们用pppd拨号到c3po并且建立了一个IP连接。在连接的两端没有预备要选择一个特定的IP地址。而是使用vlager的地址作为本地IP地址,并让c3po自己给出自己的。然而,有时候在连接的一端或两端控制要使用的地址是很有用的。pppd支持这种控制的几种变异。
要请求特定的地址,通常你要给pppd提供下面的选项: <p>local_addr:remote_addr <p>这里local_addr和remote_addr可以用点分四组表示法表示,或用主机名表示。[7] 这使得pppd试图使用第一个地址作为它自己的IP地址,而第二个作为对等点的。如果在IPCP协商时,对方拒绝了其中之一的地址,那么就不能建立起IP连接了。[8]
如果你只想设置本地地址,并接受任何对等点使用的地址,你只需不使用remote_addr部分就行了。例如,要使得vlager使用IP地址130.83.4.27而不使用自己的IP地址,你需要在命令行上给出130.83.4.27:即可。类似地,如果只想设置远端点的地址,你只需让local_addr字段为空。此时,缺省地,pppd将使用与你的主机相应的地址。
有些处理许多客户站点的PPP服务器动态地为客户分配地址:只有当拨号进来时才给客户系统分配地址,而当客户退出时就再次清除。当拨号到这种服务器时,你必须确信pppd没有要求从服务器要求任何特定的IP地址,而是接受服务器让你使用的地址。这意味着你不必指定local_addr参数。另外,你必须使用noipdefault选项,该选项使得pppd等待对等点提供IP地址,以替代使用本地主机的地址。 <p>8.7.2 通过PPP连接进行路由
在设置好网络接口以后,pppd通常将主机的路由只设置到它所连接的远端点上。如果远端主机是在一个LAN上,你当然也希望能够连接到远端主机所在网络的其它主机上;也即,必须设置一个网络路由。
上面,我们已经知道可以使用defaultroute选项请求pppd设置默认的路由。如果你所拨号连接的服务器将作为你的Internet网关话,那么这个选项将是非常有用的。
相反的情况是,你的系统作为孤独的主机的一个网关,也同样很容易做到。例如,假设虚拟酿酒厂的某个雇员,他家的机器叫做loner。当通过PPP连接到vlager时,他使用酿酒厂子网的地址。在vlager端,我们现在可以给pppd一个proxyarp选项,它将为loner安装一个代理ARP条目。这将自动地使得loner可以访问酿酒厂和葡萄酒厂的所有主机了。
然而事情并不是总是那样的简单,例如,当连接两个局域网时。这常常需要增加一个特殊的网络路由,因为这些网络都可以有它们自己默认的路由。另外,使得两个端点使用PPP连接作为默认路由将产生一个循环,到未知目的地的包将在这两个端点之间来回传送,直到它们过了存活期。
作为一个例子,假设虚拟酿酒厂在某个其它城市开了一个分支机构。这个附属机构使用IP网络号191.72.3.0运行一个他们自己的以太网,它是酿酒厂的B类网络的子网3。他们想通过PPP连接到酿酒厂的主以太网上以更新客户的数据库等等。再次,vlager将作为一个网关;它的远端点被称作sub-etha且IP地址为192.72.3.1。
当sub-etha连接到vlager时,它将象平常一样使得默认路由指向vlager。然而,在vlager上,我们必须为通过sub-etha的子网3安装一个网络路由。为此,我们使用一个pppd的至今还没有讨论过的特性—ip-up命令。这是一个位于/etc/ppp中的shell脚本或程序,是在PPP接口配置完以后执行的。当使用时,它是用下列参数调用的: <p>ip-up iface device speed local addr remote addr <p>这里,iface指定所使用的接口,device是所使用的串行设备文件(如果使用了stdin/stdout,那么是/dev/tty)的路径名,speed是设备的速度。local_addr和remote_addr给出了以点分四组表示的用于连接两端点的IP地址。在我们这种情况下,ip-up脚本可以包含下列代码段: <p>#!/bin/sh
case $5 in
191.72.3.1) # this is sub-etha
route add -net 191.72.3.0 gw 191.72.3.1&#59;&#59;
esac
exit 0 <p>以类似的方式,/etc/ppp/ip-down是用于在PPP连接再次断开以后取消所有ip-up的活动。
然而,路由选择方案还没有完成。我们已经在双方的PPP主机上设置好了路由选择表条目,但至今,在两个网上的所有其它主机关于PPP连接的任何事情。如果在附属机构的所有主机有指向sub-etha的默认路由,并且酿酒厂的所有主机都默认地路由到vlager的话,
这就不是个大问题了。如果不是这样的话,那么你唯一的选择是使用一个象gated的路由选择后台程序。在vlager上创建了网络路由以后,路由选择后台程序将会对所有子网上的主机广播这个新路由。 <p>8.8 链路控制选项
上面,我们已经遇到过LCP,也即链路控制协议,它是用于协调链路特性以及测试链路的。
通过LCP协调的两个重要的选项是最大接收单元,和异步控制字符映射表。还有许多其它的LCP配置选项,但它们太特殊,这里就不给予描述了。请参考RFC1548中对它们的解释。
异步控制字符映射表,俗称异步表,是用于象电话线路的异步链路上确定必须被换码的控制字符(用一特殊的二字符序列替换)。例如,你可能想要避开用于软件握手信号的XON和XOFF字符,因为某些配置不当的modem在接收到一个XOFF时可能会卡住。其它的控制字符包括Ctrl-](telent的换码字符)。通过在异步表中指定这些控制字符,PPP允许你对ASCII码0到31 中的任何字符进行换码。
异步表是一个32比特宽的位图,最低比特位对应于ASCII的NUL字符,最高比特位对应于ASCII码31。如果一个比特位置位,它表示相应的字符在发送到链路之前必须被转义(换码)。最初,异步表被设置为0xffffffff,它表示所有的控制字符都将被转义。
为了告诉你的对等点不需要对所有的控制字符换码,而只需要对其中的几个进行转义,你可以使用asyncmap选项给pppd指定一个新的异步映射。例如,如果只有^S和^Q(ASCII 17和ASCII 19,通常用作XON和XOFF)必须被转义,那么就使用下面的选项: <p>asyncmap 0x000A0000 <p>最大接收单元(Maximum Receive Unit),或MRU,通知对等点我们想接收的HDLC帧的最大长度。尽管这会使你想起MTU的值(最大传输单元Maximum Transfer Unit),这两者很少有共同之处。MTU是内核网络设备的一个参数,描述了接口能够处理的最大帧的大小。而MRU只是对远端点不要产生任何大于MRU值的一个建议;不管怎样,接口必须能够接收最大为1500字节的帧。
因此,如何选择一个MRU的大小就与链路的传输能力关系不大了,而是与如何能达到最大的吞吐量有关。如果你打算在链路上运行交互式的应用程序,那么将MRU值设置为小到296是个不错的主意,这样一个偶然的大数据包(比如,从一个FTP来的会话)就不会使得你的光标“跳动”了。要告知pppd请求一个296的MRU,你必须给它一个选项mru 296。然而,小的MRUs只有在你没有禁止VJ头压缩(它默认是激活的)时才有意义。
pppd也能够理解一些设置协调过程整体行为的LCP选项,比如在链路终止前可以交换的最大请求配置数。除非你明确的知道你在做什么,否则不要改动它们。
最后,还有两个用于LCP回显消息的选项。PPP定义了两类消息,回显请求(Echo Reguest)和回显响应(Echo Response)。Pppd使用这个特性来检查一个链路是否还在运行。你可以通过使用lcp-echo-interval选项和一个以秒计的时间值来激活这个特性。如果在这个时间间隔内没有从远程主机收到帧,那么pppd生成一个Echo Reguest,并切期待对等点返回一个Echo Response。如果对等点没有产生一个响应,那么在发送了一定数量的请求以后链路即被中止。这个数量可以用lcp-echo-failure选项来设置。缺省地,这个特性是全部禁止的。 <p>8.9 常规安全考虑
一个配置不当的PPP后台程序能成为一个破坏性的安全缺口。它糟糕到象允许任何人能够将他的机器接入你的以太网上(这是非常糟糕的)。在本节中,我们将讨论一些能使你安全配置PPP的方法。
Pppd的一个问题是,要配置网络设备和路由选择表需要root权限。通常解决这个问题的办法是运行它setuid root。然而,pppd允许用户设置各种与安全相关的选项。为了免受用户可能通过操作这些选项而发起的攻击,建议你在全局/etc/ppp/options文件中设置一些默认值,就象使用选项文件一节例子中显示的。其中有些,比如授权认证选项用户是覆盖不了的,所以对操作起到了一定的保护作用。
当然,你也需要针对你用PPP连接的系统来保护自己。要挡开假冒他人的主机,你应该总是检查你的对等点的授权认证。另外,你不应该允许外部主机能使用它们选择的任何IP地址,而是限制他们只能使用几个地址。下面一节将涉及到这些问题。 <p>8.10 PPP授权认证
8.10.1 CHAP与PAP
对于PPP来讲,每个系统可以要求它的对等点使用两种授权认证协议之一来认证自己。这两个协议是口令认证协议(Password Authentication Protocol)(PAP)和质询握手认证协议(Challenge Handshake Authentication Protocol)(CHAP)。当创建了一个连接以后,两端都可以请求对方认证自己,而不管它是呼叫者还是被呼叫者。下面当我想区别认证系统和认证者时,我将宽松地用“客户”和“服务器”来讲。一个PPP后台程序能够请求它的对等点通过发送另一个确定期望的认证协议的LCP配置请求来进行认证。
PAP与通常的登录过程的工作原理基本上一样。客户通过向服务器发送一个用户名和一个(可以是加密的)口令来认证自己,服务器用它们与自己的秘密数据库相比较。对于那些通过监听串行线路以获得口令的偷听者和对于重复试验出错(trial and error)的攻击来说,这项技术是易受攻击的。
CHAP就没有这些不足之处。对于CHAP,认证者(也即是服务器)向客户发送一个随机生成的“质询”字符串和自己的主机名。客户使用该主机名来查询适当的秘码(口令),并将其与质询合在一起形成一个字符串,并且使用一个单向(杂凑)哈希函数加密该串。结果值与自己的主机名一起返回给服务器。现在服务器执行相同的计算,如果得到相同的结果就认可该客户。
CHAP的另一个特性是它不仅在开始时请求客户认证自己,而且每隔一定的时间就发送一个质询,以确信客户并没有被入侵者替换掉,例如通过切换电话线路。
pppd将CHAP和PAP的秘密键值分别存放在两个不同的文件中,称为/etc/ppp/chap-secrets和pap-secrets,通过使用一个或另一个文件来进入远程主机,你可以很好地控制是使用CHAP还是PAP来与对方认证我们自己,反之也然。
默认地,pppd无须来自远端的认证,但是同意来自远端的认证请求。由于CHAP比PAP来得更为稳固和强壮,pppd会尽可能地使用前者。如果对方不支持它,或者pppd在它的chap-secrets文件中找不到该远程系统的一个CHAP秘密(密码),它就回过来使用PAP。如果它也没有针对于对等点的PAP密码,它就拒绝做任何认证。结果,连接被关闭。
这种行为可以从几个方面进行修改。例如,当给出auth键值时,pppd将请求对方来认证自己。如果pppd分别在CHAP或PAP数据库中有一个对于该对等点的密码时, pppd将同意使用CHAP或PAP来做。还有一个可以打开或关闭特定认证协议的选项,但这里我们就不再描述它们了。详细信息请参考pppd(8)手册页。
如果所有和你进行PPP对话的系统同意为你认证它们自己,你应该将auth选项放入全局/etc/ppp/options文件中并且为每个系统在chap-secrets文件中定义口令。如果一个系统不支持CHAP,那么就在pap-secrets文件中为其加入一个条目。这样,你就可以确信连接到你的主机上的任何系统都是认证过的。
下面两节描述了这两个PPP密码文件,pap-secrets和chap-secrets。它们位于/etc/ppp中,包含客户、服务器和口令三为一组的值,还可以后接任选的一个IP地址列表。客户和服务器字段的解释对于CHAP和PAP是不同的,这也起决于我们是否要为对方认证我们自己,或者要求服务器为我们认证它们自己。 <p>8.10.2 CHAP的秘密文件
当pppd必须为某些使用CHAP的服务器认证自己时,pppd就在pap-secrets文件中寻找客户字段与本地主机名相同、服务器字段与在CHAP质询中发送来的远程主机名相同的条目。当要求对等点认证它自己时,该规则只是简单地反一下:此时pppd寻找客户字段与远程主机名相同(经由客户的CHAP响应发送过来的)、服务器字段与本地主机名相同的条目。 <p>下面是vlager的一个样本chap-secrets文件:[9] <p># CHAP secrets for vlager.vbrew.com
#
# client server secret addrs
#-------------------------------------------------------------------
vlager.vbrew.com c3po.lucas.com &quot;Use The Source Luke&quot; vlager.vbr
c3po.lucas.com vlager.vbrew.com &quot;riverrun, pasteve&quot; c3po.lucas
* vlager.vbrew.com &quot;VeryStupidPassword&quot; pub.vbrew. <p>当与c3po建立了一个PPP连接时,c3po要求vlager通过发送一个CHAP质询用CHAP来认证自己。然后pppd扫描chap-secrets文件中的客户字段等于vlager.vbrew.com、服务器字段等于c3po.lucas.com的条目,[10] 这样就找到了上面的第一行。然后它就从质询字符串和密码(Use The Source Luke)生成一个CHAP响应,并发送给c3po。
与此同时,pppd为c3po组合成一个CHAP质询,其中包含一个唯一的质询字符串和它的全资主机名vlager.vbrew.com。c3po以刚才我们讨论的方式构成一个CHAP响应,并将其返回给vlager。现在,pppd从响应中取得客户的主机名(c3po.vbrew.com),并且查找chap-secrets文件中客户字段为c3po、服务器字段为vlager的一行。这正是上面的第二行,所以pppd将CHAP质询和该行的密码(riverrun, pasteve)组合在一起并进行加密,并将结果与c3po的CHAP响应相比较。
可选的第四个字段列出了在第一个字段的客户的IP地址的一个列表。这个地址可以用点分四组表示法给出也可以用解析器查找出的主机名给出。例如,如果c3po在IPCP协商中请求使用一个不在这个列表中的IP地址,请求将被拒绝,并且IPCP将被关闭。因此在上面所示的样本文件中,c3po被限制于只能使用自己的IP地址。如果地址字段是空的,那么就允许使用任何地址;如果该字段不空,就限制了该客户使用的IP地址。
样本chap-secrets文件的第三行允许任何主机与vlager建立一个PPP链接,因为一个为*的客户或服务器字段与任何主机名匹配。唯一的限制是这些主机必须知道秘码,并且使用地址pub.vbrew.com。以通配符作主机名的任何条目可以在秘密文件中的任何地方,因为pppd总是使用服务器/客户对最为匹配的条目。
关于pppd在秘密文件中查找获取主机名的方式,还有一些要作说明。就象前面所解释的,远程主机名总是通过对等点的CHAP质询或响应包提供的。本地主机名缺省的是通过调用gethostname(2)函数来得到的。如果你已经将系统名设置为你的非限制的主机名,这样的话,你就必须使用domain选项为pppd另外给出一个域名: <p># pppd …domain vbrew.com <p>这将使得对于所有有关授权认证的活动,都将把酿酒厂的域名添加到vlager上。其它修改本地主机名的progpppd的想法是usehostname和name。当你使用“local:varremote”(local不是点分四组表示的名字)在命令行上给出本地IP地址,pppd将使用它作为本地主机名。详细信息请参见pppd(8)的手册页。 <p>8.10.3 PAP秘密文件
PAP秘密文件与CHAP所用的非常相似。头两个字段总是包含一个用户名和一个服务器名;第三个字段含有PAP密码。当远端发送来一个认证请求时,pppd使用服务器字段等于本地主机名、用户字段等于请求中发送过来的用户名的条目。当为对等点认证自己时,pppd从用户字段等于本地用户名、服务器字段等于远程主机名的行中取得密码(secret)。
一个样本PAP秘密文件就象这一样: <p># /etc/ppp/pap-secrets
#
# user server secret addrs
vlager-pap c3po cresspahl vlager.vbrew.com
c3po vlager DonaldGNUth c3po.lucas.com <p>第一行用于和c3po对话时认证我们自己。第二行说明一个名为c3po的用户必须为我们认证它自己。
第一列的名字vlager-pap是我们发送给c3po的用户名。缺省地,pppd将用本地主机名作为用户名,但是你也可以通过给出user选项后跟一个名字来指定一个不同的名字。
当为了与对等点进行认证而从pap-secrets文件中选取一个条目时,pppd必须知道远端主机的名字。由于它没法找出该名字,你必须在命令行上使用remotename关键字后跟对等点的主机名来指定它。例如,要使用上面的条目与c3po认证,我们必须在pppd的命令行上加入下面的选项: <p> #{} pppd … remotename c3po user vlager-pap <p>在第四个字段(以及所有后面的字段),你可以指定特定的主机所允许的IP地址,正如CHAP秘密文件中的一样。这样,对等点就可以从那个列表中只请求地址。在样本文件中,我们要求c3po使用它的真实IP地址。
注意,PAP是一个非常弱的认证方法,所以建议尽可能使用CHAP。因此我们在这里对PAP就不再详述了;如果你对PAP的使用感兴趣的话,你可以在pppd(8)的手册页中找到许多有关PAP的特性。 <p>8.11 配置一个PPP服务器
以服务器方式运行pppd只需在命令行上加上一些适当的选项。原则上讲,你要创建一个特殊的帐号,比如说是ppp,并给它一个脚本或程序作为用这些选项调用pppd的登录shell。例如,你要在/etc/passwd中加入下面一行: <p>ppp:*:500:200ublic PPP Account:/tmp:/etc/ppp/ppplogin <p>当然,你可以使用与上面所示不同的uids和gids。你还必须使用passwd命令为上面的帐号设置口令。
然后,ppplogin脚本可以象这样: <p>#!/bin/sh
# ppplogin - script to fire up pppd on login
mesg n
stty -echo
exec pppd -detach silent modem crtscts <p>mesg命令用于禁止其他用户往tty写信息,比如使用write命令。stty命令关闭字符回显功能。这是必须的,否则的话对等点发送来的任何信息都将回显回去。上面给出的最重要的pppd选项是-detach,因为它防止pppd脱离控制tty。如果我们不指定这个选项,它就会进入后台,使得shell脚本退出。随之而来的是串行线路将被挂断,连接中止。silent选项使得pppd在开始发送前进行等待直到它从呼叫系统接收到一个数据包。这可以防止当呼叫系统很缓慢地启动它的PPP客户时传输的超时。modem选项用于使得pppd监视DTR引线用以观察对等点是否已掉线,而crtscts选项用以打开硬件握手信号。
除了这些选项以外,你还可以迫使使用某些授权认证,例如通过在pppd的命令行上或在全局选项文件中指定auth。有关开启和禁用各种认证协议的更多选项的描述,可参见在线手册。 <p><p>注释
[1] 相关的RFCs列在本书后面的指定参考书目中。
[2] 实际上,HDLC是一个由国际标准化组织(ISO)设计的非常通用协议。
[3] 两位作者都已经说过今后会比较忙。如果你有任何有关PPP的一般问题,你最好询问Linux积极分子mailing list的NET通道上的人。
[4] karl@morningstar.com 。
[5] 缺省的网络路由只是在还没有时才被建立。
[6] 如果你编辑syslog.conf将这些登录信息重定向到一个文件中,请确信这个文件是不可读的,因为chat缺省地记录下整个会话脚本—包括口令和所有其它的信息。
[7] 对于CHAP权限认证方法在该选项中使用主机名表示是有其因果关系的。请参见下面的CHAP一节。
[8] 通过将选项ipcp-accept-local和ipcp-accept-remote给予pppd,你可以允许远端点覆盖你对使用IP地址的设想。详细信息请参阅手册。
[9] 双引号不是口令的一部分,它们只是用来标明口令中的空格而已。
[10] 这个主机名是从CHAP质询中得到的。 <p>
 楼主| 发表于 2002-4-24 11:13:45 | 显示全部楼层

*#!&*Linux网络管理员手册[共16章节][转帖]

&nbsp; &nbsp;
Linux网络管理员手册(9)
<p>第九章 各种网络应用程序 <p>
在成功地设置好IP和解析器以后,我们现在转过来讨论你想在网络上提供的服务。这一章讲解了一些简单网络应用程序的配置,包括inetd服务器、以及rlogin族中的程序。象网络文件系统(NFS)以及网络信息系统(NIS)所基于的远程过程调用接口也将概要地给予讨论。然而,NFS和NIS的配置内容太多,将用独立的章节进行描述。电子邮件和网络新闻(netnews)也将用独立的章节给予讨论。
当然,我们不可能在本书中讨论所有的网络应用程序。如果你要安装一个这里没有讨论过的程序,比如说,talk、gopher或Xmosaic,请参考它们的手册以获得详细信息。 <p>9.1 inetd超级服务器(super-server)
通常,服务是由所谓的后台程序{或称端口监控程序}daemons执行的。一个端口监控程序是一个程序,它打开一个端口,并且等待进入的连接。如果来了一个连接,它就创建一个子进程来接纳这个连接,而父进程继续监听更多的请求。这个概念有个缺点,即对于所提供的每个服务,就必须运行一个监听某个端口上连接发生的端口监控程序,这通常意味着象交换空间那样的系统资源的浪费。
因而,几乎所有的UN*X安装程序运行一个“超级服务器”,它为许多服务创建套接字,并且使用select(2)系统调用同时监听所有这些端口。当远程系统请求一个服务时,超级服务器注意到这点并且会产生该端口的服务器程序。
常用的超级服务器是inetd,即Internet Daemon(Internet端口监听程序)。它是在系统引导时启动的,并且从名为/etc/inetd.conf的启动文件中取得它所要管理的服务的列表。除了上面所述的那些调用的服务器程序以外,还有许多由inetd自己处理的一般服务,称作内部服务(internal services)。这些包括简单地产生字符串的chargen、返回系统日期时间的daytime。
该文件中的一行是由以下几个字段组成的: <p>service type protocol wait user server cmdline <p>每个字段的含义如下:
service
给出服务的名称。通过查找/etc/services文件,服务名称可以转换成一个端口号。这个文件将在services和protocols文件一节(10.3节)中给予描述。
type
指定一个套接字类型,或者是stream(对于基于连接的协议)(for connection-oriented protocols)或者是dgram(对于基于数据报的协议)(for datagram protocols)。因此对于基于TCP的服务总是使用stream,而基于UDP的服务总是使用dgram。
protocol
命名服务所使用的传输协议。这必须是protocols文件中能找到的有效协议名称,也将在下面给出解释。
wait
该选项只用于dgram套接字。它可以是wait或nowait。如果指定了wait,那么对于指定的端口inetd任何时候只执行一次服务器程序。否则的话,在执行了指定的服务器以后,它将立刻在这个端口上进行监听。
这对于读取所有进入的数据报,然后退出的“单线程”服务器程序来讲是很有用的。许多RPC服务器程序是这种类型的,因而对它们需指定为wait。对于相反的类型,“多线程”服务器程序允许无限数量的例程并发运行;这是很少用到的。这种服务器程序需指定为nowait。stream套接字应该总是使用nowait。
user
这是用户的登录id,用户的进程就在其下运行。这通常是root用户,但某些服务可以使用不同的帐号。这里使用最小特权原则是个很好的主意,这是指你不应该在一个享有特权的帐号下运行一个命令,如果该程序不需要特权也能正常工作的话。例如,NNTP新闻服务器程序将作为news运行,而可能引起安全危险问题的服务(比如tftp或finger)经常作为nobody运行。
server
给出将被执行的服务器程序的全路径。内部服务用关键字internal标记。
cmdline
这是传给服务器程序的命令行(参数)。这包括参数0 –命令名。通常,这是是服务器程序名,除非当使用一个不同的名字调用时,该程序有不同的行为。对于内部服务该字段是空的。
#
# inetd services
ftp stream tcp nowait root /usr/sbin/ftpd in.ftpd -l
telnet stream tcp nowait root /usr/sbin/telnetd in.telnetd -b/etc/issue
#finger stream tcp nowait bin /usr/sbin/fingerd in.fingerd
#tftp dgram udp wait nobody /usr/sbin/tftpd in.tftpd
#tftp dgram udp wait nobody /usr/sbin/tftpd in.tftpd /boot/diskless
login stream tcp nowait root /usr/sbin/rlogind in.rlogind
shell stream tcp nowait root /usr/sbin/rshd in.rshd
exec stream tcp nowait root /usr/sbin/rexecd in.rexecd
#
# inetd internal services
#
daytime stream tcp nowait root internal
daytime dgram udp nowait root internal
time stream tcp nowait root internal
time dgram udp nowait root internal
echo stream tcp nowait root internal
echo dgram udp nowait root internal
discard stream tcp nowait root internal
discard dgram udp nowait root internal
chargen stream tcp nowait root internal
chargen dgram udp nowait root internal <p>图9.1 一个/etc/inetd.conf样本文件。
图9.1给出了inetd.conf的一个样本文件。finger服务被注释掉了,所以这个服务就不存在了。这样做通常是为了安全方面的原因,因为它可能被入侵者用来获取你系统上的用户名。
tftp同样也被注释掉了。tftp实现原始文件传输协议(Primitive File Transfer Protocol)它允许无须口令检查直接从你的系统上传输任何可读的文件等等。这对于/etc/passwd文件尤其有害,当没有使用影子口令文件时就更没的说了。
TFTP通常用于无盘客户以及X终端从一个引导服务器上下载代码。如果由于这个原因你需要运行tftpd的话,请通过在tftpd的命令行上增加那些目录名来限制它们的范围到客户获取文件的目录中。见例子中的第二个tftp行所示。 <p>9.2 tcpd访问控制工具
由于对网络访问开放一个计算机包含许多安全方面的风险,所以应用程序被设计成能够防卫几种类型的攻击。然而,其中的某些防卫可能有缺陷(最为彻底的例子是RTM Internet 蠕虫),或者并不区分请求能被接受的特定服务的安全主机与请求将被拒绝的不可靠的主机。上面我们已经概要地讨论过了finger和tftp服务。因此,人们想限制这些服务只有“可信的主机”才能访问,而使用通常的设置是不可能做到的,对于这些服务inetd要么提供给所有的客户,要么一个客户都不能使用。
为了达到此目的,一个有用的工具是tcpd,[1] 即所谓的端口监控程序包装器(daemon wrapper)。对于你想监视和保护的TCP服务,将调用这个tcpd而不是服务器程序。tcpd将请求记录到syslog后台程序,检查远程主机是否允许使用那个服务,并且只有检查通过时才会执行真正的服务器程序。注意,这对于基于UDP的服务不起作用。
例如,要包装finger daemon时,你必须改变indetd.conf中的相应行成为 <p># wrap finger daemon
finger stream tcp nowait root /usr/sbin/tcpd in.fingerd <p>不增加任何访问控制,这将如通常的finger设置一样展现在客户面前,除了任何请求将被记录到syslog的auth设施中。
访问控制是通过两个文件/etc/hosts.allow和/etc/hosts.deny来实现的。它们分别含有对特定服务和主机允许和禁止访问的条目。当tcpd处理来自名为biff.foobar.com的客户主机的服务请求时,比如说是finger服务请求,它将hosts.allow和hosts.deny(以这个次序)文件中扫描匹配这个服务和主机的条目。如果在hosts.allow中找到了匹配条目,就准予访问,而不管hosts.deny中的任何条目了。如果在hosts.deny中发现了匹配的条目,该请求将通过关闭这个连接而被拒绝。如果都没有找到匹配的条目,也准予访问。
在访问文件中的条目看上去象这样: <p>servicelist: hostlist [:shellcmd] <p>servicelist是来自于/etc/services中的服务名称的一个列表,或者是关键字ALL。要匹配除了finger和tftp的所有服务时,使用“ALL EXCEPT finger, tftp”。
hostlist是一个主机名或IP地址的列表,或者是关键字ALL、LOCAL或UNKNOWN。ALL匹配任何主机,而LOCAL匹配不含有点的主机名。[2] UNKNOWN匹配于任何名字或地址查询失败的主机。一个以点开头的名字与域名等于这个名字的主机匹配。例如,.foobar.com与biff.foobar.com相匹配。也有对IP网络地址和子网号的规定。详细信息请参见hosts_access(5)手册页。
除了本地主机以外,要限制所有主机对finger和tftp服务的访问,就将下面一行加入到/etc/hosts.deny文件中,并且/etc/hosts.allow文件为空: <p>in.tftpd, in.fingerd: ALL EXCEPT LOCAL, .your.domain <p>可选的shellcmd字段可以含有一个shell命令,当条目匹配时将被调用。这对于设置可以使潜在的入侵者暴露的陷阱是很有用的: <p>in.ftpd: ALL EXCEPT LOCAL, .vbrew.com :   
echo &quot;request from %d@%h&quot; &gt;&gt; /var/log/finger.log&#59;   
if [ %h != &quot;vlager.vbrew.com&quot; ]&#59; then   
finger -l @%h &gt;&gt; /var/log/finger.log   
fi <p>%h和%d参数被tcpd分别展开成客户的主机名和服务名称。详细信息请参见hosts_access(5)手册页。 <p>9.3 services和protocols文件
确定的“标准”的服务端口号是在“Assigned Numbers”RFC中定义的。为了使得服务器和客户程序能够将服务名称转换成这些号码(数值),每个主机起码要保存这个表的一部分;它被存于文件/etc/service中。每个条目是由象下面这行一样组成的: <p>service port/protocol [aliases] <p>这里,service指定服务的名称、port定义提供该服务的端口、protocol定义使用何种传输协议。通常protocol是udp或tcp两者之一。为多种协议提供一个服务是可能的,同样,只要协议不同,在相同的端口上提供不同的服务也是可能的。Aliases字段用于为相同的服务指定另一个可选用的名称。
通常,你无须更改你的Linux系统上的随同网络软件而来的services文件。不过,我们下面文件中给出一个小例外。 <p># The services file:
#
# well-known services
echo 7/tcp # Echo
echo 7/udp #
discard 9/tcp sink null # Discard
discard 9/udp sink null #
daytime 13/tcp # Daytime
daytime 13/udp #
chargen 19/tcp ttytst source # Character Generator
chargen 19/udp ttytst source #
ftp-data 20/tcp # File Transfer Protocol (Data)
ftp 21/tcp # File Transfer Protocol (Contr
telnet 23/tcp # Virtual Terminal Protocol
smtp 25/tcp # Simple Mail Transfer Protocol
nntp 119/tcp readnews # Network News Transfer Protoco
#
# UNIX services
exec 512/tcp # BSD rexecd
biff 512/udp comsat # mail notification
login 513/tcp # remote login
who 513/udp whod # remote who and uptime
shell 514/tcp cmd # remote command, no passwd use
syslog 514/udp # remote system logging
printer 515/tcp spooler # remote print spooling
route 520/udp router routed # routing information protocol <p>注意,例如,对于TCP和UDP,都在端口7上提供了echo服务,并且端口512被用于两个不同的服务,即在UDP上是COMSAT daemon(它用于提醒用户有新邮件到达,见xbiff(1x)),在TCP上是用于远程执行(rexec(1))。
与services文件相类似,网络库文件需要有一个方法来将协议名—例如,那些用于services文件中的—转换成为能够被别的主机的IP层理解的协议号。这是通过在/etc/protocols文件中查找协议名来做到的。这个文件每行包含一个条目,每个条目包括一个协议名和一个相关的号码。与/etc/services文件相比,就更不用对这个文件作任何改动了。下面给出一个样本文件: <p>#
# Internet (IP) protocols
#
ip 0 IP # internet protocol, pseudo protocol number
icmp 1 ICMP # internet control message protocol
igmp 2 IGMP # internet group multicast protocol
tcp 6 TCP # transmission control protocol
udp 17 UDP # user datagram protocol
raw 255 RAW # RAW IP interface <p>9.4 远程过程调用
客户-服务器应用程序的一个非常普通的机制是有RPC提供的,远程过程调用(Remote Procedure Call)软件包。RPC是由Sun Microsystems开发出来的,是工具和库函数的一个汇集。建立在RFC上的重要应用程序是NFS—网络文件系统、以及NIS—网络信息系统,这两者将在后面的章节中给予介绍。
一个RPC服务器是由一个过程的集合组成,客户可以通过向服务器发出一个带有过程参数的RPC请求来调用这些过程。服务器将代表客户调用指定的过程,如果有任何返回值时就返回它。为了与机器无关,所有在客户和服务器之间交换的数据都被发送者转换成所谓的外部数据表示格式(External Data Representation format)(XDR),并有接收者在转回机器本地表示方式。
有时候,对一个RPC应用程序的改进会给过程调用的接口带来不兼容性的改变。当然,只是简单地改变服务器将导致所有期望原先行为的应用程序不能使用。因此,RPC程序有相应的版本号,通常是从1开始的,并且随着每一个新版本的RPC接口这个计数值将增加。经常,一个服务器可能同时提供几个版本;因此客户通过在他们请求中的版本号来指定他们想使用服务的哪个实现。
在RPC服务器和客户之间的网络通信有些奇特。一个RPC服务器提供一个或多哥过程的集合;每个集合被称作一个程序(program),并且唯一地由一个程序号(program number)指定。映射服务名到程序号的一个列表通常存于/etc/rpc中。它的一个摘要在下面图9.2中给出。 <p>#
# /etc/rpc – miscellaenous RPC-based services
#
portmapper 100000 portmap sunrpc
rstatd 100001 rstat rstat_svc rup perfmeter
rusersd 100002 rusers
nfs 100003 nfsprog
ypserv 100004 ypprog
mountd 100005 mount showmount
ypbind 100007
walld 100008 rwall shutdown
yppasswdd 100009 yppasswd
bootparam 100026
ypupdated 100028 ypupdate <p>图9.2 一个/etc/rpc样本文件 <p>在TCP/IP网络中,RPC的作者所面临的问题是将程序号映射到普通的网络服务上。他们为每个程序的每个版本选择同时提供TCP和UDP端口服务。一般来讲,RPC应用程序将使用UDP来发送数据,并且仅当数据不能放入单个UDP数据报时才转回来使用TCP传输数据。
当然,客户程序必须有一个方法来找出哪个程序号映射到哪个端口上。如果使用一个配置文件来做这事将显得太不灵活了;因为RPC应用程序不使用保留的端口,无法保证一个原先被我们的数据库应用程序使用的端口没有被某个其它进程占用。因此,RPC应用程序抓取它能得到的任何端口,并且用所谓的portmapper daemon进行登记注册。后者为所有运行在它的机器上的RPC服务器充当代理的角色:一个希望用给出的程序号联系一个服务的客户将首先询问服务器主机上的portmapper,portmapper将返回能够到达这个服务的TCP和UDP端口号。
这个方法有一特别的缺点,它会带来一个失败点,正象在标准Berkeley服务中inetd端口监控程序一样。然而,这个情况甚至有些更糟,因为当portmapper死去时,所有的RPC端口信息都将丢失;这通常意味着你必须手工重新启动所有的RPC服务器程序,或者干脆重新启动整个机器。
在Linux中,portmapper被称作rpc.portmap并且在/usr/sbin中。它是从rc.inet2中启动的,其它可以确定的是portmapper不用做任何配置工作。 <p>9.5 配置r命令
有许多命令用于在远程主机上执行命令。这些是rlogin、rsh、rcp以及rcmd。它们都在远程主机上产生一个shell并允许用户执行命令。当然,客户需要在执行命令的主机上有一个帐号。因此所有这些命令都要执行授权认证过程。通常,客户将告知服务器用户的登录名,服务器随之会请求一个使用常用方法鉴定的口令。
然而,有时候希望放宽对特定用户的认证检查。比如,如果你必须频繁地登录进你的LAN上的其它机器上,你可能希望不要每次都键入密码而被接纳。
禁用授权认证仅在有很少一些口令数据库是同步的主机的情况下、或是对于很少部分特权用户他们由于管理方面的原因需要访问许多主机的情况下才是可取的。每当你想要允许人们不用指定登录id或口令就能登录进你的主机时,确信你没有意外地授权准许别人访问你的机器。
对于r命令有两种方法来禁用认证检查。一个方法是超级用户允许特定的或所有的用户在特定的或所有的主机上(后者肯定是个坏点子)登录而无须键入口令。这种访问是由/etc/hosts.equiv文件控制的。它含有等同于在本地主机上的用户的一张主机和用户名列表。另一个方法是一个用户在特定的主机上准许其他用户访问她的帐号。这些可以在用户的主目录中列于.rhosts文件里。考虑到安全方面的原因,这个文件必须由该用户或超级用户掌管,并且不能是一个符号连接,否则的话它将被忽略掉。[3]
当一个客户请求一个r服务时,就会在/etc/hosts.equiv文件中搜寻她的主机和用户名,然后会在她想作为其登录的用户的.rhosts中搜寻。作为一个例子,假设janet是在gauss上工作并且试图在euler上登录进joe的帐号中。在下面,我们将Janet看作为一个客户用户,而将Joe看作是一个本地用户。现在,当Janet在gauss上键入下面一行时 <p>$ rlogin –l joe euler <p>服务器将首先检查hosts.equiv如果Janet被准许自由访问,并且如果这个检查失败了,就会在joe主目录的.rhosts文件中查找她。
euler上的hosts.equiv文件看上去象这样: <p>gauss
euler
-public
quark.physics.groucho.edu andres <p>每一个条目由一个主机名和一个可选的用户名组成。如果一个条目上只有一个主机名,那么那个主机上的所有用户使用他们的本地帐号都将被接受而无须作任何检查。在上面的例子中,当从gauss过来时,Janet将被允许登录到她的帐号janet中,对于任何其他用户也是这样的,除了root用户。然而,如果Janet想以joe登录时,她将象平常一样得到一个输入口令的提示信息。
如果一个主机名后跟一个用户名的话,就如上面例子文件中的最后一行,那么除了root帐号以外,这个用户将可以无口令地访问其他所有的帐号。
主机名前也可以有一个减号,就象条目“-public”。这表明对于public上的所有帐号都需要授权认证,而不管个别用户在它们的.rhosts文件中被准许访问。
.rhosts文件的格式与hosts.equiv的格式是一样的,但是意思稍微有些不同。考虑euler上Joe的.rhosts文件: <p>chomp.cs.groucho.edu
gauss janet <p>第一个条目准许joe在从chomp.cs.groucho.edu登录进来时能自由地访问,但并不影响(侵犯)euler或chomp上的任何其它帐号。第二个条目稍微有些不同,它同意janet在从gauss登录进来时可以自由访问Joe的帐号。
注意,客户的主机名是通过逆向映射呼叫者的地址到名字而获得的,所以这个特性对于解析器未知的主机来说是没有用的。在以下几种情况下,客户的主机名被认为是与hosts文件中的名字匹配的:
&#61548&#59; 客户的规范主机名(不是一个别名)与文件中的主机名相匹配。
&#61548&#59; 如果客户主机名是一个全资域名(比如当你正运行着DNS时解析器的返回值),并且与hosts文件中的主机名不是逐字符匹配的,那么就与用本地域名扩展的主机名相比较。 <p><p><p>注释
[1] 由Wietse Venema编制,wietse@wzv.win.tue.nl。
[2] 通常只有从/etc/hosts中查到的本地主机名不含有点。
[3] 在一个NFS环境当中,你可能需要给它一个444的属性保护,因为超级用户对通过NFS加载的磁盘上文件的访问经常是非常严格的。
[4] 注意,当某人试图以root登录时,hosts.equiv文件是不会被搜寻的。
 楼主| 发表于 2002-4-24 11:14:38 | 显示全部楼层

*#!&*Linux网络管理员手册[共16章节][转帖]

&nbsp; &nbsp;
Linux网络管理员手册(10)

第十章 网络信息系统 <p>
当你运行着一个局域网时,你的整个目标通常时为你的用户提供一个清晰透明的网络环境。做到这一步的一个重要步骤是在所有主机之间保持重要数据(比如用户帐号信息)的同步。我们在前面已经看到,对于主机名的解析,存在一个强大而复杂的服务,即DNS。对于其他任务没有这种特殊的服务。此外,如果你只是管理一个没有Internet连接的小LAN的话,那么对于许多管理员来说安装设置DNS是不值得的。
这就是为什么Sun开发出了NIS,即网络信息系统(Network Information System)。NIS提供了通用数据库访问设施,它可用来想你的网络上的所有主机分发信息,比如象passwd和groups文件所包含的信息。这使得网络看起来象一个独立系统,在所有的主机上有着相同的帐号。以同样的方式,你可以用NIS向网络上的所有机器分发来自/etc/hosts中的主机名信息。
NIS是基于RPC的,是由一个服务器、一个客户端库以及几个管理工具组成。起初,NIS被称作黄页(Yellow Pages),或YP,现在仍然使用这个名称来非正式地指这项服务。另一方面,Yellow Pages是英国电信的商标,英国电信一直要求Sun更换这个名字。随着事态的发展,某些名称已与人们分不开了,所以YP一直以与NIS相关命令的前缀形式继续存在着,比如象ypserv、ypbind等等。
今天,几乎所有的UN*X都包括NIS,而且甚至有它的免费实现版本。一个是来自BSD的Net-2发行版,源自于Sun捐赠的公众域参考实现。该版的客户库代码已经存在于GNU的libc中很长时间了,而管理程序只是在最近才由Swen Thümmler [1] 移植到Linux上。在这个参考实现中漏掉了一个NIS服务器程序。Tobias Reber已经编制出了另外一个NIS软件包,其中包括所有的工具和一个服务器;该软件包称作yps。[2]
目前,一个完全重写的称为NYS的NIS代码已由Peter Eriksson [3]编制出来,它支持普通的NIS和Sun的经过许多修正的NIS+。NYS不仅提供了一个NIS工具集和一个服务器,而且还增加了一个全新的库函数集,这个库函数集可能最终会被加入到标准libc中。这包括替换目前使用host.conf的主机名解析的一个新设置方案。这些函数的特性将在下面讨论。
这一章将集中讨论NYS而非另外两个软件包,对于这两个软件包我将称它们为“传统的”NIS代码。如果你确实要想运行任何这些软件包的话,本章中的说明也许已经足够也许还不够。要获取另外的信息,请取得一本有关NIS的标准(权威)书本,比如象Hal Stern的NFS和NIS(见[Stern92])。
目前,NYS仍处于开发阶段,因此标准的Linux工具如网络程序或login程序还没有注意到NYS的配置方案。只有到NYS合并进主流libc中时,如果你想使得所有这些执行程序使用NYS时,你才需要重新编译它们。在任何这些应用程序的Makefiles中,在libc之前,指定-lnsl作为linker的最后一个选项。这将有关函数从libnsl—NYS库中连接过来,取代从标准C库的连接。 <p>10.1 理解NIS
NIS在所谓的包含键-值对的maps中保存数据库信息。Maps被存储于运行NIS服务器的中央主机中,从该主机中,客户可以通过各种RPC调用检索信息。最频繁地,maps是存于DBM文件中的。[4]
Maps本身是从主要文本文件(比如/etc/hosts或/etc/passwd)中生成的。对于某些文件,会生成几个maps,每个搜寻键类型对应一个。例如,你可以为主机名和IP地址搜查hosts文件。相应地,从中会生成两个NIS maps,分别称为hosts.byname和hosts.byaddr。表10.1列出了通用maps和它们生成的文件。 <p>Master File Map(s)
/etc/hosts
/etc/networks
/etc/passwd
/etc/group
/etc/services
/etc/rpc
/etc/protocols
/usr/lib/aliases Hosts.byname hosts.byaddr
Networks.byname networks.byaddr
Passwd.byname passwd.byuid
Group.byname group.bygid
Services.byname services.bynumber
Rpc.byname rpc.bynumber
Protocols.byname protocols.bynumber
Mail.aliases <p>表10.1 一些标准的NIS maps以及相应的文件。 <p>在某些NIS软件包或其它软件中,还有一些你可能会觉得有用的别的文件和maps。这些文件和maps可能含有没在这本书中讨论过的应用程序的信息,比如可能用于某些BOOTP服务器中的bootparams maps,或者在Linux中目前不含有任何函数的文件(就象ethers.byname和ethers.byaddr maps)。
对于某些maps,人们通常使用绰号(nicknames),它们很短因而易于键入。要想获得一个你的NIS工具能够理解的绰号的完整列表,运行下面的命令: <p>$ ypcat –x
NIS map nickname translation table:
“passwd” -&gt; “passwd.byname”
“group” -&gt; “group.byname”
“networks” -&gt; “networks.byaddr”
“hosts” -&gt; “hosts.byname”
“protocols” -&gt; “protocols.bynumber”
“services” -&gt; “services.byname”
“aliases” -&gt; “mail.aliases”
“ethers” -&gt; “ethers.byname”
“rpc” -&gt; “rpc.bynumber”
“netmasks” -&gt; “netmasks.byaddr”
“publickey” -&gt; “publickey.byname”
“netid” -&gt; “netid.byname”
“passwd.adjunct” -&gt; “passwd.adjunct.byname”
“group.adjunct” -&gt; “group.adjunct.byname”
“timezone” -&gt; “timezone.byname” <p>NIS服务器传统地称为ypserv。对于一个中等大小的网络来说,单个服务器通常就足够了;大型的网络可能需要在不同的网段以及不同的机器上运行几个服务器,以减轻服务器机器和路由器的负荷。通过将这些服务器之一作为主服务器(master server),其它的服务器作为次服务器(slave servers),使得这些服务器同步。Maps将只在主服务器上建立。从主服务器上将它们分发到所有次服务器上。
你可能已经注意到,我们一直很含糊地论及“网络”;当然引用这样一个网络的NIS存在着与众不同的概念,也即通过NIS共享它们部分系统配置数据的所有主机的一个集合:NIS域。不幸的是,NIS域与我们在DNS中遇到的域绝对没有一点共同之处。为了在本章中避免含糊不清的情况,我将总是指出我说的哪一类型的域。
NIS域只具有纯粹的管理功能。对于用户来说它们主要是不可见的,除了在域中所有机器之间口令的共享。因此,给NIS域取的名字仅与管理员有关。通常,可以使用任何名字,只要该名字与你的本地网络上的其它NIS域名不同就行。例如,虚拟酿酒厂的管理员可以选择建立两个NIS域,一个是给酿酒厂本身用的,另一个是个葡萄酒厂的,她分别将其命名为brewery和winery。另一个很普遍的方案是简单地用DNS域名也作为NIS的域名。为了设置和显示你的主机的NIS域名,你可以使用dommainname命令。当不加任何参数调用时,它打印出当前NIS域名;如要设置这个域名的话,你必须成为超级用户并键入: <p># domainname brewery <p>NIS域决定了一个应用程序将查询哪个NIS服务器。例如,在葡萄酒厂(Winery)的主机上的login程序(当然)将只向葡萄酒厂的NIS服务器(或者是它们其中之一,如果存在多个服务器的话)查询用户的口令信息;而酿酒厂主机上的应用程序将只查询酿酒厂的服务器。
现在还有一个疑点要解决,也即一个客户如何知道要连接到哪一台服务器上去。最简单的途径是有一个配置文件,它给出了要在其上查找服务器的主机名。然而,这个办法非常不灵活,因为它不允许客户依据这些服务器存在与否使用不同的服务器(当然是指从同一个域)。因此,传统的NIS实现依赖于一个称作ypbind的特殊后台程序在它们的NIS域中来侦测一个适当的NIS服务器。在能够执行任何NIS查询之前,任何应用程序首先要从ypbind找出要使用哪个服务器。
ypbind通过向本地IP网络广播来探测服务器;第一个响应的服务器假设基本上是最快的一个并将用于随后的NIS查询。在某个间隔时间过去以后,或者如果服务器不工作了,ypbind将再次探测运行着的服务器。
现在,关于动态绑定的争论点是你很少需要它,并且它会带来安全方面的问题:ypbind盲目地相信任何应答者,而这个应答者可能会是一个谦逊的NIS服务器也可能是一个怀有恶意的入侵者。不用说如果你在NIS上管理你的口令数据库的话,这将变成特别麻烦的事。为了防范这个问题,NYS缺省地不使用ypbind,而是从一个配置文件中取得服务器的主机名。 <p>10.2 NIS与NIS+
NIS和NIS+除了在名字上和有共同的目标以外,很少有相同之处。NIS+是用一个完全不同的方法构成的。它使用一个类似于DNS的分级名字空间,而不是一个平面的名字空间和松散脱节的NIS域。它使用一个由行和列组成的所谓的表(tables)而不是maps,在NIS+数据库中表的每一行表示一个对象,而列表示NIS+所知所关心的对象的那些属性。一个给定的NIS+域的每个表由那些它们的父域组成。另外,表中的一个条目可以包含到另一个表的链接。这些特性使得用许多方法构造信息成为可能。
传统的NIS的RPC版本号是2,而NIS+的是版本3。
NIS+至今似乎还没有被广泛地使用,而且我实际上对它也知道不多。(唔,几乎一窍不通)。由于这个原因,这里我们将不涉及它了。如果你对它感兴趣并想多学一点的话,请参阅Sun的NIS+管理手册([NISPlus])。 <p>10.3 客户边的NIS
如果你熟悉编制或移植网络应用程序的话,你将会注意到上面所列出的许多NIS maps与C库中的库函数相对应。例如,要获得passwd信息,你通常使用getpwnam(3)和getpwuid(3)函数,它们分别返回与给定的用户名或数值用户id相对应的帐号信息。在通常的环境下,这些函数将在标准文件(比如/etc/passwd)中执行请求的查找。
然而,这些函数的基于NIS(NIS-aware)的实现将更改这种行为,并且会启用一个RPC调用让NIS服务器查询用户名或id。对于应用程序来说这个操作是完全透明的。这个函数可以将NIS map“附加”或“替换”掉原始的文件。当然,这并没有对文件进行实际的修改,它只是让应用程序看上去好象该文件已经被替换或附加上去了。
对于传统的NIS实现来讲,对于那些maps替换掉以及那些被添加到原始信息中,曾有某些惯例。有些maps(比如passwd maps)需要对passwd文件进行杂凑地修改,当做错时,就会打开安全方面的缺口。为了避免这个缺陷,NYS常规的配置方案,该方案确定了一个特定的客户函数集是否使用原始文件、NIS、NIS+,并且以什么次序使用。这将在本章后续小节中加以讨论。 <p>10.4 运行一个NIS服务器
在这么多理论方面的喋喋不休之后,现在开始动手做实际的配置工作。在本节中,我们将讨论NIS服务器的配置。如果在你的网络上已经有一个NIS服务器在运行,你就不必设置你自己的服务器了;在这种情况下,你可以安全地跳过本节。
注意,如果你只是准备对服务器做试验,请确信你没有设置一个已经在你网络上使用的NIS域名。因为这会使整个网络服务瘫痪并使得许多人不高兴和恼怒。
对于Linux目前有两个现存的免费NIS服务器,一个包含在Tobias Reber的yps软件包中,另一个在Peter Eriksson的ypserv软件包中。至于你运行哪一个是无关紧要的,也不管你使用NYS还是目前在libc中的标准NIS客户代码。在写作本书时,yps中的NIS次服务器处理的代码似乎更完善一些。所以如果你要涉及到次要服务器的话,yps可能是一个更好的选择。
当在/usr/sbin中安装好服务器程序(ypserv)以后,你应该建立一个目录,用于存放你的服务器分发的map文件。当为brewery域设置好一个NIS域时,maps将存于/var/yp/brewery中。服务器通过检测是否存在一个map目录来确定它是否在为一个特定的NIS域服务。如果你对某些NIS域禁用了服务,请确信同时也删除那个目录。
Maps通常储存于DBM文件中以加速查询。它们是用一个称为makedbm(对于Tobias的服务器)或dbmload(对于Peter的服务器)的程序从主文件中创建的。它们是不可互换的。将主文件转换成dbmload可分析的形式通常需要一些awk或sed技巧,这对于录入有些乏味并且难于记忆。因此,Perter Eriksson的ypserv软件包含有一个Makefile(称为ypMakefile),它将为你做所有这些工作。你应该将它作为Makefile安装在你的map目录中,并且编辑它,以反映你要分发的maps。在文件的头部,你会发现all目标,它列出了ypserv将要提供的服务。缺省地,该行看上去象这样: <p>all: ethers hosts networks protocols rpc services passwd group netid <p>例如,如果你不想生成ethers.byname和ethers.byaddr maps,只须简单地从这条规则中去掉ethers先决条件。为了测试你的设置,开始只使用一二个maps,比如services.* maps,就已经足够了。
在map的目录里,在编辑好Makefile以后,键入“make”。这将自动地生成并安装maps。你必须确信每当你改变了主文件之后,一定要更新maps,否则所做的改变对网络仍然是不可见的。
下一节解释如何配置NIS客户代码。如果你的安装设置不工作的话,你应该查出有没有任何请求到达你的服务器。如果你对NYS服务器指定-D命令行标志,它将在控制台上打印出有关所有进入的NIS查询的调试信息,并且返回结果。这些将给你一个提示来确定问题到底出在哪里。Tobias的服务器没有这个选项。 <p>10.5 使用NYS设置一个NIS客户
在本章的余下部分,我们将讨论NIS客户的配置。
你的第一步应该是告知NYS对于NIS服务使用哪个服务器,并在/etc/yp.conf配置文件中设置好。对于在葡萄酒厂(Winery)网络上一台主机上的简单样本文件看上去象这样: <p># yp.conf – YP configuration for NYS library.
#
domainname winery
server vbardolino <p>第一条语句告诉所有NIS客户,他们属于winery NIS域。如果你省略这一行,NYS将使用你通过domainname命令指派给你系统的域名。server语句指定所使用的NIS服务器。当然,与vbardolino相应的IP地址必须在hosts文件中设置;另外,你也可以在server语句中使用IP地址本身。
在上面所示的表单中,server命令告诉NYS使用指定的服务器而不管目前的NIS域是什么。然而,如果你频繁地在不同的NIS域中移动你的机器的话,你可能想要在yp.conf文件中保存几个域的信息。你可以通过在server语句中增加NIS域名获得几个NIS域的服务器的信息。例如,你可以为一个便携机改变上面样本文件成这样: <p># yp.conf – YP configuration for NYS library
#
server vbardolino winery
server vstout brewery <p>这允许你在系统引导时通过domainname命令设置期望的NIS域来在两个域的任何一个域中使用便携机。
在创建了这个基本的配置文件并确信它是可读的以后,你应该运行的第一次测试来检查你是否能连接到你的服务器上。确信选择你的服务器分发的任何map,如hosts.byname,并试着使用ypcat工具来检索它。ypcat,就象所有其它的NIS管理工具一样,应该存在于/usr/sbin中。 <p># ypcat hosts.byname
191.72.2.2 vbeaujolais vbeaujolais.linus.lxnet.org
191.72.2.3 vbardolino vbardolino.linus.lxnet.org
191.72.1.1 vlager vlager.linus.lxnet.org
191.72.2.1 vlager vlager.linus.lxnet.org
191.72.1.2 vstout vstout.linus.lxnet.org
191.72.1.3 vale vale.linus.lxnet.org
191.72.2.4 vchianti vchianti.linus.lxnet.org <p>你所得到的输出应该与上面显示的相象。如果你得到了一条错误信息指出“Can’t bind to server which serves domain”或者某些类似的信息,那么或者是你设置的NIS域名在yp.conf中没有匹配的服务器,或者是由于某些原因服务器找不到。在后一种情况下,请确信ping到那个主机产生正确的结果,并且它确实正在运行一个NIS服务器。你可以使用rpcinfo来验证后者,它将生成以下输出: <p># rpcinfo –u serverhost ypserv
program 100004 version 2 ready and waiting <p>10.6 选择正确的maps
在确信能够与NIS服务器联系之后,你必须决定要用NIS maps替换或添加哪个配置文件。一般地,你将会对主机和口令查找函数使用NIS maps。前者对于没有使用BIND时特别有用。后者允许所有用户在NIS域的任何系统上登录进他们的帐号;这通常要求通过NFS在所有的主机之间共享一个中央/home目录。这将在10.7节中详细讨论。其它的maps,如同services.byname,并没有如此有戏剧性的效能,但能为你省去某些编辑工作如果你安装了任何网络应用程序而该应用程序使用了一个不在标准services文件中的服务名。
通常,对于一个查找函数何时使用本地文件、何时询问NIS服务器,你会想有某些自由的选择。NYS允许你配置函数访问这些服务的顺序。这是通过/etc/nsswitch.conf文件来控制的,该文件名是指名称服务交换(Name Service Switch),当然其并不限制于名称服务。对于NYS支持的任何数据查找函数,它都包含指定所用服务的一行。
服务的正确顺序是与数据的类型有关的。并无必要让services.byname的map一定要含有与本地services文件中不同的条目;它可以包含更多的条目。所以,一个好的选择可以是首先查询本地文件,并且只有当服务名称没有找到时才查找NIS。另一方面,主机名信息可能会非常频繁地改变,所以DNS或NIS服务器应该总是有非常正确的信息,而本地的hosts文件只作为在DNS和NIS不可用时的一个备份而已。在这种情况下,你可能想最后查询本地文件。
下面的例子显示出了如何以上面描述的方式配置gethostbyname(2)、gethostbyaddr(2)和getservbyname(2)函数。它们将依次试用列出的服务;如果一个查找成功,结果就返回,否则试用下一个服务。 <p># small sample /etc/nsswitch.conf
#
hosts: nis dns files
services: files nis <p>可以在nsswitch.conf文件中有一个条目的完整服务的列表如下面所示。实际被查询的maps、文件、服务器和对象依赖于条目名。 <p>nisplus或nis+
对这个域使用NIS+服务器。服务器的位置从/etc/nis.conf文件中获得。 <p>nis 使用这个域的当前NIS服务器。被查询的服务器的位置在yp.conf文件中设置,见前节所示。对于hosts条目,要查询hosts.byname和hosts.byaddr maps。 <p>dns 使用DNS名字服务器。这个服务类型只对hosts条目有用。要被检索的名字服务器仍然由标准resolv.conf文件确定。 <p>files 使用本地文件,比如对于hosts条目使用/etc/hosts文件。 <p>dbm 从位于/var/dbm内的DBM文件中查找信息。文件所使用的名字与NIS map相对应。 <p>目前,NYS支持下面这些nsswitch.conf条目:hosts、networks、passwd、group、shadow、gshadow、services、protocols、rpc和ethers。以后还会增加更多的条目。
图10.1显示了一个更完整的例子,它引入了nsswitch.conf的另一个特性:hosts条目中的[NOTFOUND=return]关键字通知NYS,如果在NIS或DNS数据库中没有找到所要的项就返回。也即,只有在向NIS和DNS服务器的呼叫由于某些其它原因失败时,NYS才将继续搜寻本地文件。因此,本地文件只在启动引导期间使用并且当NIS服务器关闭时起一个备份的作用。 <p># /etc/nsswitch.conf
#
hosts: nis dns [NOTFOUND=return] files
networks: nis [NOTFOUND=return] files <p>services: files nis
protocols: files nis
rpc: files nis <p>图10.1 nsswitch.conf样本文件。 <p>10.7 使用passwd和group Maps
NIS的一个主要应用是在一个NIS域中的所有主机上同步用户以及帐目信息。关于这方面,你通常只保存了一个小的本地/etc/passwd文件,对于这个文件,从NIS maps获得的站点范围的信息被添加了进去。然而,只是简单地在nsswitch.conf中为这个服务启用NIS查找还不很够。
当引用NIS描述的口令信息时,你必须首先确信在你本地passwd文件中任何用户的数值用户id与NIS服务器的用户id匹配。同样对于其它目的你也会需要这样的,比如从你的网络中其它主机上加载NFS卷时。
如果/etc/passwd或/etc/group中的任何数值id与maps中的相偏离,你必须为属于那个用户的所有文件调整文件的所有权。首先你必须将passwd和group中的uid和gid改成一个新值;然后找出属于刚改变的用户的所有文件,最后改变这些文件的所有权。假设news曾有一个id为9,而okir有一个id为103,它们将被改成其它值;那么你可以发出以下的命令: <p># find / -uid 9 –print &gt;/tmp/uid.9
# find / -uid 103 –print &gt;/tmp/uid.103
# cat /tmp/uid.9 | xargs chown news
# cat /tmp/uid.103 | xargs chown okir <p>必须针对新安装的passwd文件执行这些命令,并且在改变任何文件的所有权之前收集所有文件的名字,这点很重要。为了更新文件的组所有权,你将使用一个类似的命令。
在做完这些工作之后,你系统上的数值uid和gid将与你的NIS域中所有其它主机上的相匹配。下一步将是在nsswitch.conf中增加配置行,它为用户和组信息启用NIS查找: <p># /etc/nsswitch.conf – passwd and group treatment
passwd: nis files
group: nis files <p>这使得在一个用户试图登录时,login命令和所有其它类似命令首先查询NIS maps,如果这个查找失败时,再返回使用本地文件。一般来讲,你将从你的本地文件中删除所有的用户,而只留下root和象mail一样的通用帐目。这是因为某些至关重要的系统任务可能需要将uid映射到用户名上或者反之。例如,管理用的cron作业可能会执行su命令来临时变成news,或者UUCP子系统可能要邮寄一个状态报告。如果news和uucp在本地passwd文件中没有条目了,那么在NIS不能使用期间这些作业将糟糕地失败。
这里有两个大告戒:一方面,上面所描述的设置在这里只适应于没有使用影子(shadow)口令的登录状况,象那些包括在util-linux软件包中的。与NIS一起使用影子口令的复杂问题将在下面论及。另一方面,登录命令并不是仅有的访问passwd文件的命令—请看许多人几乎一直使用的ls命令。每当进行一次长列表时,ls将显示一个文件的用户和组的宿主的符号名;也即,对于它遇到的每个uid和gid,它就要查询NIS服务器一次。如果你的本地网络受到阻塞时将严重地拖延进行的工作,或者更糟糕的是,当NIS服务器不在同一个物理网络上时,数据报还必须通过路由器传输。
事情还没结束。想象以下如果一个用户想要更改她的口令时会发生什么情况。通常,她会执行passwd,它将读入新的口令并更新本地passwd文件。对于NIS来说,这是不可能的,因为这个文件已不再存在于本地了,但是每当用户想要改变他们的口令时就让他们登录进NIS也不是个选择。因此,NIS提供了一个对passwd的混入替换称为yppasswd,它用来在目前的NIS中做类似的工作。为了改变服务器主机上的口令,它通过RPC联系那个主机上的yppasswdd后台程序,并向它提供更新过的口令信息。通常,你通过象这样做在常规程序上安装yppasswd: <p># cd /bin
# mv passwd passwd.old
# ln yppasswd passwd <p>与此同时你必须在服务器上安装rpc.yppasswdd并从rc.inet2中启动它。这将对你的用户有效地隐藏NIS所带来的任何扭曲。 <p>10.8 使用支持影子(shadow)的NIS
至今还没有对使用影子登录程序组的站点的NIS支持。John F. Haugh,影子程序组的作者,最近往comp.sources.misc发布了一个受GNU库的GPL保护的影子库函数的一个版本。它对NIS已经有了一些支持,但还不完整,并且这些函数还没有加入到标准C库中。另一方面来讲,通过NIS之类公布来自于/etc/shadow中的信息是与shadow组件的目的相违背的。
尽管NYS口令查找函数不使用shadow.byname map或任何这类map,NYS还是支持透明地使用一个本地/etc/shadow文件的。当getpwnam的NYS实现被调用来查找与给定的登录名相关的信息时,nsswitch.conf中的passwd条目所指定的设施被检索。nis服务将简单地在NIS服务器的passwd.byname map中查找这个名字。而files服务将检查/etc/shadow是否存在,并且如果存在的话,就试着打开它。如果不存在的话,或者如果用户没有root特权的话,它就返回到只在/etc/passwd中查找用户信息的传统的处理方法中。然而,如果shadow文件存在,并且能被打开的话,NYS将从shadow中抽取用户的口令。getpwuid 函数也是这样实现的。在这种方式下,用NYS编译的执行文件将透明地处理本地影子组件的安装。 <p>10.9 使用传统的NIS代码
如果你使用目前在标准C库中的客户代码的话,那么配置一个NIS客户就稍微有些不同。一方面,它使用一个ypbind后台程序(daemon)来广播查询运行着的服务器而不是从一个配置文件中取得(服务器)信息的。因此,你必须确信在启动期间开始运行ypbind。它必须在NIS域已被设置好并且RPC portmapper已启动后才被调用。此时,上面所示的调用ypcat进行对服务器测试才能工作。
最近,有许多有关NIS出错报告(bug reports),出错信息说“clntudp_create: RPC: portmapper failure – RPC: unable to receive”。这是由于对ypbind与库函数有关绑定信息的通信(沟通)方式的不兼容的改动。取得最新有关NIS工具的最新源程序并重新编译之可以解决这个问题。[5]
同样,传统的NIS确定是否要和如何将NIS信息与本地文件中的信息合并的方法与NYS中所使用的方法是有偏差的。例如,为了使用NIS口令maps,你必须在/etc/passwd map中包含下列行: <p>+:*:O:O::: <p>这标记出口令查找函数“插入”NIS maps的地方。往/etc/group中插入类似的一行(去掉最后两个冒号)会对group.* maps做出同样的事。为了使用NIS分发的hosts.* maps,只要改动host.conf文件中的order一行。例如,如果你要使用NIS、DNS以及/etc/hosts文件(以这个顺序),你必须将这行改成 <p>order yp bind hosts <p>目前,传统的NIS实现不支持任何其它的maps。 <p><p><p>
注释
[1] 可以用swen@uni-paderborn.de与他联系。NIS客户程序以yp-linux.tar.gz的形式在matlab.unc.edu上的system/Network中有。
[2] 当前的版本(在写作本书时)是yps-0.21并且可以从ftp.lysator.liu.se的/pub/NYS目录中取得。
[3] 可以用pen@lysator.liu.se与他联系。
[4] DBM是一个简单的数据库管理库,它使用杂凑技术(hashing technigues)来加速查询操作。GNU计划有它的一个免费实现,称为gdbm,它已包括在大多数Linux发行版中。
[5] 可以从ftp.uni-paderborn.de的/pub/Linux/LOCAL目录中取得yp-linux源程序。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表