善意提醒

如果您打开本站很慢,布局排版混乱,并且看不到图片,那么可能是因为您还没有掌握用科学的方法上网的本领。
显示标签为“信创”的博文。显示所有博文
显示标签为“信创”的博文。显示所有博文

2025-10-24

程序员节,闻逆流有感

「惊闻」《四中全会决定大幅提高科技自立》,感觉到大概率又要搞一波运动了。

学大寨?放卫星?大炼钢铁?超英赶美?
不知道又有多少人借此机会大发「国难财」,不知道有多少从我这里上缴的税费溜进了这些投机者的口袋。

作为深受「信创」其害的 IT 从业人员,退休之心不由得更加迫切了。躲进小屋成一统,管它冬夏与春秋。反正种子我已经播下去了。

若要问我有什么想说的:如果《中科院反右中消失的一页——寻找青年物理研究者刘治平》这种事情不能得到真正的解决,包括那虽然幼稚可笑但起码是个态度的「平反」,以及彻底的清算和至少两代人以上的反思,那么所谓「科技自立」,只不过是镜中花、水中月,南柯一梦耳。

以及,以上只是必要条件,而非充分条件。听说现在义务教育不教「逻辑」,有不明白的请自行弯腰摸石头。

图片来自《中国数字时代》,阿平漫画


2024-09-29

信创踩坑笔记

图片来自网络

1. 银河麒麟(Kylin V10)

银河麒麟算是好的,毕竟高仿 CentOS。看它的文档,似乎 V4 的时候还是 Ubuntu / Debian 系的,现在的 V10 已经转到 RedHat / CentOS 派系下了。

我们的程序基本都是静态链接,所以就还好。唯一动态链接的是 OpenSSL,这个在《编译自己的 CentOS7 OpenSSL 1.0.2u 动态链接库》这篇 Blog 中已经介绍过了。

1.1. ldconfig

说起来算个坑的,就是它的 SP2 版本的 ldconfig 无法正确读取被 patchelf 改过 SONAME 的库,说什么「已被截断」。搜了一下,说是属于 ldconfig 的 Bug。patchelf 改过 soname 的 so 库,里面的段顺序会变。但规范里面并没写顺序是有保障的,ldconfig 不应该自行假设顺序一定是那个样子。

有人说这是上游供应链(glibc)的 Bug。的确无论 SP3 的哪个版本都是好的。但我看 SP2 和 SP3 的 glibc 的版本也没看出来有什么变化,这里先存疑一下吧。
我的应对方案就是 SP2 下就不改 SONAME 了,难看就难看一些。

1.2. VMware

接下来这一个实际上应该放在最前面,不过只是因为我用了 VMware 来安装这些而已。不见得所有人都会遇到。

银河麒麟 V10 安装在 VMware 上的时候,显示分辨率默认是 800×600。在这种情况下,无法调整显示分辨率,因为「保存」按钮被挡在屏幕外面了。
解决方法是用 xrandr,例如:

xrandr -s 1440x900_60

最后一个参数是刷新率(60Hz)。有些 Blog 上说这里只能用 xrandr 列出来的选项,但其实未必,只要显示器支持就行。
另外,有些 Blog 上说这种方式只能临时调整,重启后效果就没了。的确如此,可是现在屏幕大了,你就可以用 UI 来正式调整显示分辨率了,不是吗?

1.3. 9090 端口

我们有个服务,默认启动在 9090 端口上。结果等产品要上线到生产环境的时候,运维人员去启动的时候得到了报错,一看才发现 端口被人占了。
问题是我自己之前搭环境测试的时候,没有遇到这种情况。估计因为我的银河麒麟 V10 是「最小化安装」,而客户那边生产环境则没有这样做吧。

2. 达梦(DM8)

总的来说,在 Windows 上安装达梦 8 的过程要顺畅很多,没遇到什么问题。Linux 下就开始有坑。

2.1 ulimit

准备阶段的第一个坑是 ulimit 的问题,之前已经先写了 Blog,这里就只给出链接了《Linux 下修改 ulimit 不能完全生效的问题》。这个坑严格来说不算麒麟也不算达梦的问题,而且不见得所有人都会遇上。

2.2. cdrom

第二个坑是挂载光驱。挂上来之后没有 x 权限,但不知道怎么回事,用 -o exec 也挂不出来 x 权限。最后只好用命令行强制运行解决:

bash DMInstall.bin

接下来的安装倒是没出多大问题。我在 Linux 上安装达梦的目的只是为了抠出里面的 bin、include 和 drivers 目录来,用来制作 Python 和 PHP 的运行环境而已。所以后续运维的踩坑经验我就无法提供提供了。

2.3. Python

我们的 Python 运行环境是用 Conda 搭的,有 2.7 和 3.5 两个版本。按照达梦官方文档的说法(那文档写得不好,链接恕我不放了,自己搜吧),需要安装达梦客户端,然后再编译驱动。照着操作就可以,没什么大坑。

2.3.1. ldconfig

我是从一台安装了达梦客户端的 Linux 机器上把 bin、include、drivers 这三个目录抠了出来,设了一下 LD_LIBRARY_PATH,然后去 Conda 环境里面编译驱动。这样做是没问题。

但是当我把目录放 /etc/ld.conf.d 里面之后,一跑 ldconfig,sshd 直接挂掉了。数个 SSH 会话同时被踢,吓了我一大跳,还以为被黑客入侵了。

好在 tty 登录没有问题,看起来是 OpenSSL 导致了 OpenSSH 不能用了。一看达梦的 bin 目录,libcrypto.so 和 libssl.so 就这样裸躺在里面,服了。最后还是只能用回 LD_LIBRARY_PATH 方案。

2.3.2. 多线程

接下来我们尝试在 Python 环境中登录达梦数据库。有一个小坑:达梦的 dmPython.connect 会开子线程来进行登录。我们的 Python 环境在 Python 解释器跑起来后把 nproc 改成了 0,结果就 CoreDump 了。看过 CoreDump 里面的 CallStack 才明白原因。看起来 C 代码里面的异常捕获,dmPython 完全没有做嘛。抛个 Python 异常也好啊。

2.4. PHP

达梦的文档在这一部分有比较大的问题。
首先,有点语无伦次。无论是 yum 还是源代码编译,都是指的 PHP 的安装方式,但达梦的部分应该都是一样的。然而文档中却说得好像不一样。
其次,版本混乱。安装代码中同时有 7 和 5 的库,显然是更新文档的时候没有更新完整。
最后,其交代的技术细节存在着问题,至少与事实不符。我按照其中列出的 DPI 库准备的环境,PHP 的 PDO_DM 库完全加载不起来。

我想办法得到了一份正确的 so 依赖列表,比达梦文档中给出的要多,多了不少。主要是因为 libdmcalc.so 和 libdmdta.so 导致的。我觉得我直接给出我的 so 库列表并不是一个好主意,毕竟 DM8 的版本肯定也在不时地变化。更有用的是介绍我的方法。

我的方法也很简单:找个编辑器打开达梦的两个 PDO 的 so 库,然后就搜「.so」。ldd 中看得见的,这样能搜到。看不见的,那种用 dl_open 打开的,这样也能搜到。然后顺藤摸瓜就行。貌似 DPI 的那些 so 库都还不会用 dl_open。
当然,将来达梦如果对 so 的内容进行混淆或加密,那我就不敢说这样能行了。希望它不会犯这个蠢。

后面就还好了。我一度担心 OpenSSL 又惹事,但大概是我们的 PHP 环境比较简单,没惹出什么麻烦。我直接把它们塞进了一个 docker 镜像里面,这部分的工作成果总算是被固化了下来。

2024-09-09

编译自己的 CentOS7 OpenSSL 1.0.2u 动态链接库

图片由 Google Gemini 生成

因为老板想从「信创」分一杯羹,于是我们现在需要把一个 CentOS7 上面跑着的系统,移植到「银河麒麟」上去运行。

对于「国产」操作系统了解不多,不敢妄自确定方案。先去 下载 了银河麒麟的数个版本,主要都是服务器操作系统 V10,包括 SP2 的「CentOS 兼容版」,海光版,以及 SP3 2303 以及 2403 的海光版本。考虑到海光 CPU 也是 x86 架构,理论上应该可以跑在普通的 Intel / AMD CPU 的机器上,实际测试下来也是如此。

不得不说,我一开始对于情况设想得比现状要严峻一些。实在是没有想到银河麒麟 V10 对于 CentOS 抄得如此彻底,怪我太高看了国人的本领。无论是「CentOS 兼容版」还是海光版,我们在 CentOS7 上编译的东西,基本上拿上去就可以直接跑。
当然,从好处想,这样做的确提升了这些「国产」操作系统的兼容性,极大拓展了生态链。一定程度上也算是利国利民的好事情。除了钱以外的事情,我也就不吐槽了。

之所以说是「基本上」可以直接跑,是因为银河麒麟 V10 大概是从 CentOS8 开始「魔改」的,所以上面搭载的 OpenSSL 是 1.1.1 版本。有一些是 1.1.1c,有一些是 1.1.1f,总之不是 CentOS7 的 1.0.2。用 yum list 看了一下,源里面也只有 1.1.1 的版本可供安装。

我们的程序是在 CentOS7 上编译出来的,用了 so 版本的 OpenSSL 1.0.2,所以缺了这个东西还没法运行。尽管我们可以把自己的代码改成去链接 OpenSSL 1.1.1,或者索性静态链接进去,但还有些第三方厂商提供的库也是基于 OpenSSL 1.0.2 的,而且不算少。总之这个问题是绕不开的,只能迎头而上去解决它。
另外,我们发现那个「CentOS 兼容版」的默认安装会在 /lib64 下面形成 OpenSSL 1.0.2o 的库。yum list 里面还是没有,说明应该是某个软件包自行装上的。既然那个软件包可以这样做,我们也可以。把自己编译的 OpenSSL 1.0.2 的库放进系统里面去,然后 ldconfig 就好。

以上交代了背景,接下来就说说看具体怎么做,以及介绍一下踩过的坑。


编译 OpenSSL 很简单,从 OpenSSL官网 上下载 1.0.2u的tar.gz包(最后一个版本,1.0.2 已经停止维护了),解压以后编译:

wget https://openssl.org/source/old/1.0.2/openssl-1.0.2u.tar.gz
tar -xvzf openssl-1.0.2u.tar.gz
cd openssl-1.0.2u
./config --prefix=/usr/local/openssl-1.0.2u --openssldir=/usr/local/openssl-1.0.2u shared
make
make install

以上的操作,随处都可以搜到,AI 也能提供。不过编译出来的 openssl 动态链接库,有两个问题:

  1. 拿这两个编译出来的 so 库去用,会报「no version information available」。事实上 ldd 的时候就会报这个错。
  2. 编译出来的文件名是 libcrypto.so.1.0.0 和 libssl.so.1.0.0,而不是我想要的 libcrypto.so.1.0.2u 和 libssl.so.1.0.2u。

前者问题大一些,后者往小了说只是自己看着顺不顺眼的问题。一个一个解决吧。

问题1

拿着「no version information available」去搜,得到的信息不太具有参考价值。问 AI 也一样。
大多数的回答是说错用了别的操作系统编译的 OpenSSL 库,可能很多人遇到的情况也的确是这个,但显然我们遇到的情况并不是。

唯一找到 一篇相关文章,跟着评论找到了知乎上的 一篇文章。作者是想自己编译 1.0.2u 的库,替换掉 CentOS7 上的 1.0.2k 的版本。
顺带说一句:以前 CentOS7 还在维护,即使是 1.0.2k 的库,CentOS 也会补上安全漏洞。现在 CentOS7 不维护了,或许将有必要这样去做。但 1.0.2u 也已经是 2019 年发布的版本,换句话说,OpenSSL 1.0.2 在更早的时间就停止维护了。所以原文作者这样去做可能也没有什么意义。

该文作者的思路和实际操作都没有什么问题,尊重他人的劳动成果,我就不原样贴一遍了。需要的朋友可以根据上面的链接自己去看。虽然原文不知道为什么贴了 Markdown 的内容,在知乎上看不出样式,至少 PC Web 版上看不出,但内容总归能看懂。
我遇到的坑是:按照该文操作的「1.4」步骤得到的函数名称中有「@库名」的内容,例如:

sk_find@libcrypto.so.10;
sk_set@libcrypto.so.10;
asn1_add_error@libcrypto.so.10;
……

对于 Version Script,这是不可接受的写法。我的处理方法是把这里面的「@libcrypto.so.10」直接删掉了。原文假设所有的函数都是「@@」形式的默认导出,而不是「@」一个符号,这个假设是不对的。
这里是我从 CentOS7 中的 OpenSSL 1.0.2k 提取出来的 Version Script,既然 CentOS7 和 OpenSSL 1.0.2u 都已经停止维护,那这个文件应该算是 Stable 了。可以 点此下载。

把下载得到的 version.map 放在解压生成的 openssl-1.0.2u 目录下。随后,./config 的时候换成下面这句:

./config --prefix=/usr/local/openssl-1.0.2 --openssldir=/usr/local/openssl-1.0.2 shared -Wl,--version-script=/root/openssl-1.0.2u/version.map -Wl,-Bsymbolic-functions zlib-dynamic

最重要的参数就是 -Wl,--version-script=version.map 这句。再编译生成的 so 库就不会被报「no version information available」了。而且这里似乎必须得写绝对路径。

问题2

直接改文件名是不行的。因为文件里面有 SONAME。做符号链接以及 ldconfig 的时候都会原形毕露。我们需要把文件内部的 SONAME 也一起改掉才行。

据说在编译前手动调整一些文件也可以解决这个问题。不过我是选择在编译之后用 patchelf 来解决这个问题的。为此当然首先要安装 patchelf:

yum -y install patchelf

然后就开始改文件了:

patchelf --set-soname libssl.so.1.0.2u libssl.so.1.0.0
patchelf --set-soname libcrypto.so.1.0.2u libcrypto.so.1.0.0
mv libssl.so.1.0.0 libssl.so.1.0.2u
mv libcrypto.so.1.0.0 libcrypto.so.1.0.2u
patchelf --replace-needed libcrypto.so.1.0.0 libcrypto.so.1.0.2u libssl.so.1.0.2u

最后一句也是必须的,因为 libssl.so 会引用 libcrypto.so。

2024-07-27

「微软蓝屏事件」与「信创」

图片来自网络,与本文内容无关

「微软蓝屏事件」也已经过去一个多星期了。各方信息差不多到位了,讨论得也相对充分,应该不需要我再来分析或者补充什么了。

不过,这个事件发生之后,我遇到一种有意思的想法,可以与大家分享一下。

蓝屏幕席卷全球的时候,我正在旅游。连日记都只能在手机上简单记录一下要点的我,完美错过了这个事件的波峰。等我有空来了解的时候,整个事件基本已经有了结论,甚至都快平息了。我不知道这算我的幸运还是不幸。

当然,余波还是在的。等我周一回到公司,有同事就向我表示,「信创」的事情,可能要因此而加速。理由是这次中国在此次全球性事件中基本幸存,有赖于「脱钩」,那么接下来这个过程应该会更加地紧锣密鼓。

这自然是他自己的理解,不过也很有可能会是一个「正确」的预测。我们都知道所谓的「上头」其实也只是一届「草台班子」而已(实际上谁不是呢?)。他们的见识不见得比普通人高出多少。所以,按照常识,他们很可能也会这样去想,去思考,也就会真的这样去做。

问题是:中国这次的「幸存」,真的是因为「脱钩」吗?

跟许多人的理解可能不太一样,这次微软所谓的蓝屏事件,实际上跟微软没有什么关系。在我看来,这事就是一个装机量巨大的杀毒软件出了一个 Bug。由于在企业用户中装机量巨大,企业服务的客户也被影响到,于是闹出了这么大一个事端。微软还真是可怜,其实是它被别的软件给「搞」了。

可能现在活跃在网上的人都太年轻,也或者互联网真的是没记忆了。但我可是都还记得的。
我曾经写过一篇 Blog《突发的 c000021a 蓝屏故障》。2007 年,距今有一些年头,15 年有,但还不到 20 年。在我看来,那次的事件比起这一次,其实还更为严重一些。这次只是内核驱动层面出了问题而已。驱动嘛,开个安全模式就进去了。然后把文件夹改个名,让它正常启动时加载不了,就恢复了。2007 年那次可是把系统 DLL 文件直接给干掉了,相当于把操作系统删掉了一部分,安全模式都没用。单机只有哭。

我并不是太清楚现今的 CrowdStrike 与当年的 Symantec 哪个更牛逼。反正我现在不用什么杀毒软件或安全防护软件。「自己的安全自己负责」,很多年前我就学会了自己解决问题。普通人肯定没法照搬我的情况,这也是为什么 360 这种东西至今也还能大行其道的原因。
那么,说到这里,我的另一个大问题就要抛出来了:你为什么就能确定,360 之流不会闹出同样的问题呢?

在我看来,作为一个拿到了 ring0 权限的软件,要把系统搞蓝屏,那简直是举手之劳。能把你 Windows 搞蓝屏的内核驱动,我要不了几分钟就能写上一个。像 CrowdStrike 那样的情况,我们一般称之为「逻辑炸弹」,也不是什么多难的事情。无怪有很多人对此事归结于阴谋论。
我觉得这种逻辑炸弹恐怕还有很多,最好不要被什么歹人给拿到。但对此你无法打包票,所以还得要有自己的能力,以及要有备援才行。我上面说的那句话的扩大版,此时应该强调一下:自己的事情,只有自己来操心才靠谱,靠别人都是靠不住的。

况且,国内的软件企业就很靠谱吗?
这次很多人觉得很不可思议的一点是:CrowdStrike 既不好好测试,也不做灰度更新,直接全球推送,非常大胆,非常的不专业。有人发现,CrowdStrike 的创始人之一,之前在 McAfee 也闹出过类似的问题。这一点还真是,我也不知道如何吐槽。
CrowdStrike 是草台班子,这一点可能没错。但国内的软件企业,我可是更加不放心。

我曾经有个同事,脑子算是聪明。别人上大学的时候,他当兵去了。复员后也没受过什么系统性的专业训练,「怎么写代码」这件事情,都是自己琢磨的。其实从这一点就能看出来,人的确是挺聪明的。但他路子也挺野。若让他去研究技术问题,我认为或许会是一把好手,但不应该去做工程师。他写出来的代码,Bug 不少。
他有一种自创的加密文件格式,其中的加密算法基本上就是异或,关键是密钥是他自己的硬编码。这个东西用在了他当时给公司开发的产品中。后来他离职了,代码就交接给了我。「Bug 多」的印象,也就是这个时候留下的。
听别人说他去了某大城市发展。再后来,可能四五年后了,我在研究 360 的一款产品的时候,发现它们的漏洞库文件的 HEX 密文看上去很眼熟。于是我用那位同事留下的代码去试了一下,没想到真的一下子就解密成功了。
这……

所以,「脱钩」并不能保证不受影响。相反,闭门造车,低水平造轮子,还加上不用接受市场检验,由政府背书和「保送」,使得出现这种问题的机会,其实是增加了。
要问什么才是真正有效的手段,窃以为,增加多样性,增加市场竞争,算是一个。
所谓「信创」,不管背后的内容是什么,重点应该放在「创」字上。如果还是现在这种搞法,把重点放在「不被卡脖子」上,不可能解决这个问题,反而会恶化。

如果能创造出更多样的生态,有了更多的选择,就不会吊死在一棵树上。最理想的情况,每个软件都是不一样的,就不会因为一个弱点而全球瘫痪。
就像生物世界一样,每个人的 DNA 都是不一样的,没有什么病毒可以杀死 100% 的人类,总有人能幸存下来,然后把抗病毒的基因传播下去。

说到底,科学技术范畴的事情,就要遵循科学技术的发展规律,而不要想着去为自己的政权安全服务。出发点如果就「心术不正」,最后是结不出什么好果子的。