下载的Linux软件包,怎么确认没被人动过手脚

从网上下载一个ISO镜像或者软件包,尤其是从镜像站、种子网络这类不完全受控的渠道拿到的文件,装到系统里之前多一步验证,能避免装了个被人动过手脚的版本。很多教程只教到sha256sum这一步就停了,其实这只完成了验证工作的一半。

sha256sum验证的是"完整",不是"真实"

1
sha256sum 下载的文件名

跑出来的这一串哈希值,如果跟官方公布的校验值对上了,说明这个文件在传输过程中没有损坏或者被篡改——但这里有个容易被忽略的漏洞:如果攻击者连官方公布的校验值本身也一起篡改了(比如你是从一个被劫持的镜像站同时拿到了文件和它对应的SHA256SUMS文件),两者对得上号,你验证得再仔细也是白搭,因为参照物本身就是假的。单纯的哈希校验,验证的是"文件有没有在传输中损坏",回答不了"这个文件到底是不是官方发布的原版"这个更关键的问题。

GPG签名验证,才是真正在确认"来源"

想同时验证完整性和真实性,得靠GPG签名这一层。以Ubuntu镜像为例,官方在发布ISO的同时,还会提供一份对应的.gpg签名文件,这份签名是用官方私钥对校验文件本身签的名,只有真正的官方才能生成这个签名。

先导入官方的公钥:

1
gpg --keyserver hkp://keyserver.ubuntu.com --recv-keys 官方公钥ID

再用这个公钥验证签名文件:

1
gpg --verify SHA256SUMS.gpg SHA256SUMS

看到Good signature from这行,说明这份校验文件确实是官方私钥签过名的,不是中途被人偷梁换柱换成假的。这一步验证通过之后,再拿这份可信的校验文件去比对你下载的实际文件:

1
sha256sum -c <(grep 你的文件名 SHA256SUMS)

两步叠加起来,才算是既确认了"文件没坏",又确认了"文件确实来自官方",单独任何一步都不能完全说明问题。

平时这么严格的验证,什么时候真正用得上

日常从大厂官方渠道装个常规软件包,被篡改的风险本来就不高,没必要每次都走这一整套流程。但遇到这几种场景,多花两分钟验证一下很值——从BT种子网络下载的镜像文件、从个人维护的第三方软件源添加的包、或者干脆是从来源不太确定的镜像站下载的东西。

一个容易忽略的细节:公钥本身也得从可信渠道拿

验证流程里还有个环节容易被跳过——gpg --recv-keys这一步,是从密钥服务器拉取官方公钥,如果这个公钥本身就是假的(比如从一个不可信的地方手动导入了一个伪造的公钥),后面所有的验证步骤都会"验证成功",但验证的是攻击者伪造的一整套签名体系,看着流程走完了,结果照样是假的。密钥服务器本身通常是分布式、多方维护的,比单一站点可信度更高,但如果条件允许,最好还是从软件官方网站直接确认一下公钥指纹(fingerprint)对不对得上,而不是盲目信任密钥服务器返回的第一个结果。

顺带一提

之前写Helium浏览器那篇提到过"只从官方GitHub下载,避免被篡改的安装包",这条建议背后的具体操作方法,其实就是这篇讲的这一套——不管是给服务器装软件包,还是给手机装一个第三方浏览器APK,验证来源可信这件事的思路是通用的。如果是在排查服务器是否已经被入侵,类似的多方交叉验证思路,可以参考VPS被暴力破解怎么查有没有被入侵那篇。