UniVPN 打包的问题※
0x01 序※
公司之前用华为的secoclient VPN,虽然AUR有一个secoclient 但是已经不能用了,也没人维护。
本来我想接手的,但找安装包发现官方已经不提供下载了,全网搜索也只找到一个7.0.2.26的旧版。
千辛万苦装上之后发现可能是动态库老旧的问题,我现在的环境已经不能使用了,还要去找老的动态库。
这一点也不Arch。
回到华为官方论坛,有这样一个提示:
VPN Client Download
The SecoClient for firewalls and VPN gateways has stopped evolution and cannot be downloaded from Support website. The downloaded SecoClient can still be used. Uni VPN Client, a new-generation client jointly developed by Leagsoft and Huawei, is available for use. You can click the link to download the Uni VPN Client.
华为的SecoClient已经停止支持,新一代的UniVPN也可以使用。想要一劳永逸,装新的!
0x02 安装UniVPN※
下载官方安装包,官网下载还要填写信息,还好不需要登录。
解压安装包,里面是run文件,review发现是自解压文件。直接root运行就安装了
但有一个问题:
univpn-linux-64-10781.18.1.0512.run: 行 20: arch: 未找到命令
Only support 64 bit, Please download 32 bit installation package!
```
问题1:arch 命令未找到※
看上去是由于没有找到arch指令,不能判断是64位架构而导致安装终止。
这个问题其实是发行版的问题,简单来说在一些发行版(如Ununtu)中arch
指令是 coreutils
软件包的一个程序,本质就是uname -m
。
arch没有安装这个,所以没有arch指令。uname -m
和arch
指令是等效的。
解决办法显然就是用uname -m
替代arch
。
sed -i 's/ARCH="`arch`"/ARCH="`uname -m`"/g' "univpn-linux-64-${pkgver}.run"
问题2:Qt库版本冲突※
错误现象:
sa@home:~/code$ sudo univpn
QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-root'
GetAbsoluteDir "/usr/local/UniVPN/" "阿里巴巴普惠体,12,-1,5,50,0,0,0,0,0"
QMetaObject::connectSlotsByName: No matching signal for on_pb_ProxySetting_clicked()
Cannot mix incompatible Qt library (5.15.3) with this library (5.15.17)
已中止
初步分析:
- UniVPN 使用 Qt 5.15.3 编译
- 系统安装的是 Qt 5.15.17
- 版本不匹配导致程序崩溃
检查依赖库:
发现 UniVPN 自带完整的 Qt 库:
$ ls -la /usr/local/UniVPN/lib/
libQt5Core.so.5
libQt5Gui.so.5
libQt5Network.so.5
libQt5Widgets.so.5
# ... 其他库
解决方案:
设置库路径使用自带的Qt库 export LD_LIBRARY_PATH="/usr/local/UniVPN/lib:$LD_LIBRARY_PATH"
将/usr/bin/univpn
替换为如下脚本,以在启动时为程序指定动态链接库的位置。注意可执行权限。
#!/bin/bash
# UniVPN 启动脚本 - 设置库路径以使用自带的Qt库
export LD_LIBRARY_PATH="/usr/local/UniVPN/lib:$LD_LIBRARY_PATH"
cd /usr/local/UniVPN
exec ./UniVPN "$@"
LD_LIBRARY_PATH
是 Linux 系统中一个重要的环境变量,用于指定动态链接器(dynamic linker)在加载共享库(.so 文件)时的额外搜索路径。作用原理:
当你运行一个依赖共享库的程序时,系统的动态链接器(通常是/lib/ld-linux.so
或/lib64/ld-linux-x86-64.so
)需要找到程序所需的共享库(如libc.so
、libssl.so
等)。
默认情况下,链接器只会搜索系统预设的路径(如/lib
、/usr/lib
、/usr/local/lib
等,这些路径在/etc/ld.so.conf
或/etc/ld.so.conf.d/
中定义)。而LD_LIBRARY_PATH
允许你临时添加额外的搜索路径,让链接器优先在这些路径中查找共享库。典型用途:
测试未安装的共享库
如果你编译了一个自定义的共享库(如libmylib.so
),但尚未安装到系统默认路径(如仍在/home/yourname/dev/lib
目录下),可以通过LD_LIBRARY_PATH
让程序临时加载它:LD_LIBRARY_PATH=/home/yourname/dev/lib ./myprogram
解决「找不到共享库」的错误
当运行程序时出现类似error while loading shared libraries: libxxx.so: cannot open shared object file: No such file or directory
的错误,说明链接器找不到所需库。若库已存在于非默认路径,可通过LD_LIBRARY_PATH
临时指定:LD_LIBRARY_PATH=/path/to/missing/library ./myprogram
使用特定版本的库覆盖系统默认库
若需要让程序使用某个特定版本的库(而非系统默认版本),可通过LD_LIBRARY_PATH
指定该版本库的路径,链接器会优先加载该路径下的库。
打包上传AUR,现在可以直接从AUR安装UniVPN。
0x03 技术总结※
1. 自解压脚本分析
- 理解
.run
文件结构 - 定位二进制数据分界点
- 正确提取压缩包内容
2. 库依赖管理
- 识别程序自带的依赖库
- 使用 LD_LIBRARY_PATH
优先指定库路径
- 避免系统库版本冲突
0x04 经验建议※
1. 充分测试
- 不要仅仅构建成功就认为没问题
- 要实际运行程序验证功能
2. 理解上游软件
- 深入了解软件的打包方式
- 不要盲目照搬安装脚本
3. 考虑系统差异
- 不同发行版可能缺少某些命令
- 库版本可能存在差异
0x05 跋 ※
通过这次问题修复,我们不仅解决了 UniVPN 在 Arch Linux 上的运行问题,更重要的是积累了处理复杂软件包问题的经验。正确的分析方法、系统的排查思路和完善的解决方案,是处理此类问题的关键。
最终的修复方案现已提交到 AUR,用户可以通过 paru -S univpn
或 yay -S univpn
安装使用。