更新 Ubuntu 系统,避免报错「校验和不符」


【编者的话】网络运营商的 HTTP 缓存,会导致用户更新 Ubuntu 系统时报错「校验和不符」。如果构建以 Ubuntu 为基础的容器镜像过程出现这个错误, Dockerfile 后续指令不会再被执行。本文提出三种解决方案:(1)加 HTTP 或者 SOCKS 代理;(2)修改软件源的访问协议为 HTTPS 或者 FTP;(3)修改 apt 源码,用 IP 地址指定软件源服务器。

1. 问题

使用 Ubuntu 操作系统,执行
sudo apt-get update


更新系统时,经常会见到类似如下所示的报错信息:


W: 无法下载 http://cn.archive.ubuntu.com/u ... urces Hash 校验和不符
,系统更新失败。

这是一个烦人的问题,尤其是当以 Ubuntu 为基础构建容器镜像时,如果系统更新失败, Dockerfile 中的后续指令不会被执行。

「校验和不符」( Hash Sum mismatch) 在 2012 年已经被确认是 Ubuntu 的一个 BUG , 但是几年过去,还是没改好。

出现这个错误的原因是 Ubuntu 下载的索引文件不是来自指定的软件源,而是网络服务提供商的缓存。

网上给出的解决方案:
sudo apt-get clean
sudo rm -rf /var/lib/apt/lists
sudo apt-get update


经实际验证,这种方法是无效的。

2. 解决方法

(1)代理

指定使用 HTTP 代理。如果是设置只对当前会话有效的临时代理,执行
export http_proxy=http://yourproxyaddress:proxyport
sudo apt-get update
sudo apt-get upgrade


如果要设置持久代理,编辑 /etc/apt/apt.conf,添加一行:
Acquire::http::Proxy "http://yourproxyaddress:proxyport";


,然后执行:
sudo apt-get update
sudo apt-get upgrade


如果没有 HTTP 代理,只有 SOCKS 代理,首先安装 proxychains 程序,编辑 /etc/proxychains.conf ,指定 SOCKS 服务器的 IP 地址和端口;接下来,执行:
sudo proxychains apt-get update
sudo apt-get upgrade


(2)换协议

网络服务商只使用了 HTTP 缓存,如果软件源还支持 HTTPS 或者 FTP 协议,修改 /etc/apt/sources.list ,把其中所有的 http:// 换成 ftp:// ,再执行系统更新。

这种方法的不足是中国境内的软件源不支持 FTP 协议访问, Ubuntu 主服务器支持,但是网络速度会比较慢。

(3)黑科技

警告:这种方法是否有潜在问题,还有待持续一段时间的观察。不要在生产环境中使用。

第一步:修改 apt 包的源代码,不让它报这个错。
sudo apt-get install build-essential
sudo apt-get build-dep apt
sudo apt-get source apt


此时,有一个 apt-1.0.1ubuntu2.7 的文件夹,包含 apt 包的源代码。修改 apt-pkg/accquire-item.cc ,查找 HashSumMismatch 关键词。第一个出现的地方是打印报错信息的函数,不用管。把剩下的五段代码都注释掉。例如,
/*
if (!ExpectedHash.empty() && !ExpectedHash.VerifyFile(DestFile))
{
RenameOnError(HashSumMismatch);
Dequeue();
return;
}
*/


然后,在 apt-1.0.1ubuntu2.7 目录下,执行:
make
dpkg-buildpackage -us -uc -nc


成功执行后,在 apt-1.0.1ubuntu2.7 的上一级目录中有新创建的一系列 .deb 文件。我们的修改,包含在 libapt-pkg4.12_1.0.1ubuntu2.7_amd64.deb 中。

安装这个软件包,并标记为不更新:
sudo dpkg -i libapt-pkg4.12_1.0.1ubuntu2.7_amd64.deb
sudo apt-mark hold libapt-pkg4.12


第二步:把 /etc/apt/sources.list 中的软件源域名换成对应的 IP 地址。以中国服务器镜像为例,首先查找 cn.archive.ubuntu.com 对应的 IP 地址:
dig cn.archive.ubuntu.com


查询结果是:
cn.archive.ubuntu.com.  133 IN  CNAME mirrors.aliyun.com.
mirrors.aliyun.com. 133 IN  A 112.124.140.210
mirrors.aliyun.com. 133 IN  A 115.28.122.210


原来中国服务器就是阿里云镜像。编辑 /etc/apt/sources.list , 把 cn.arhive.ubuntu.com 替换成 112.124.140.210 ,保存。

从此以后,就可以无烦恼更新系统了。

=========================

作者:柳泉波,读书喝茶踢球写程序。

0 个评论

要回复文章请先登录注册