TiDB修改版本号

本文记录的是修改tidb数据库版本号信息,由于本文涉及知识点不多,没有技术含量,请谨慎按需阅读。

起因

近来似乎流行国产化适配,上半年做的一个项目,原先是用mysql的,经历过从5.7升级到8.0,经历过不同版本数据不兼容的痛苦阶段。后来上峰一声令下,要切换到国产数据库。考虑到项目中需用mysql的是一个java写的低代码平台微服务,考虑到团队开发人员的技术栈,考虑到时效,考虑到切换平滑,在多重考虑后,在一段时间选型后,决定使用TiDB,当时有文章记录了TiDB的编译部署。不久前,负责安全的团队发来报告,说扫描出重大漏洞,一项是tomcat的,另一项是数据库的。编号达20多个:

CVE-2023-21912、CVE-2019-3822、CVE-2022-37434、CVE-2021-3711、CVE-2021-22926、CVE-2019-5443、CVE-2019-5482、CVE-2022-43551、CVE-2021-22946、CVE-2022-27778、CVE-2021-2144、CVE-2019-2632、CVE-2023-21980、CVE-2021-22946、CVE-2021-22945、CVE-2021-22901、CVE-2019-17543、CVE-2023-0215、CVE-2022-32221、CVE-2020-1967、CVE-2022-1292、CVE-2022-0778

不管哪一个,都指向了mysql/5.7.25

报告还给出了官方修复的链接:

https://www.oracle.com/security-alerts/cpuapr2023.html
https://www.oracle.com/security-alerts/cpuapr2022.html
https://www.oracle.com/security-alerts/cpuapr2021.html
https://www.oracle.com/security-alerts/cpuapr2020.html
https://www.oracle.com/security-alerts/cpuapr2019.html

好家伙,我家大妞从没生出到会背“床前明月光”的年份都有,不管哪一个年份列表,都没法做到,因为TiDB虽然高度兼容MySQL,但毕竟不是MySQL。正如说“当作自己人”,就很明显地说明了“不是自己人”。

但不管如何,出了问题总是要解决,想办法解决,克服困难解决,别人不懂的要自己上场解决。

排查及解决

开始解决

首先,在网上搜索,找到TiDB社区相关的帖子,这一个是帖子另一个也是帖子。里面提到修改版本号的方案。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Oo7oxFxo-1691135417973)(2023-08-03-tidb修改版本号/image-20230804152153334.png)]

但里面说的是有集群的情况,无法直接使用该方案。但TiDB是开源的,当时也是自己亲自编译的,于是决定看源码,下文就是通过修改源码或配置文件达到修改版本号的目的。

问题定位

注意看,漏洞扫描报告里提到的MySQL版本是5.7.25。使用mysql命令连接TiDB数据库,会先显示版本号信息:

$ mysql -uroot -h 127.0.0.1 -P4000
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 405
Server version: 5.7.25-TiDB- TiDB Server (Apache License 2.0) Community Edition, MySQL 5.7 compatible

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

TiDB版本号信息是这一行Server version: 5.7.25-TiDB- TiDB Server (Apache License 2.0) Community Edition, MySQL 5.7 compatible,除了没有TiDB版本号外,其它的都具备了。

扫描二维码关注公众号,回复: 16973091 查看本文章

既然5.7.25那么重要,直接在源码工程搜索,果然发现了端倪。

修改字样 5.7.25-TiDB-

parser\mysql\const.go 文件中,相关代码片段如下:

// parser\mysql\const.go 
// Version information.
var (
	// TiDBReleaseVersion is initialized by (git describe --tags) in Makefile.
	TiDBReleaseVersion = "None"

	// ServerVersion is the version information of this tidb-server in MySQL's format.
	ServerVersion = fmt.Sprintf("5.7.25-TiDB-%s", TiDBReleaseVersion)
)

ServerVersion由固定前缀5.7.25-TiDB-TiDBReleaseVersion组成。

继续分析,在config\config.go有相关版本号的定义,如下:

// config\config.go
ServerVersion      string `toml:"server-version" json:"server-version"`
VersionComment     string `toml:"version-comment" json:"version-comment"`
TiDBEdition        string `toml:"tidb-edition" json:"tidb-edition"`
TiDBReleaseVersion string `toml:"tidb-release-version" json:"tidb-release-version"`

这些字段均属于Config结构体,里面的字段即是命令行--config指定的配置文件中的字段。其中,TiDBReleaseVersion表示TiDB发布的版本号,ServerVersion表示整体的版本号,如字段不为空(默认为空_),则用其值代替。

因此直接在配置文件tidb.toml中添加如下版本号字段:

server-version = "7.1.1"

#tidb-release-version = "7.1.1"

# TiDB server host.
。。。

运行数据库:

./bin/tidb-server --config tidb.toml 

在另一终端使用mysql连接,信息如下:

$ mysql -uroot -h 127.0.0.1 -P4000
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 403
Server version: 7.1.1 TiDB Server (Apache License 2.0) Community Edition, MySQL 5.7 compatible

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

然而,版本信息那一行依然有MySQL 5.7 compatible字样。这时就要真的动源码了。

删除字样MySQL 5.7 compatible

搜索关键字, MySQL 5.7 compatible,在tidb-server\main.gosessionctx\variable\sysvar.go文件中都有相关字符串,为安全起见,均删除掉。

// tidb-server\main.go setGlobalVars函数 
if len(cfg.TiDBEdition) > 0 {
		versioninfo.TiDBEdition = cfg.TiDBEdition
		variable.SetSysVar(variable.VersionComment, "TiDB Server (Apache License 2.0) "+versioninfo.TiDBEdition+" Edition, MySQL 5.7 compatible")
	}

// sessionctx\variable\sysvar.go  defaultSysVars 数组
{Scope: ScopeNone, Name: VersionComment, Value: "TiDB Server (Apache License 2.0) " + versioninfo.TiDBEdition + " Edition, MySQL 5.7 compatible"},

在联网情况下,在安装go情况下,在工程目录中输入make即可。注意,1.18版本无法编译,提示undefined: atomic.Bool,本文使用1.20能正常编译。

测试

运行数据库:

./bin/tidb-server --config tidb.toml 

在另一终端使用mysql连接,信息如下:

$ mysql -uroot -h 127.0.0.1 -P4000
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 403
Server version: 7.1.1 TiDB Server (Apache License 2.0) Community Edition

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

此时,可以看到版本号信息已经达到预期效果了。

其它说明

值得一提的是,更新TiDB源码,不影响数据目录,笔者使用的docker部署,数据目录做了持久化挂载,能快速适用于不同的机器。就当前阶段,已经有2台国产化ARM服务器在使用了,即使在一台x86平台的服务器,笔者也是运行ARM版本TiDB。

另外,本文针对的是版本号的修改和验证。TiDB的root账户默认没有密码,端口默认为4000。

小结

本文记录了从发现问题,思索问题,定位问题,到解决问题的过程,期间看了源码,编了源码,换了go编译器。是不是真的能解决所谓的漏洞,还要等待一段时间才知晓。

猜你喜欢

转载自blog.csdn.net/subfate/article/details/132106307