最近 Arch Linux 终于把 OpenSSL 更新到了 3.x 系列版本。一直以来,在处理涉及打包工具链本身的 soname bump 等更新问题时,我们一直缺乏一个透明、优雅的流程。
以往采用过的方法包括但不限于:临时往编译环境里手动塞旧版本兼容包、手动在过渡版本的新版 PKGBUILD 里再编译一份旧版包然后把 lib 装进去等。由于处理这件事的开发者一般独自完成了整个过程,留下来的资料除了 IRC 里的寥寥几语往往十分有限,对于其他开发者、或是下游发行版试图重现这个过程来说,都是一个比较痛苦的过程。
这一次趁着 OpenSSL 3 的机会,本喵深度参与了整个 bootstrap rebuild 过程,并且在 RISC-V port 里复现了一遍。现在记录一下大致的过程和遇到的问题,以备不时之需。
1、首先把旧版库打包,使其可以与新版库同时安装。
openssl-1.1:https://github.com/archlinux/svntogit-packages/commit/d50ecccc79b637830b71795bd919e6467e118ef0
由于需要避免文件冲突,相应的编译选项(–libdir)和 package() 过程中做了一些兼容性处理。如果这个包还需要在 rebuild 之后留下来,比如这次的 openssl-1.1 的情况,头文件和 pkgconfig 的 .pc 文件也需要做处理。如果只是作为兼容包,可以仅保留带 soname 和具体版本的库文件本身。(当然,这种情况下也可以考虑在新版包里直接编译一份旧版库安装进去,毕竟只是临时使用。)
2、让新版库临时依赖旧版库的包
这里用到的技巧是,在 package() 方法内追加 depends,以避免编译环境中提前引入这个依赖,产生文件冲突(此时的仓库中,原包名对应的包仍然是旧版本,和 openssl-1.1 兼容包存在文件冲突)。
3、用此时的环境 rebuild 整个工具链需要用到的基础包
这一步具体要处理哪些包需要仔细分析。以这次 openssl rebuild 为例,一共有这么多包需要先使用这个依赖了旧版库的新版包来 bootstrap 以避免破坏打包环境本身:
coreutils
cryptsetup
curl
kmod
krb5
libarchive
libevent
libfido2 (for systemd's tests)
libssh2
openldap
pacman
sudo
systemd
tpm2-tss (for systemd's tests)
4、rebuild 新版库,去掉对旧版库的依赖
在完成这个步骤之后,需要重建 build chroot 以去掉之前引入的旧版库(这确实是 Arch 工具链的一个毛病,当前的机制不能自动保证 chroot 是干净、完整的)。
5、将前面步骤里 rebuild 过的基础包再次 rebuild
这一步主要是为了保证环境干净。编译得到的包应该和之前没有差异。
至此,已经可以继续平常的 rebuild 过程处理剩下的包了。
OpenSSL 更新进入稳定仓库后,在群组里果然遇到了大胆部分更新的用户不幸炸掉自己的 pacman。甚至有使用 pacman-static 的用户也因为 sudo 链接到 openssl 而悲剧了。再次奉劝大家切忌对官方仓库内的软件包部分更新,尤其是这种一看就不好惹的系统核心库!
另外,本喵自己的老 OpenVPN 配置在更新后也被制裁了:
SSL_CTX_use_certificate:ca md too weak
于是只好加入了 tls-cipher "DEFAULT:@SECLEVEL=0"
从此远离了推荐的配置。
我当时过度紧张以为自己的 pacman 爆炸了, 去下了 pacman-static 来修, 后来一翻历史才发现自己是把 pacman 打成了 paru (我说我没有部分更新为啥会炸
喵喵喵