Linux网络管理员手册(18) 第十八章 NNTP说明
Linux网络管理员手册(18) 第十八章 NNTP说明 Linux网络管理员手册(18)
gohigh@shtdu.edu.cn
第十八章 NNTP说明
由于所使用的不同网络传输方式,NNTP为C News的新闻交换提供了一个非常不同的途径。NNTP代表“网络新闻传输协议”(“Network News Transfer Protocol”),它并不是一个特定的软件包,而是一个Internet标准。[1] 它是基于通常在TCP上的流式连接,该连接存在于网络中的客户和在磁盘上保存着网络新闻的服务器主机之间。流式连接允许客户与服务器交互地协商几乎无延迟的文章传输,因而使得重复的文章数量很低。另外,还由于Internet的高传输速率,这使得至今新闻的传输胜过原来的UUCP网络。而在几年前,让一篇文章到达Usenet的最后一个角落往往要两个星期或更长的时间,这在当时是普遍的现象,但现在常常不用两天就能到达;而在Internet当中,甚至只需要几分钟就行了。
有各种命令允许客户检索(提取)、发送和投递文章。发送和投递之间的区别在于后者可能涉及带有不完整标题信息的文章。[2] 文章的检索可以被用于新闻传输客户以及新闻阅读器。这使得NNTP为许多客户在一个本地网络上提供进行新闻访问的一个极好的工具,而不需要在使用NFS时绕弯子。
NNTP同样也提供主动的和被动的新闻传输方法,相应地称为“推入”(“pushing”)和“拉出”(“pulling”)操作。推入操作基本上与C News的ihave/sendme协议相同。客户通过“IHAVE ”命令向服务器提供文章,而服务器则返回一个响应代码,指出是否已有这篇文章,还是想要这篇文章。如果想要这篇文章,客户就会发送出这篇文章,并且用单个点在一独立行上来结束该篇文章。
推入新闻有一个缺点,它会给服务器系统带来很大的负荷,因为服务器必须针对每篇文章搜索它的历史数据库。
相反的技术是拉出新闻,在这种操作中,客户从一个组中请求一在指定日期以后到达的所有文章的列表清单。这个查询是由NEWNEWS命令来执行的。从返回的消息标题中,客户挑选出那些自己还没有的文章,然后对每篇文章依次使用ARTICLE命令。
拉出新闻的问题在于它需要服务器对客户请求的组和发布的信息有严密的控制。例如,它必须确保本地站点新闻组中没有机密的资料被发送给未经认可的客户。
对于新闻阅读器还有许多方便的命令允许它们对文章标题和文章内容分别检索,甚至是检索一系列文章标题行中的一行。这让你能够将所有的新闻都保存在一个中央主机上,让网络上的所有用户(假定都是本地的)使用基于NNTP的客户程序进行新闻的阅读和投递。这是第17章中讨论过的通过NFS输出新闻目录的另一种替代方法。
NNTP的一个总体问题是它允许有本事者将有着伪造发送者说明的文章插入到新闻流中。这称为伪造新闻(news faking)。[3] 一个对NNTP的扩展是对特定命令要求用户身份验证。
现存有很多NNTP软件包。其中最为有名的是NNTP daemon,也以参考实现(reference implementation)知名。原先,它是由Stan Barber和Phil Lapsley编写的,用以演示RFC 977的细节。目前它的最新版本是nntpd-1.5.11,这将在下面讨论。你或者可以取得源程序并由你自己进行编译,或者使用Fred van Kempen的net-std执行程序包中的nntpd。没有现存的直接可用的nntpd,因为有很多与站点相关的值要编译进去。
nntpd软件包由一个服务器和两个客户软件以及一个inews替代程序组成,这两个客户软件分别用于拉出和推入操作。它们原是在Bnews环境下运行的,但有些奇怪的是它们在C News下也能很好的运行。然而,如果你计划使用NNTP不仅仅是给新闻阅读器提供访问你的新闻服务器的功能,那么参考实现并不是一个实用的选择。因此我们将只讨论nntpd软件包中的NNTP daemon,而不涉及其中的客户程序。
还有一个叫做“InterNet News”的软件包,或简称INN,是由Rich Salz编写的。它同时提供基于NNTP和UUCP的新闻传输,并且更适合于大型的新闻网络中。当它应用于NNTP上的新闻传输时,肯定要比nntpd好。INN目前的版本是inn-1.4sec。有一个Arjan de Vet编制的小软件用于在Linux机器上建立INN;可以从sunsite.unc.edu的system/Mail目录中得到它。如果你想设置INN,请参考随源程序而来的文档,以及定期投递到news.software.b中的INN FAQ。
18.2 安装NNTP服务器
NNTP服务器称为nntpd,根据新闻系统上所期望的负荷情况,可以用两种方式编译它。没有现成编译好的版本的,因为某些与站点相关的默认设置是编制在执行文件中的。所有的配置参数是通过在common/conf.h中的宏定义来实现的。
Nntpd可以配置成在系统启动时从rc.inet2启动的单机服务器,或配置成由inetd来管理的后台程序(daemon)。在后一种情况下,必须在/etc/inetd.conf中有着下面这样一个条目:
nntp stream tcp nowait news /usr/etc/in.nntpd nntpd
如果你将nntpd配置成单机形式的(独立的),请确信在inetd.conf中的任何象上面这样的行都已被注释掉了。在这两种方式下,都必须保证在/etc/services中有下面这一行:
nntp 119/tcp readnews untp # Network News Transfer Protocol
如果要临时存储任何入站的文章等,那么在你的新闻假脱机目录中nntpd也需要一个.tmp目录。你应该使用如下命令来创建它。
# mkdir /var/spool/news/.tmp
# chown news.news /var/spool/news/.tmp
18.3 限制NNTP的访问
对NNTP资源的访问是由/usr/lib/news中的nntp_access文件来控制的。该文件中的每一行描述了给予外部主机的访问权限。每一行的格式如下:
site read|xfer|both|no post|no [!exceptgroups]
如果一个客户连接至NNTP端口,nntpd就会通过客户的IP地址进行反向查询来获得客户主机的全资域名。此时客户的主机名和IP地址就会用来与文件中出现的各个条目的site字段象比较进行检查。可能会是部分匹配也可能是完全匹配。如果有一个条目是完全匹配的,就使用这个条目;如果是部分匹配的,那么在没有任何其他更好的匹配条目时就应用这个条目。site可以用以下的方法之一来指定:
hostname 这是一个主机的全资域名。如果它与客户的规范主机名完全匹配的话,就使用这个条目,其余所有的条目都被忽略。
IP address 这是一个用*.domain指定的域名。如果客户的主机名与这个域名匹配的话,该条目就是匹配的。
network name 这是/etc/networks中指定的网络的名字。如果客户IP地址的网络号与网络名称相应的网络号匹配的话,该条目就是匹配的。
default default与任何客户相匹配。
有着更为一般的站点说明的条目应该在前面指定,因为任何这些匹配条目将会被后面更精确的匹配条目所代替。
第二和第三个字段描述赋予客户的访问权限。第二个字段详细说明了通过拉出(读取)操作来检索新闻和通过推入(xfer)操作来传送新闻的许可权限。一个both值将启用两者,而no禁止这两种访问。第三个字段赋予客户投递文章的权限,也即,投递通过新闻软件完善过的原来有着不完整标题信息的文章。如果第二个字段含有值no,那么第三个字段就被忽略。
第四个字段是可选的,含有用逗号分开的禁止客户访问的组的清单。
一个样本nntp_access文件显示如下:
#
# by default, anyone may transfer news, but not read or post
default xfer no
#
# public.vbrew.com offers public access via modem, we allow
# them to read and post to any but the local.* groups
public.vbrew.com read post !local
#
# all other hosts at the brewery may read and post
*.vbrew.com read post
18.4 NNTP授权
当用大写字母写nntp_access文件中的访问记号时,nntpd对相应的操作需要从客户处得到认可权限。例如,当指定一个Xfer或XFER权限,那么只有在客户通过权限认可后,nntpd才让客户将文件传输到你的站点。
权限认可过程是依靠一个称为AUTHINFO的新的NNTP命令来完成的。使用这个命令,客户将发送一个用户名和一个密码到NNTP服务器,nntpd通过把这个用户名和密码与/etc/passwd数据库的内容作比较来验证它们,并且还要验证这个用户是否是属于nntp组的。
NNTP权限认可的目前实现仅仅是实验性的,因此其移植性并不是很好。其结果是它只能用于纯文本形式的密码数据库;影子密码库它是识别不了的。
18.5 nntpd与C News的相互作用
当收到一篇文章时,nntpd必须将它投递到新闻子系统中。根据它是用IHAVE还是POST命令接收的,文章将分别送至rnews或inews。除了调用rnews,你还可以(在编译时)将它配置成把入站文章进行批处理并且将处理结果移入/var/spool/news/in.coming中,在这个地方,将等待下一次队列操作时relaynews来取它们。
为了能够正确地执行ihave/sendme协议,nntpd必须能够访问history文件。因此,在编译时,你必须确信路径是正确的。你也必须确信C News和nntpd使用同样格式的history文件。C News使用dbm 杂凑(哈希)函数来访问它的;然而,dbm库有许多不同的和略微不兼容的实现。如果C News是与标准libc中不同的dbm库链接的话,那么你也必须让nntpd连接那个库。
nntpd和C News在数据库格式上不相容的一个典型征兆是,系统日志中的错误信息指出nntpd不能正确地打开它,或着是通过NNTP收到重复的文章。一个好的测试方法是从假脱机(spool)目录中任取一篇文章,远程登录(telnet)到nntp端口,并把这篇文章提供给nntpd,见如下所示(你的输入是象这样标记的)。当然,你必须用你想再次喂给nntpd的文章的message-ID来替换
$ telnet localhost nntp
Trying 127.0.0.1...
Connected to localhost
Escape characters is ‘^]’.
201 vstout NNTP[auth] server version 1.5.11t (16 November 1991) ready at
Sun Feb 6 16:02:32 1194 (no posting)
IHAVE
435 Got it.
QUIT
这个对话显示了nntpd的适当响应;信息“Got it”告诉你它已经有这篇文章了。如果你得到了信息“335 OK”而不是“Got it”,这表示由于某种原因对histroy文件的查询失败了。可以用Ctrl-D来中止对话。你可以通过检查系统日志来核对什么地方出错了;nntp将使用syslog的daemon来记录所有类型的消息。dbm库的不兼容通常在一条信息中本身就很明了,指出dbminit失败了。
注释
[1] 正式说明在RFC 977中。
[2] 当通过NNTP邮寄一篇文章时,服务器起码要加上一个标题字段,该字段是Nntp-Posting-Host:。其中含有客户的主机名。
[3] SMTP,即简单邮件传输协议也存在同样的问题。