2. 操作原理

在此,我们讨论 Usenet 新闻系统运作背后的基本概念。

2.1. 新闻组和文章

一篇 Usenet 新闻文章位于 Usenet 服务器磁盘上的一个文件或某些其他磁盘数据结构中,其内容如下所示

Xref: news.starcomsoftware.com starcom.tech.misc:211 starcom.tech.security:452
Newsgroups: starcom.tech.misc,starcom.tech.security
Path: news.starcomsoftware.com!purva!shuvam
From: Shuvam <shuvam@starcomsoftware.com>
Subject: "You just throw up your hands and reboot" (fwd)
Content-Type: TEXT/PLAIN; charset=US-ASCII 
Distribution: starcom
Organization: Starcom Software Pvt Ltd, India
Message-ID: <Pine.LNX.4.31.0107022153490.30462-100000@starcomsoftware.com>
Mime-Version: 1.0
Date: Mon, 2 Jul 2001 16:27:57 GMT

Interesting quote, and interesting article.

Incidentally, comp.risks may be an interesting newsgroup to follow. We
must be receiving the feed for this group on our server, since we
receive all groups under comp.*, unless specifically cancelled. Check it
out sometime.

comp.risks tracks risks in the use of computer technology, including
issues in protecting ourselves from failures of such stuff.

Shuvam

> Date: Thu, 14 Jun 2001 08:11:00 -0400
> From: "Chris Norloff" <cnorloff@norloff.com>
> Subject: NYSE: "Throw up your hands and reboot"
> 
> When the New York Stock Exchange computer systems crashed for 85
> minutes (8 Jun 2001), Andrew Brooks, chief of equity trading at
> Baltimore mutual fund giant T. Rowe Price, was quoted as saying "Hey,
> we're all subject to the vagaries of technology. It happens on your
> own PC at home. You just throw up your hands and reboot."
> 
> http://www.washingtonpost.com/ac3/ContentServer?articleid=A42885-2001Jun8&pagename=article
> 
> Chris Norloff
> 
> 
> This is from --
> 
> From: risko@csl.sri.com (RISKS List Owner)
> Newsgroups: comp.risks
> Subject: Risks Digest 21.48
> Date: Mon, 18 Jun 2001 19:14:57 +0000 (UTC)
> Organization: University of California, Berkeley
> 
> RISKS-LIST: Risks-Forum Digest  Monday 19 June 2001
> Volume 21 : Issue 48
> 
>    FORUM ON RISKS TO THE PUBLIC IN COMPUTERS AND RELATED SYSTEMS (comp.risks)
>    ACM Committee on Computers and Public Policy,
>    Peter G. Neumann, moderator
> 
> This issue is archived at <URL:http://catless.ncl.ac.uk/Risks/21.48.html>
> and by anonymous ftp at ftp.sri.com, cd risks .
> 

如果您想了解 Usenet 的运作方式,Usenet 文章的标头非常有趣。发件人, 主题,和日期标头对于任何使用过电子邮件的人来说都很熟悉。Message-ID标头包含每条消息的唯一 ID,并且存在于每封电子邮件消息中,尽管许多非技术电子邮件用户并不了解它。Content-TypeMime-Version标头用于文章的 MIME 编码、附加文件和其他附件,就像在电子邮件消息中一样。

Organisation标头是一个信息性标头,旨在携带一些信息,以标识文章作者所属的组织。现在剩下的是Newsgroups, Xref, PathDistributions标头。这些是 Usenet 文章特有的,并且非常重要。

OrganisationNewsgroups标头指定此文章应属于哪些新闻组。Distributions标头在当今全球化的互联网世界中可悲地未得到充分利用,它允许文章作者指定文章将被重新传输的范围。文章的作者与配置良好的 Usenet 服务器网络协同工作,可以控制其文章复制的“半径”,从而将具有本地意义的文章发布到新闻组中,但将Distribution标头设置为适当的设置,例如localstarcom,以防止文章被中继到指定域之外的服务器。

OrganisationXref标头指定此文章在插入的每个新闻组中的精确文章编号,对于当前服务器而言。当一篇文章作为新闻源的一部分从一个服务器复制到另一个服务器时,接收服务器会丢弃旧的Xref标头,并插入自己的标头,其中包含其自己的文章编号。这表明了 Usenet 系统的一个有趣的特性:Usenet 服务器中的每篇文章对于它所属的每个新闻组都有一个唯一的编号(整数)。我们的示例文档已添加到我们服务器上的两个新闻组中,并且在这些组中的文章编号分别为 211 和 452。因此,任何 Usenet 客户端软件都可以查询我们的服务器,并请求新闻组starcom.tech.misc中的文章编号 211,并获取这篇文章。请求starcom.tech.security中的文章编号 452 也会获取这篇文章。在另一台服务器上,编号可能会非常不同。

OrganisationPath指定此文章在到达当前服务器之前经过的机器列表。此字符串使用 UUCP 样式语法。当前示例表明,一个名为shuvam的用户首先编写了这篇文章并将其发布到一台自称为purva的计算机上,然后这台计算机通过新闻源将这篇文章传输到news.starcomsoftware.comPath标头对于打破新闻源中的循环至关重要,稍后将详细讨论。

我们的示例文章将永远存在于上面列出的两个新闻组中,除非过期。服务器上的 Usenet 软件通常配置为根据某些条件使文章过期,例如,在文章超过一定天数后。我们使用的 C-News 软件允许基于新闻组层次结构和新闻组类型(,审核或未审核)进行过期控制。对于每类新闻组,它允许管理员指定文章过期前的天数。文章有可能通过携带Expires标头来控制其自身的过期时间,该标头指定日期和时间。除非在 Usenet 服务器软件中被覆盖,否则文章仅在其显式过期时间到达后才会过期。

2.2. 阅读器和服务器

访问 Usenet 文章的计算机大致分为两类:阅读器和服务器。Usenet 服务器携带文章存储库,管理它们,处理新闻源,并向授权的阅读器提供其存储库以供阅读。Usenet 阅读器仅仅是一台具有适当软件的计算机,允许用户访问软件、获取文章、发布新文章,并跟踪其在每个新闻组中已阅读的文章。就功能而言,Usenet 阅读软件对于 Usenet 管理员来说不如 Usenet 服务器软件有趣。然而,就代码行数而言,Usenet 阅读器软件通常可能比 Usenet 服务器软件大得多,这主要是因为现代 GUI 代码的复杂性。

大多数现代计算机几乎专门使用 NNTP(网络新闻传输协议)访问 Usenet 服务器进行阅读和发布。该协议也可用于服务器间通信,但这些方面将在稍后讨论。NNTP 协议与任何其他设计良好的基于 TCP 的互联网协议一样,携带以CR-LF结尾的 ASCII 命令和响应,并且包含一系列命令,有点让人联想到电子邮件的 POP3 协议。使用 NNTP,Usenet 阅读器程序连接到 Usenet 服务器,请求活动新闻组列表,并接收此(通常是巨大的)列表。然后,它将“当前新闻组”设置为其中一个,具体取决于用户想要浏览的内容。完成此操作后,它会获取组中所有当前文章的元数据,包括作者、主题行、日期和每篇文章的大小,并向用户显示文章索引。

然后,用户扫描此列表,选择一篇文章,并要求阅读器获取它。阅读器将此文章的文章编号提供给服务器,并获取完整的文章供用户阅读。一旦用户完成其 NNTP 会话,他就会退出,并且阅读器程序会关闭 NNTP 套接字。然后,它(通常)更新用户主目录中的本地文件,跟踪用户已阅读的新闻文章。下次通常不会向用户显示这些文章,从而允许用户在每个会话中快速浏览新文章。阅读器软件在此过程中得到了Xref标头的帮助,通过该标头,它知道单个文章在服务器中被标识的所有不同身份。因此,如果您通过访问starcom.tech.misc来阅读上面给出的示例文档,当您访问starcom.tech.miscstarcom.tech.security时,您将永远不会再次看到这篇文章;您的阅读器软件将通过跟踪Xref标头并映射文章编号来做到这一点。

当用户发布文章时,他首先使用其阅读器软件的用户界面编写消息。当他最终给出发送文章的命令时,阅读器软件会使用预先存在的 NNTP 连接联系 Usenet 服务器,并将文章发送给它。该文章携带Newsgroups标头,其中包含要发布到的新闻组列表,通常是Distribution标头,其中包含分发规范以及其他标头,如发件人, 主题 等等ExpiresApproved等特殊和罕见的标头在存在时会被执行。服务器为文章分配一个新的文章编号,用于它发布到的每个新闻组,并为文章创建一个新的Xref标头。

服务器之间的文章传输以各种方式完成,并在下面标题为“新闻源”的 XXX 节中进行了相当详细的讨论。

2.3. 新闻源

2.3.1. 基本概念

当我们尝试分析现实生活中的新闻源时,我们开始看到,对于大多数站点,流量在两个方向上都不是对称的。我们通常发现,一台服务器每天会将世界上大部分文章馈送到一台或多台辅助服务器,并交换接收由这些辅助服务器的用户编写的少量文章。因此,我们通常发现文章从全球 Usenet 服务器网络的主干流向分支,再流向叶子,而不是完全平衡的网状流动模式。因此,我们使用术语“上游服务器”来指代我们从中接收每日大部分文章的服务器,使用“下游服务器”来指代从我们这里接收大部分文章的服务器。

新闻源将文章从一台服务器中继到其“隔壁邻居”服务器,比喻来说。因此,文章在全球范围内移动,不是通过从原始服务器到世界各地每台服务器的大量单跳传输,而是通过一系列跳跃,就像在接力赛中传递接力棒一样。这增加了文章在经过十跳后到达远程三级服务器的延迟时间,但它允许更严格地控制在每次跳跃时中继的内容,并有助于冗余、服务器负载的去中心化和网络带宽的节省。在这方面,Usenet 新闻源比 HTTP 数据流更复杂,后者通常使用单跳技术。

因此,每台 Usenet 新闻服务器都必须担心每次接收文章时的新闻源,无论是通过新的帖子还是来自传入的新闻源。当 Usenet 服务器消化这篇文章并将其归档到其存储库中时,它同时会查看其数据库,以查看应将文章馈送到哪个其他服务器。为了做到这一点,它会执行一系列检查,如下所述。

每台服务器都知道哪些其他服务器是其“隔壁邻居”;此信息保存在其新闻源配置信息中。对于每个“隔壁邻居”,都将有一个它想要的新闻组列表和一个分发列表。新文章的新闻组列表将与“隔壁邻居”的新闻组列表进行匹配,以查看是否甚至有一个共同的新闻组使得有必要将文章馈送到它。如果存在匹配的新闻组,并且服务器的分发列表与文章的分发匹配,则文章将被标记为馈送到此邻居。

当邻居接收到作为新闻源一部分的文章时,它会执行一些自己的健全性检查。它执行的第一个检查是针对新文章的Newsgroups标头。如果在那里列出的新闻组中没有一个是该服务器的活动新闻组列表的一部分,则可以拒绝该文章。这样拒绝的文章甚至可以排队等待传出到其他服务器的新闻源,但不会被消化以纳入本地文章存储库。

执行的下一个检查是针对传入文章的Path标头。如果此标头在任何位置列出了当前 Usenet 服务器的名称,则表明它之前至少通过此服务器一次,并且现在由于新闻源循环而错误地重新出现在这里。为了冗余,新闻源拓扑中经常配置此类循环:“如果不是服务器 Y,我将从服务器 X 获取文章,并且让第一个服务器获胜。”Usenet 服务器软件会自动检测到文章的重复新闻源并拒绝它。

下一个检查是针对所谓的服务器历史数据库。每台 Usenet 服务器都有一个历史数据库,它是本地存储库中所有当前文章的消息 ID 列表。通常,历史数据库还包含最近过期的所有消息的消息 ID。如果传入文章的消息 ID 与数据库中的任何条目匹配,则再次拒绝它,而不会将其归档到本地存储库中。这是第二种循环检测方法。有时,仅仅检查文章的Path标头并不能检测到所有潜在问题,因为问题可能是重新插入而不是循环。当同一批传入的新闻文章被重新馈送到本地服务器时,会发生重新插入,可能是在系统崩溃后从磁带恢复系统数据之后。在这种情况下,没有新闻源循环,但仍然存在一篇文章可能被两次消化到本地服务器中的风险。历史数据库可以防止这种情况发生。

所有这些简单的检查都非常有效,并且根据互联网标准,跨服务器和软件类型工作。它们共同实现了稳健且故障安全的 Usenet 文章在全球范围内的流动。

2.3.2. 新闻源的类型

本节解释新闻源的基础知识,而无需深入了解软件和配置文件的细节。

2.3.2.1. 排队的新闻源

这是将文章从一台服务器发送到另一台服务器的最常用方法,并且每当每天要传输大量文章时都会遵循此方法。这种方法需要对上游服务器的配置进行一次性修改,为每个传出的新闻源定义一个新的队列

本质上,所有排队的新闻源都以以下方式工作。当发送服务器接收到一篇文章时,它会处理该文章以包含到其本地存储库中,并检查其所有传出的新闻源定义,以查看是否需要为任何新闻源对文章进行排队。如果是,则将其添加到每个传出新闻源的队列文件中。队列文件的精确细节可能会因软件实现而异,但基本过程保持不变。队列文件是排队文章的列表,但不包含文章内容。典型的队列文件是 ASCII 文本文件,每篇文章一行,给出本地假脱机区域中文章副本的路径。

稍后,一个单独的进程会拾取每个队列文件,并为每个传出的新闻源创建一批或多批批次批次是一个包含多篇 Usenet 新闻文章的大文件。批次创建完成后,可以使用各种传输机制将文件从发送服务器移动到接收服务器。您甚至可以使用脚本化的 FTP。您只需要确保从上游服务器拾取批次,并以某种方式将其复制到下游服务器中的指定传入批次目录中即可。

UUCP 传统上一直是批次移动的首选机制,因为它早于互联网和快速分组交换数据网络的广泛可用性。今天,随着 TCP/IP 无处不在,UUCP 再次成为批次移动最合理的选择,因为它也与时俱进:它可以通过 TCP 工作。

NNTP 是互联网上运营商级 Usenet 服务器移动排队新闻源的事实上的首选机制,不幸的是,对于许多其他 Usenet 服务器也是如此。我们在第 12.1 节> 中讨论了我们发现这种选择不幸的原因。但是在 NNTP 新闻源中,可以消除从队列文件构建批次的中间步骤---这既是它的优点又是它的缺点。

在排队的 NNTP 新闻源的情况下,文章会如上所述添加到队列文件中。NNTP 传输进程会定期唤醒,拾取队列文件,并与下游服务器建立 NNTP 连接。然后,它开始处理循环,其中对于每个排队的文章,它使用 NNTPIHAVE命令来通知下游服务器文章的消息 ID。下游服务器检查其本地存储库,以查看它是否已拥有该消息。如果不是,它会回复SENDME响应。然后,传输服务器以纯文本形式泵出文章内容。当队列中的所有文章都已如此处理后,发送服务器会关闭连接。如果 NNTP 连接在中间因任何原因中断,则发送服务器会截断队列文件,并且仅保留那些尚未传输的文章,从而最大限度地减少重复传输。

> 排队的 NNTP 新闻源与发送服务器建立到接收服务器的 NNTP 连接一起工作。这意味着接收服务器必须具有发送服务器知道或可以在 DNS 中查找的 IP 地址。如果接收服务器使用拨号连接定期连接到互联网并使用动态分配的 IP 地址工作,这可能会变得棘手。UUCP 新闻源没有此类问题,因为新闻源的发送服务器可以是 UUCP 服务器,被动的。新闻源的接收服务器可以是 UUCP 主服务器,主动方。因此,接收服务器可以启动 UUCP 连接并连接到发送服务器。因此,即使双方之一具有静态 IP 地址,UUCP 排队的新闻源也可以正常工作。

因此,NNTP 新闻源的发送速度可能比用于 UUCP 和其他旧方法的批次传输过程稍快,因为不需要构建批次。然而,NNTP 通常用于新闻源中,而这是不必要的,并且会导致带宽的巨大浪费。在我们研究 NNTP 与批次新闻源的效率问题之前,我们将介绍可以使用 NNTP 组织的另一种新闻源方式:拉取新闻源。

2.3.2.2. 拉取新闻源

这种传输一组文章的方法仅适用于 NNTP,并且绝对不需要在上游或传输服务器上进行任何配置。事实上,上游服务器甚至无法轻易检测到下游服务器正在拉取新闻源---它看起来就像一个繁重而彻底的新闻阅读器,仅此而已。

这种拉取新闻源的工作方式是,下游服务器像任何 NNTP 新闻阅读器一样,使用 NNTPARTICLE命令,并将消息 ID 作为参数,逐一拉取文章 i。有趣的细节是它最初是如何获得消息 ID 的。为此,它使用一个专门为拉取新闻源设计的 NNTP 命令,称为NEWNEWS。此命令采用层次结构和日期,
 NEWNEWS comp 15081997 

此命令由下游服务器通过 NNTP 发送到上游服务器,实际上是要求上游服务器列出comp层次结构中所有比 1997 年 8 月 15 日新的新闻文章。上游服务器回复一个(通常是巨大的)消息 ID 列表,每行一个,最后一行是一个句点。

然后,拉取服务器将每个新接收到的消息 ID 与其自己的文章数据库进行比较,并制作一个(可能更短的)它没有的所有文章的列表,从而消除重复获取。完成此操作后,它开始使用 NNTPARTICLE命令逐一获取文章,如上所述。

此外,还有另一个 NNTP 命令,NEWGROUPS,它允许 NNTP 客户端---,在这种情况下为下游服务器---询问其上游服务器自给定日期以来创建了哪些新新闻组。这允许下游服务器将新组添加到其active文件中。

OrganisationNEWNEWS基于 方法通常是拉取大型 Usenet 新闻源的最无效方法之一。通过低效率,我们在这里指的是上游服务器上的 CPU 负载和 RAM 利用率,而不是带宽使用率。这种低效率是因为大多数 Usenet 新闻服务器不按层次结构和日期索引其文章数据库;CNews 当然不会。这意味着向服务器发出的NEWNEWS命令将使该服务器对其文章数据库进行顺序搜索,以查看哪些文章符合给定的层次结构并且比给定的日期新。

如果拉取新闻源成为发送文章的最常见方式,那么所有上游服务器都将迫切需要一种有效的方式来对其文章数据库进行排序,以允许每个NEWNEWS命令快速生成其匹配文章列表。今天,一台速度较慢的上游服务器可能需要几分钟才能开始响应NEWNEWS命令,而下游服务器可能会超时并在此期间关闭其 NNTP 连接。我们经常看到这种情况发生,直到我们调整超时时间。

NNTP 用于新闻源中存在基本的带宽利用率效率问题,这适用于排队和拉取新闻源。但是NEWNEWS的问题是拉取新闻源独有的,并且与服务器负载有关,而不是带宽浪费。

2.4. 控制消息

Usenet 是一个庞大的分散服务器集合,几乎在没有任何监管的情况下运行,前提是它们具有足够的磁盘空间并且不会因电源故障等导致磁盘损坏。(事实上,令人惊讶的是,一个好的 Usenet 服务器是多么的自我管理,前提是满足这两个先决条件。)这些服务器都由人工管理员控制,但最好某些例行操作可以在所有这些服务器上从一个位置远程执行,而无需这些人的手动干预。

集中操作的一个常见需求是在标准八个层次结构中创建新组。Usenet 遵循相当正式的流程,该流程要求来自全球阅读者的投票,然后才能决定其新闻组列表的重组,包括合并低容量组、将高容量组拆分为许多专用组、创建新组,甚至删除组。一旦更改的投票过程结束并且要执行更改操作,向成千上万的 Usenet 管理员发送电子邮件并希望他们正确进行更改,并在他们感到困惑时回答他们的疑问,这将非常乏味。最好有一种自动方式来跨所有服务器进行更改,当然要经过适当的授权。

此解决方案不在于赋予某些中央机构在其选择的所有世界 Usenet 服务器上运行 OS 级命令的能力,因为 OS 命令因 OS 而异,并且很少有 Usenet 管理员会信任来自世界另一端的陌生人的 OS 级别访问权限。因此,解决方案在于定义一组常见的 Usenet 维护操作,并仅允许通过传递称为控制消息的特殊命令消息在所有服务器上触发这些操作。

控制消息或多或少看起来像普通的 Usenet 文章。它们有一个额外的标头行,其值采用特定格式,但它们通常带有看起来像普通人编写的文章的正文文本。这是一个控制消息(一个虚假的控制消息,但这暂时可以了)

Xref: news.starcomsoftware.com control:814217
Path: news.starcomsoftware.com!linux594.dn.net!news.dn.hoopoo.com!
	feed-out.newsfeeds.com!newsfeeds.com!feed.newsfeeds.com!
	newsfeeds.com!news-spur1.maxwell.syr.edu!news.maxwell.syr.edu!
	newsfeed.icl.net!newsfeed.skycache.com!Cidera!newsfeed.gamma.ru!
	Gamma.RU!carrier.kiev.ua!goblin.nadrabank.kiev.ua!not-for-mail
From: tale@uunet.uu.net (David C Lawrence)
Newsgroups: news.groups,humanities.hipcrime
Subject: cmsg newgroup humanities.hipcrime
Control: newgroup humanities.hipcrime
Date: Sun, 18 Feb 2001 11:50:28 GMT
Organization: The Cabal
Lines: 20
Approved: tale@uunet.uu.net
Message-ID: <3afWYZTIR.G5YOC2@uunet.uu.net>
NNTP-Posting-Host: 203.145.147.67
X-Trace: goblin.nadrabank.kiev.ua 982528840 21455 203.145.147.67
         (18 Feb 2001 20:40:40 GMT)
X-Complaints-To: usenet@nadrabank.kiev.ua
NNTP-Posting-Date: 18 Feb 2001 20:40:40 GMT
X-No-Archive: Yes

humanities.hipcrime is an unmoderated newsgroup which passed its
vote for creation by 326:10 as reported in news.announce.newgroups
on 18 Feb 2001.

For your newsgroups file:
humanities.hipcrime	HipCrime for Humanity - you committed one now!

Anyone can create a newsgroup in the alt, biz, comp, earth,
humanities, misc, news, meow, rec, sci, soc, talk, us, or
any other Usenet hierarchy.  New newsgroup proposals may be
optionally discussed in news.groups. Please be sure that your
/usr/lib/news/control.ctl is configured correctly:

##	NEWGROUP MESSAGES
## honor them all and log in \${LOG}/newgroup.log
newgroup:*:alt.*|biz.*|comp.*|earth.*|humanities.*|misc.*|news.*|\
	meaw.*|rec.*|sci.*|soc.*|talk.*|us.*:doit=newgroup

##	RMGROUP MESSAGES
## drop them all and don't log
rmgroup:*:*:drop

Meow!
David C Lawrence

控制消息必须具有Control标头。此外,所有控制消息都将具有Approved标头,就像发布到审核的新闻组的消息一样。Control标头实际上指定要在本地服务器上运行的命令,以及要提供给它的参数。本地 Usenet 服务器软件应该找出自己的方法来完成任务。在此示例中,Control标头中的命令是newgroup,它创建一个新的新闻组。其参数是humanities.hipcrime,它给出了要创建的新闻组的名称。

在 C-News 中,控制消息实现通过保存在固定目录中的单独 shell 脚本工作,$NEWSBIN/ctl/,作为一种安全措施;如果可执行脚本不存在于那里,则控制消息命令将被忽略。支持的控制消息类型有

Usenet 新闻软件维护一个名为control的伪新闻组,它在其中归档它接收到的所有控制消息。如果您有来自公共 Usenet 的传入新闻源,则您的服务器的control组通常会充满来自世界各地手指发痒的人的数千条取消消息。像 C-News 这样的 Usenet 新闻服务器软件允许您根据新闻组过滤传入的新闻源,并将丢弃其未订阅组的文章。但是,由于所有服务器都必须接收和处理控制消息,因此它们都将接受这些取消消息,尽管其中许多可能适用于不属于您高度修剪的组子集的文章。生活就是如此.

请记住将control组的过期时间设置为一天甚至更短,以便可以尽快清除垃圾,就像junk新闻组一样。

控制消息架构的优点在于,它无缝集成到新闻源机制中,以实现对服务器网络的自动控制。控制操作不需要单独的连接通道。文章复制会自动传播带有可读文章的控制消息,从而保证跨异构网络技术的覆盖范围。

您的 Usenet 服务器在接收到控制消息时执行的操作受授权文件$NEWSCTL/controlperms(在 C-News 的情况下)和control.ctl(例如,在 INN 的情况下)的约束。此模块实施的安全措施通过pgpcontrol软件包及其pgpverify脚本得到进一步增强。使用pgpverify,您的服务器可以检查所有控制消息(文章取消消息除外)是否由受信任方使用军用规格公钥加密进行数字签名。我们的集成 Usenet 新闻软件发行版包括与pgpverify.