[ 上一页 ] [ 目录 ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7 ] [ 8 ] [ 9 ] [ 10 ] [ 11 ] [ 12 ] [ A ] [ B ] [ C ] [ D ] [ E ] [ F ] [ G ] [ H ] [ 下一页 ]


Debian 手册安全指南
第 7 章 - Debian 安全基础设施


7.1 Debian 安全团队

Debian 有一个安全团队,负责处理 stable 发行版中的安全问题。处理安全问题意味着他们跟踪软件中出现的漏洞(关注 Bugtraq 或 vuln-dev 等论坛),并确定 stable 发行版是否受到影响。

此外,Debian 安全团队也是上游开发者或 CERT 等组织协调的问题的联络点,这些问题可能影响多个供应商。也就是说,当问题不是 Debian 特有时。安全团队的联络点是 team@security.debian.org,只有安全团队的成员才能阅读。

敏感信息应发送到第一个地址,在某些情况下,应使用 Debian 安全联系密钥(可在 Debian 密钥环中找到)进行加密。

一旦安全团队收到可能的问题,它将调查 stable 发行版是否受到影响,如果受到影响,则会对源代码库进行修复。此修复有时包括向上游(通常比 Debian 发行的版本提前几个版本)制作的补丁进行反向移植。完成修复的测试后,将准备新的软件包并在 http://security.debian.org 站点上发布,以便可以通过 apt 检索(请参阅 执行安全更新,第 4.2 节)。同时,Debian 安全公告 (DSA) 会在网站上发布,并发送到公共邮件列表,包括 debian-security-announce 和 Bugtraq。

关于 Debian 安全团队的其他常见问题可以在 关于 Debian 安全团队的问题,第 12.3 节 中找到。


7.2 Debian 安全公告

每当发现影响 Debian 软件包的安全漏洞时,都会发布 Debian 安全公告 (DSA)。这些公告由安全团队成员之一签名,包括受影响的版本以及更新位置的信息。此信息是

DSA 发布在 Debian 首页Debian 安全页面 上。通常,这不会在网站重建(每四小时一次)之前发生,因此它们可能不会立即出现。首选渠道是 debian-security-announce 邮件列表。

然而,感兴趣的用户可以(并且在一些 Debian 相关门户中这样做)使用 RDF 频道自动将 DSA 下载到他们的桌面。一些应用程序,例如 Evolution(电子邮件客户端和个人信息助理)和 Multiticker(GNOME 小程序),可以用于自动检索公告。RDF 频道可在 http://www.debian.org/security/dsa.rdf 获得。

网站上发布的 DSA 可能会在发送到公共邮件列表后进行更新。常见的更新是添加对安全漏洞数据库的交叉引用。此外,DSA 的翻译[49] 不会发送到安全邮件列表,而是直接包含在网站中。


7.2.1 漏洞交叉引用

Debian 提供了一个完整的 交叉引用表,包括自 1998 年以来发布的所有公告的所有可用引用。此表旨在补充 CVE 提供的参考地图

您会注意到此表提供了对安全数据库的引用,例如 BugtraqCERT/CC 公告US-CERT 漏洞注释数据库 以及 CVE 名称(见下文)。提供这些引用是为了方便使用,但只有 CVE 引用会定期审查和包含。

将交叉引用添加到这些漏洞数据库的优点是


7.2.2 CVE 兼容性

Debian 安全公告在 2004 年 2 月 24 日被 声明为 CVE 兼容[50]。

Debian 开发者理解需要提供关于 Debian 发行版安全状态的准确和最新的信息,允许用户管理与新安全漏洞相关的风险。CVE 使我们能够提供标准化的引用,允许用户开发 启用 CVE 的安全管理流程

通用漏洞和暴露 (CVE) 项目由 MITRE 公司维护,并提供漏洞和安全暴露的标准名称列表。

Debian 认为,向用户提供与影响 Debian 发行版的安全问题相关的额外信息非常重要。在公告中包含 CVE 名称有助于用户将通用漏洞与特定的 Debian 更新相关联,从而减少处理影响我们用户的漏洞所花费的时间。此外,它简化了在环境中的安全管理,在该环境中,启用 CVE 的安全工具(例如网络或主机入侵检测系统或漏洞评估工具)已经部署,无论它们是否基于 Debian 发行版。

Debian 为自 1998 年 9 月以来发布的所有 DSA 提供 CVE 名称。所有公告都可以在 Debian 网站上检索到,并且与新漏洞相关的公告在发布时如果可用,则会包含 CVE 名称。与给定 CVE 名称关联的公告可以直接通过 Debian 安全跟踪器(见下文)搜索。

在某些情况下,您可能在已发布的公告中找不到给定的 CVE 名称,例如因为


7.3 安全跟踪器

Debian 安全团队了解到的关于漏洞的中心数据库是 Debian 安全跟踪器。它交叉引用了软件包、不同套件的易受攻击和已修复版本、CVE 名称、Debian 错误编号、DSA 和杂项注释。它可以被搜索,例如,按 CVE 名称查看哪些 Debian 软件包受到影响或已修复,或按软件包显示未解决的安全问题。跟踪器中唯一缺少的信息是安全团队在禁运下收到的机密信息。

软件包 debsecan 使用跟踪器中的信息向系统管理员报告已安装的软件包中哪些是易受攻击的,以及哪些更新可用于修复安全问题。


7.4 Debian 安全构建基础设施

由于 Debian 目前在大量架构中得到支持,因此管理员有时会想知道给定架构是否可能比另一个架构需要更长的时间才能接收安全更新。事实上,除了极少数情况外,所有架构的更新都是同时提供的。

安全存档中的软件包是自动构建的,就像常规存档一样。然而,安全更新与软件包维护者发送的正常上传略有不同,因为在某些情况下,在发布之前,它们需要等待进一步测试、编写公告,或者需要等待一周或更长时间,以避免在所有供应商都有合理的机会修复之前公开漏洞。

因此,安全上传存档使用以下程序工作

此程序以前是手工完成的,在 Debian 3.0 woody 的冻结阶段(2002 年 7 月)进行了测试和实施。由于此基础设施,安全团队能够在不到一天的时间内为所有受支持的(近二十个)架构准备好 apache 和 OpenSSH 问题的更新软件包。


7.4.1 开发者安全更新指南

需要在其软件包中与安全团队协调修复问题的 Debian 开发者可以参考《开发者参考》部分 处理安全相关错误


7.5 Debian 中的软件包签名

本节也可以标题为“如何安全地升级/更新您的 Debian GNU/Linux 系统”,它应该有自己的章节,主要是因为它是一个重要的安全基础设施组成部分。软件包签名是一个重要的问题,因为它避免了在镜像中分发的软件包被篡改以及中间人攻击的下载。自动软件更新是一个重要的功能,但消除可能有助于木马传播和更新期间系统受损的安全威胁也很重要[51]。

Debian 不提供签名的软件包,但提供了一种自 Debian 4.0 (代号 etch) 以来可用的机制来检查下载软件包的完整性[52]。有关更多信息,请参阅 安全 apt,第 7.5.2 节

V. Alex Brennen 的 Strong Distribution HOWTO 中更好地描述了这个问题。


7.5.1 当前软件包签名检查方案

当前使用 apt 进行软件包签名检查的方案是

通过遵循 MD5 校验和链,apt 能够验证软件包是否来自特定发行版。这不如逐个签名每个软件包灵活,但也可以与该方案结合使用(见下文)。

此方案在 apt 0.6 中 完全实现,并且自 Debian 4.0 发行版以来可用。有关更多信息,请参阅 安全 apt,第 7.5.2 节。提供 apt 前端的软件包需要进行修改以适应此新功能;aptitude 就是这种情况,它已 修改 以适应此方案。目前已知可以与此功能正常工作的前端包括 aptitudesynaptic

软件包签名已在 Debian 中讨论了一段时间,有关更多信息,您可以阅读:http://www.debian.org/News/weekly/2001/8/http://www.debian.org/News/weekly/2000/11/


7.5.2 安全 apt

自 Debian 4.0 etch 及更高版本以来可用的 apt 0.6 版本包括 apt-secure(也称为 安全 apt),它是一个工具,允许系统管理员测试通过上述方案下载的软件包的完整性。此版本包括工具 apt-key,用于向 apt 的密钥环添加新密钥,默认情况下,密钥环仅包含当前的 Debian 存档签名密钥。

这些更改基于 apt 的补丁(可在 Bug #203741 中获得),该补丁提供了此实现。

安全 apt 通过 Release 文件检查发行版来工作,如 每个发行版发布检查,第 7.5.3 节 中所述。通常,此过程对管理员是透明的,尽管您每年[53]都需要干预以在密钥轮换时添加新的存档密钥,有关管理员需要采取的步骤的更多信息,请查看 安全地添加密钥,第 7.5.3.7 节

此功能仍在开发中,如果您认为您发现了其中的错误,请首先确保您使用的是最新版本(因为此软件包在最终发布之前可能会发生很大变化),并且如果运行最新版本,请针对 apt 软件包提交错误报告。

您可以在 wiki 页面 和官方文档中找到更多信息:迁移到 APT 0.6APT 签名检查


7.5.3 每个发行版发布检查

本节描述了发行版发布检查机制的工作原理,它由 Joey Hess 编写,也可在 Debian Wiki 中获得。


7.5.3.1 基本概念

以下是一些基本概念,您需要理解这些概念才能理解本节的其余部分。

校验和是一种将文件简化为一个相当短的数字的方法,该数字唯一地标识文件的内容。做好这一点比看起来要难得多,最常用的校验和类型 MD5 校验和正在被破解。

公钥密码术基于密钥对,即公钥和私钥。公钥发布给全世界;私钥必须保密。任何拥有公钥的人都可以加密消息,以便只有拥有私钥的人才能读取。也可以使用私钥对文件进行签名,而不是加密它。如果使用私钥对文件进行签名,那么任何拥有公钥的人都可以检查该文件是否由该密钥签名。任何没有私钥的人都无法伪造这样的签名。

这些密钥是非常长的数字(1024 到 2048 位或更长),为了使它们更易于使用,它们有一个密钥 ID,这是一个更短的 8 位或 16 位数字,可用于引用它们。

gpg 是安全 apt 中用于签名文件和检查其签名的工具。

apt-key 是一个程序,用于管理安全 apt 的 gpg 密钥环。密钥环保存在文件 /etc/apt/trusted.gpg 中(不要与相关的但不是很有趣的 /etc/apt/trustdb.gpg 混淆)。apt-key 可用于显示密钥环中的密钥,以及添加或删除密钥。


7.5.3.2 Release 校验和

Debian 存档包含一个 Release 文件,每次存档中的任何软件包发生更改时都会更新该文件。除其他外,Release 文件包含存档中其他文件的一些 MD5 校验和。Release 文件示例的摘录

     MD5Sum:
      6b05b392f792ba5a436d590c129de21f            3453 Packages
      1356479a23edda7a69f24eb8d6f4a14b            1131 Packages.gz
      2a5167881adc9ad1a8864f281b1eb959            1715 Sources
      88de3533bf6e054d1799f8e49b6aed8b             658 Sources.gz

Release 文件还包括 SHA-1 校验和,一旦 MD5 校验和完全被破解,这将很有用,但是 apt 尚未使用它们。

现在,如果我们查看 Packages 文件内部,我们会发现更多 MD5 校验和,每个列出的软件包都有一个。例如

         Package: uqm
         Priority: optional
         ...
         Filename: unstable/uqm_0.4.0-1_i386.deb
         Size: 580558
         MD5sum: 864ec6157c1eea88acfef44d0f34d219

这两个校验和可用于验证您是否下载了 Packages 文件的正确副本,其 md5sum 与 Release 文件中的 md5sum 匹配。当它下载单个软件包时,它还可以根据 Packages 文件的内容检查其 md5sum。如果 apt 在这些步骤中的任何一个步骤失败,它将中止。

这些在安全 apt 中都不是新的,但它确实提供了基础。请注意,到目前为止,有一个文件 apt 无法检查:Release 文件。安全 apt 的全部意义在于使 apt 在对其进行任何其他操作之前验证 Release 文件,并堵塞此漏洞,以便从您将要安装的软件包一直到软件包提供商都有一条验证链。


7.5.3.3 验证 Release 文件

为了验证 Release 文件,为 Release 文件添加了 gpg 签名。这放在一个名为 Release.gpg 的文件中,该文件与 Release 文件一起发布。它看起来像这样 [54] ,尽管只有 gpg 实际上正常查看其内容

     -----BEGIN PGP SIGNATURE-----
     Version: GnuPG v1.4.1 (GNU/Linux)
     
     iD8DBQBCqKO1nukh8wJbxY8RAsfHAJ9hu8oGNRAl2MSmP5+z2RZb6FJ8kACfWvEx
     UBGPVc7jbHHsg78EhMBlV/U=
     =x6og
     -----END PGP SIGNATURE-----

7.5.3.4 apt 检查 Release.gpg

安全 apt 总是在下载 Release 文件时下载 Release.gpg 文件,如果无法下载 Release.gpg,或者签名错误,它将发出抱怨,并将记录 Release 文件指向的 Packages 文件以及其中列出的所有软件包都来自不受信任的来源。以下是 apt-get update 期间的样子

     W: GPG error: http://ftp.us.debian.org testing Release: The following signatures
      couldn't be verified because the public key is not available: NO_PUBKEY 010908312D230C5F

请注意,长数字的后半部分是 apt 不知道的密钥的密钥 ID,在本例中为 2D230C5F。

如果您忽略该警告并稍后尝试安装软件包,apt 将再次警告

     WARNING: The following packages cannot be authenticated!
       libglib-perl libgtk2-perl
     Install these packages without verification [y/N]?

如果您在此处说 Y,您将无法知道您获得的文件是您应该安装的软件包,还是可以拦截与服务器通信的某人[55]为您安排的完全不同的东西,其中包含令人讨厌的惊喜。

请注意,您可以使用 --allow-unauthenticated 运行 apt 来禁用这些检查。

还值得注意的是,较新版本的 Debian 安装程序在 apt 可用之前,在其 Debian 基础系统的 debootstrap 期间使用相同的签名 Release 文件机制,并且安装程序甚至使用此系统来验证它从网络下载的自身片段。此外,Debian 目前未在其 CD 上签名 Release 文件;apt 可以配置为始终信任来自 CD 的软件包,因此这不是一个大问题。


7.5.3.5 如何告诉 apt 信任什么

因此,整个系统的安全性取决于是否存在一个 Release.gpg 文件,该文件签名 Release 文件,以及 apt 使用 gpg 检查该签名。要检查签名,它必须知道签名文件的个人的公钥。这些密钥保存在 apt 自己的密钥环 (/etc/apt/trusted.gpg) 中,管理密钥是安全 apt 的作用所在。

默认情况下,Debian 系统预配置了密钥环中的 Debian 存档密钥。

     # apt-key list
     /etc/apt/trusted.gpg
     --------------------
     pub   1024D/4F368D5D 2005-01-31 [expires: 2006-01-31]
     uid                  Debian Archive Automatic Signing Key (2005) <ftpmaster@debian.org>

这里 4F368D5D 是密钥 ID,请注意,此密钥仅在一年期限内有效。Debian 轮换这些密钥是作为防止某种安全漏洞破坏密钥的最后一道防线。

这将使 apt 信任官方 Debian 存档,但是如果您向 /etc/apt/sources.list 添加一些其他 apt 存储库,如果您希望 apt 信任它,您还必须向 apt 提供其密钥。一旦您拥有密钥并验证了它,只需运行 apt-key add file 即可添加它。获取密钥和验证密钥是比较棘手的部分。


7.5.3.6 查找存储库的密钥

debian-archive-keyring 软件包用于将密钥分发给 apt。此软件包的升级可以添加(或删除)主 Debian 存档的 gpg 密钥。

对于其他存档,尚无标准位置可以找到给定 apt 存储库的密钥。有一个粗略的标准是将密钥放在存储库的网页上或作为存储库本身中的文件,但没有真正的标准,因此您可能必须搜索它。

Debian 存档签名密钥可在 http://ftp-master.debian.org/ziyi_key_2006.asc 获得(将 2006 替换为当年)。[56]

gpg 本身有一种分发密钥的标准方法,使用密钥服务器,gpg 可以从该服务器下载密钥并将其添加到其密钥环。例如

     $ gpg --keyserver pgpkeys.mit.edu --recv-key 2D230C5F
     gpg: requesting key 2D230C5F from hkp server pgpkeys.mit.edu
     gpg: key 2D230C5F: public key "Debian Archive Automatic Signing Key (2006) <ftpm
     aster@debian.org>" imported
     gpg: Total number processed: 1
     gpg:               imported: 1

然后,您可以从自己的密钥环中导出该密钥,并将其提供给 apt-key

     $ gpg -a --export 2D230C5F | sudo apt-key add -
     gpg: no ultimately trusted keys found
     OK

“gpg: no ultimately trusted keys found”警告意味着 gpg 未配置为最终信任特定密钥。信任设置是 OpenPGP Web-of-Trust 的一部分,此处不适用。因此,此警告没有问题。在典型的设置中,用户自己的密钥是最终信任的。


7.5.3.7 安全地添加密钥

通过将密钥添加到 apt 的密钥环,您是在告诉 apt 信任由该密钥签名的所有内容,这使您确定 apt 不会安装任何未由拥有私钥的人员签名的内容。但是,如果您足够偏执,您可以看到这只是将事情提高了一个级别,现在您不必担心软件包或 Release 文件是否有效,您可以担心您是否实际获得了正确的密钥。上面提到的 http://ftp-master.debian.org/ziyi_key_2006.asc 文件真的是 Debian 的存档签名密钥吗,还是已被修改(或者本文档撒谎)。

在安全方面保持偏执是好的,但是从这里验证事情更难。gpg 具有信任链的概念,该信任链可以从您确定的人开始,该人签名某人的密钥,该人签名其他密钥,等等,直到您获得存档密钥。如果您足够偏执,您会希望检查您的存档密钥是否由您可以信任的密钥签名,其信任链可以追溯到您亲自认识的人。如果您想这样做,请参加 Debian 会议或当地 LUG 进行密钥签名 [57]。

如果您无法承受这种程度的偏执,请在添加新的 apt 源和新密钥时执行您认为合适的任何操作。也许您想给提供密钥的人员发送邮件并验证它,或者也许您愿意冒险下载它并假设您获得了真实的东西。重要的是,通过将问题简化为要信任哪些存档密钥,安全 apt 使您可以根据自己的需要尽可能谨慎和安全。


7.5.3.8 验证密钥完整性

您可以验证指纹以及密钥上的签名。可以从多个来源检索指纹,您可以查看 The Debian System Book,与 IRC 上的 Debian 开发者交谈,阅读将宣布密钥更改的邮件列表或任何其他额外的手段来验证指纹。例如,您可以这样做

     $ GET http://ftp-master.debian.org/ziyi_key_2006.asc | gpg --import
     gpg: key 2D230C5F: public key "Debian Archive Automatic Signing Key (2006)
       <ftpmaster&debian.org>" imported
     gpg: Total number processed: 1
     gpg:               imported: 1
     $ gpg --check-sigs --fingerprint 2D230C5F
     pub   1024D/2D230C5F 2006-01-03 [expires: 2007-02-07]
           Key fingerprint = 0847 50FC 01A6 D388 A643  D869 0109 0831 2D23 0C5F
     uid   Debian Archive Automatic Signing Key (2006) <ftpmaster@debian.org>
     sig!3        2D230C5F 2006-01-03  Debian Archive Automatic Signing Key
                                       (2006) <ftpmaster@debian.org>
     sig!         2A4E3EAA 2006-01-03  Anthony Towns <aj@azure.humbug.org.au>
     sig!         4F368D5D 2006-01-03  Debian Archive Automatic Signing Key
                                       (2005) <ftpmaster@debian.org>
     sig!         29982E5A 2006-01-04  Steve Langasek <vorlon@dodds.net>
     sig!         FD6645AB 2006-01-04  Ryan Murray <rmurray@cyberhqz.com>
     sig!         AB2A91F5 2006-01-04  James Troup <james@nocrew.org>

然后从您的密钥(或您信任的密钥)检查信任路径到至少一个用于签名存档密钥的密钥。如果您足够偏执,您将告诉 apt 仅当您找到可接受的路径时才信任该密钥

     $ gpg --export -a 2D230C5F | sudo apt-key add -
     Ok

请注意,密钥是用以前的存档密钥签名的,因此理论上您只需建立在您以前的信任之上即可。


7.5.3.9 Debian 存档密钥年度轮换

如上所述,Debian 存档签名密钥每年在 1 月份更改。由于安全 apt 还很年轻,我们没有太多更改密钥的经验,并且仍然存在粗糙的地方。

在 2006 年 1 月,制作了一个新的 2006 年密钥,并且 Release 文件开始由它签名,但是为了尽量避免破坏拥有旧的 2005 年密钥的系统,Release 文件也由它签名。目的是 apt 会根据它拥有的密钥接受一个或另一个签名,但是 apt 结果证明存在错误,除非它同时拥有两个密钥并且能够检查两个签名,否则拒绝信任该文件。这在 apt 版本 0.6.43.1 中得到了修复。关于如何将密钥分发给已经拥有使用安全 apt 的用户的系统也存在混淆;最初,它被上传到网站,没有公告,也没有真正的方法来验证它,用户被迫手动下载它。

在 2006 年 1 月,制作了一个新的 2006 年密钥,并且 Release 文件开始由它签名,但是为了尽量避免破坏拥有旧的 2005 年密钥的系统,Release 文件也由它签名。为了防止对已经拥有使用安全 apt 系统的用户的最佳分发机制造成混淆,引入了 debian-archive-keyring 软件包,该软件包管理 apt 密钥环更新。


7.5.3.10 已知的发布检查问题

一个不太明显的问题是,如果您的时钟偏差很大,安全 apt 将无法工作。如果将其设置为过去的日期,例如 1999 年,apt 将失败并显示无益的消息,例如

     W: GPG error: http://archive.progeny.com sid Release: Unknown error executing gpg

虽然 apt-key list 将使问题变得明显

     gpg: key 2D230C5F was created 192324901 seconds in the future (time warp or clock problem)
     gpg: key 2D230C5F was created 192324901 seconds in the future (time warp or clock problem)
     pub   1024D/2D230C5F 2006-01-03
     uid                  Debian Archive Automatic Signing Key (2006) <ftpmaster@debian.org>

如果将其设置为过远的未来日期,apt 会将密钥视为已过期。

如果您使用 testing 或 unstable,您可能遇到的另一个问题是,如果您最近没有运行 apt-get update 并且 apt-get install 一个软件包,apt 可能会抱怨它无法进行身份验证(它为什么这样做?)。apt-get update 将解决此问题。


7.5.3.11 手动每个发行版发布检查

如果您现在想添加额外的安全检查,并且不想或无法运行最新的 apt 版本[58],您可以使用下面 Anthony Towns 提供的脚本。此脚本可以自动执行一些新的安全检查,以允许用户确信他/她正在下载的软件与 Debian 分发的软件匹配。这阻止了 Debian 开发者在没有上传到主存档所提供的问责制的情况下入侵某人的系统,或者镜像镜像几乎但不太像 Debian 的东西,或者镜像提供具有已知安全问题的过时 unstable 副本。

此示例代码,重命名为 apt-check-sigs,应以下列方式使用

     # apt-get update
     # apt-check-sigs
     (...results...)
     # apt-get dist-upgrade

首先,您需要

这是 apt-check-sigs 的示例代码,最新版本可以从 http://people.debian.org/~ajt/apt-check-sigs 检索。此代码目前处于 beta 版,有关更多信息,请阅读 http://lists.debian.org/debian-devel/2002/debian-devel-200207/msg00421.html

     #!/bin/bash
     
     # Copyright (c) 2001 Anthony Towns <ajt@debian.org>
     #
     # This program is free software; you can redistribute it and/or modify
     # it under the terms of the GNU General Public License as published by
     # the Free Software Foundation; either version 2 of the License, or
     # (at your option) any later version.
     #
     # This program is distributed in the hope that it will be useful,
     # but WITHOUT ANY WARRANTY; without even the implied warranty of
     # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     # GNU General Public License for more details.
     
     rm -rf /tmp/apt-release-check
     mkdir /tmp/apt-release-check || exit 1
     cd /tmp/apt-release-check
     
     >OK
     >MISSING
     >NOCHECK
     >BAD
     
     arch=`dpkg --print-installation-architecture`
     
     am_root () {
             [ `id -u` -eq 0 ]
     }
     
     get_md5sumsize () {
             cat "$1" | awk '/^MD5Sum:/,/^SHA1:/' | 
               MYARG="$2" perl -ne '@f = split /\s+/; if ($f[3] eq $ENV{"MYARG"}) {
     print "$f[1] $f[2]\n"; exit(0); }'
     }
     
     checkit () {
             local FILE="$1"
             local LOOKUP="$2"
     
             Y="`get_md5sumsize Release "$LOOKUP"`"
             Y="`echo "$Y" | sed 's/^ *//;s/  */ /g'`"
     
             if [ ! -e "/var/lib/apt/lists/$FILE" ]; then
                     if [ "$Y" = "" ]; then
                             # No file, but not needed anyway
                             echo "OK"
                             return
                     fi
                     echo "$FILE" >>MISSING
                     echo "MISSING $Y"
                     return
             fi
             if [ "$Y" = "" ]; then
                     echo "$FILE" >>NOCHECK
                     echo "NOCHECK"
                     return
             fi
             X="`md5sum < /var/lib/apt/lists/$FILE | cut -d\  -f1` `wc -c < /var/lib
     /apt/lists/$FILE`"
             X="`echo "$X" | sed 's/^ *//;s/  */ /g'`"
             if [ "$X" != "$Y" ]; then
                     echo "$FILE" >>BAD
                     echo "BAD"
                     return
             fi
             echo "$FILE" >>OK
             echo "OK"
     }
     
     echo
     echo "Checking sources in /etc/apt/sources.list:"
     echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
     echo
     (echo "You should take care to ensure that the distributions you're downloading
     "
     echo "are the ones you think you are downloading, and that they are as up to"
     echo "date as you would expect (testing and unstable should be no more than"
     echo "two or three days out of date, stable-updates no more than a few weeks"
     echo "or a month)."
     ) | fmt
     echo
     
     cat /etc/apt/sources.list | 
       sed 's/^ *//' | grep '^[^#]' |
       while read ty url dist comps; do
             if [ "${url%%:*}" = "http" -o "${url%%:*}" = "ftp" ]; then
                     baseurl="${url#*://}"
             else
                     continue
             fi
     
             echo "Source: ${ty} ${url} ${dist} ${comps}"
     
             rm -f Release Release.gpg
             lynx -reload -dump "${url}/dists/${dist}/Release" >/dev/null 2>&1
             wget -q -O Release "${url}/dists/${dist}/Release"
     
             if ! grep -q '^' Release; then
                     echo "  * NO TOP-LEVEL Release FILE"
                     >Release
             else
                     origline=`sed -n 's/^Origin: *//p' Release | head -1`
                     lablline=`sed -n 's/^Label: *//p' Release | head -1`
                     suitline=`sed -n 's/^Suite: *//p' Release | head -1`
                     codeline=`sed -n 's/^Codename: *//p' Release | head -1`
                     dateline=`grep "^Date:" Release | head -1`
                     dscrline=`grep "^Description:" Release | head -1`
                     echo "  o Origin: $origline/$lablline"
                     echo "  o Suite: $suitline/$codeline"
                     echo "  o $dateline"
                     echo "  o $dscrline"
     
                     if [ "${dist%%/*}" != "$suitline" -a "${dist%%/*}" != "$codeline" ]; then
                             echo "  * WARNING: asked for $dist, got $suitline/$codeline"
                     fi
     
                     lynx -reload -dump "${url}/dists/${dist}/Release.gpg" >/dev/null 2>&1
                     wget -q -O Release.gpg "${url}/dists/${dist}/Release.gpg"
     
                     gpgv --status-fd 3 Release.gpg Release 3>&1 >/dev/null 2>&1 | sed -n "s/^\[GNUPG:\] //p" | (okay=0; err=""; while read gpgcode rest; do
                             if [ "$gpgcode" = "GOODSIG" ]; then
                                 if [ "$err" != "" ]; then
                                     echo "  * Signed by ${err# } key: ${rest#* }"
                                 else
                                     echo "  o Signed by: ${rest#* }"
                                     okay=1
                                 fi
                                 err=""
                             elif [ "$gpgcode" = "BADSIG" ]; then
                                 echo "  * BAD SIGNATURE BY: ${rest#* }"
                                 err=""
                             elif [ "$gpgcode" = "ERRSIG" ]; then
                                 echo "  * COULDN'T CHECK SIGNATURE BY KEYID: ${rest %% *}"
                                 err=""
                             elif [ "$gpgcode" = "SIGREVOKED" ]; then
                                 err="$err REVOKED"
                             elif [ "$gpgcode" = "SIGEXPIRED" ]; then
                                 err="$err EXPIRED"
                             fi
                         done
                         if [ "$okay" != 1 ]; then
                             echo "  * NO VALID SIGNATURE"
                             >Release
                         fi)
             fi
             okaycomps=""
             for comp in $comps; do
                     if [ "$ty" = "deb" ]; then
                             X=$(checkit "`echo "${baseurl}/dists/${dist}/${comp}/binary-${arch}/Release" | sed 's,//*,_,g'`" "${comp}/binary-${arch}/Release")
                             Y=$(checkit "`echo "${baseurl}/dists/${dist}/${comp}/binary-${arch}/Packages" | sed 's,//*,_,g'`" "${comp}/binary-${arch}/Packages")
                             if [ "$X $Y" = "OK OK" ]; then
                                     okaycomps="$okaycomps $comp"
                             else
                                     echo "  * PROBLEMS WITH $comp ($X, $Y)"
                             fi
                     elif [ "$ty" = "deb-src" ]; then
                             X=$(checkit "`echo "${baseurl}/dists/${dist}/${comp}/source/Release" | sed 's,//*,_,g'`" "${comp}/source/Release")
                             Y=$(checkit "`echo "${baseurl}/dists/${dist}/${comp}/source/Sources" | sed 's,//*,_,g'`" "${comp}/source/Sources")
                             if [ "$X $Y" = "OK OK" ]; then
                                     okaycomps="$okaycomps $comp"
                             else
                                     echo "  * PROBLEMS WITH component $comp ($X, $Y)"
                             fi
                     fi
             done
             [ "$okaycomps" = "" ] || echo "  o Okay:$okaycomps"
             echo
       done
     
     echo "Results"
     echo "~~~~~~~"
     echo
     
     allokay=true
     
     cd /tmp/apt-release-check
     diff <(cat BAD MISSING NOCHECK OK | sort) <(cd /var/lib/apt/lists && find . -type f -maxdepth 1 | sed 's,^\./,,g' | grep '_' | sort) | sed -n 's/^> //p' >UNVALIDATED
     
     cd /tmp/apt-release-check
     if grep -q ^ UNVALIDATED; then
         allokay=false
         (echo "The following files in /var/lib/apt/lists have not been validated."
         echo "This could turn out to be a harmless indication that this script"
         echo "is buggy or out of date, or it could let trojaned packages get onto"
         echo "your system."
         ) | fmt
         echo
         sed 's/^/    /' < UNVALIDATED
         echo
     fi
     
     if grep -q ^ BAD; then
         allokay=false
         (echo "The contents of the following files in /var/lib/apt/lists does not"
         echo "match what was expected. This may mean these sources are out of date,"
         echo "that the archive is having problems, or that someone is actively"
         echo "using your mirror to distribute trojans."
         if am_root; then 
             echo "The files have been renamed to have the extension .FAILED and"
             echo "will be ignored by apt."
             cat BAD | while read a; do
                 mv /var/lib/apt/lists/$a /var/lib/apt/lists/${a}.FAILED
             done
         fi) | fmt
         echo
         sed 's/^/    /' < BAD
         echo
     fi
     
     if grep -q ^ MISSING; then
         allokay=false
         (echo "The following files from /var/lib/apt/lists were missing. This"
         echo "may cause you to miss out on updates to some vulnerable packages."
         ) | fmt
         echo
         sed 's/^/    /' < MISSING
         echo
     fi
     
     if grep -q ^ NOCHECK; then
         allokay=false
         (echo "The contents of the following files in /var/lib/apt/lists could not"
         echo "be validated due to the lack of a signed Release file, or the lack"
         echo "of an appropriate entry in a signed Release file. This probably"
         echo "means that the maintainers of these sources are slack, but may mean"
         echo "these sources are being actively used to distribute trojans."
         if am_root; then 
             echo "The files have been renamed to have the extension .FAILED and"
             echo "will be ignored by apt."
             cat NOCHECK | while read a; do
                 mv /var/lib/apt/lists/$a /var/lib/apt/lists/${a}.FAILED
             done
         fi) | fmt
         echo
         sed 's/^/    /' < NOCHECK
         echo
     fi
     
     if $allokay; then
         echo 'Everything seems okay!'
         echo
     fi
     
     rm -rf /tmp/apt-release-check

您可能需要为 sid 应用以下补丁,因为当输入为 stdin 时,md5sum 会在总和后添加一个 '-'

     @@ -37,7 +37,7 @@
             local LOOKUP="$2"
     
             Y="`get_md5sumsize Release "$LOOKUP"`"
     -       Y="`echo "$Y" | sed 's/^ *//;s/  */ /g'`"
     +       Y="`echo "$Y" | sed 's/-//;s/^ *//;s/  */ /g'`"
     
             if [ ! -e "/var/lib/apt/lists/$FILE" ]; then
                     if [ "$Y" = "" ]; then
     @@ -55,7 +55,7 @@
                     return
             fi
             X="`md5sum < /var/lib/apt/lists/$FILE` `wc -c < /var/lib/apt/lists/$FILE`"
     -       X="`echo "$X" | sed 's/^ *//;s/  */ /g'`"
     +       X="`echo "$X" | sed 's/-//;s/^ *//;s/  */ /g'`"
             if [ "$X" != "$Y" ]; then
                     echo "$FILE" >>BAD
                     echo "BAD"

7.5.4 非 Debian 源的发布检查

请注意,当使用最新的 apt 版本(带有 secure apt)时,除非您使用非 Debian 源,否则您无需额外操作。如果您使用非 Debian 源,apt-get 将需要额外的确认步骤。通过在非 Debian 源中提供 ReleaseRelease.gpg 文件可以避免这种情况。Release 文件可以使用 apt-ftparchive(在 apt-utils 0.5.0 及更高版本中可用)生成,Release.gpg 只是一个分离签名。要生成这两个文件,请按照以下简单步骤操作

     $ rm -f dists/unstable/Release
     $ apt-ftparchive release dists/unstable > dists/unstable/Release
     $ gpg --sign -ba -o dists/unstable/Release.gpg dists/unstable/Release

7.5.5 包签名方案的替代方案

另一种为每个软件包进行签名的方案允许在软件包不再被现有 Packages 文件引用时对其进行检查,并且也可以在 Debian 中使用从未为其创建过 Packages 文件的第三方软件包,但这不会是默认方案。

此软件包签名方案可以使用 debsig-verifydebsigs 来实现。这两个软件包可以对 .deb 文件本身中嵌入的签名进行签名和验证。Debian 现在已经具备执行此操作的能力,但是由于首选归档签名方案,因此没有实施策略或其他工具的特性计划。这些工具可供宁愿使用此方案的用户和归档管理员使用。

最新的 dpkg 版本(自 1.9.21 起)包含一个 补丁,该补丁在安装 debsig-verify 后立即提供此功能。

注意:目前 /etc/dpkg/dpkg.cfg 默认配置为 “no-debsig”。

注意 2:由于当前首选的方法是如前所述的版本检查,因此来自开发者的签名在进入软件包归档时会被移除。


[ 上一页 ] [ 目录 ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7 ] [ 8 ] [ 9 ] [ 10 ] [ 11 ] [ 12 ] [ A ] [ B ] [ C ] [ D ] [ E ] [ F ] [ G ] [ H ] [ 下一页 ]


Debian 手册安全指南

版本:3.13,Sun,2012 年 4 月 8 日 02:48:09 +0000

Javier Fernández-Sanguino Peña jfs@debian.org
作者,1.1 节