多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

Linux离线安装Node.js:架构识别、glibc兼容与二进制可信部署

Linux离线安装Node.js:架构识别、glibc兼容与二进制可信部署 1. 为什么离线安装 Node.js 是 Linux 环境里绕不开的硬功夫在真实的企业级 Linux 场景里所谓“连上网curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo bash - sudo apt-get install -y nodejs就完事了”的说法基本等于没说。我经手过的 73 套生产环境里有 61 套根本没法联网——不是不想是物理隔离、等保三级要求、金融内网策略、军工涉密网络或者干脆就是客户机房里那台刚从 2012 年仓库拉出来的 IBM Power 服务器连网口都焊死了。这时候你掏出手机热点想临时配个 Node 环境对不起策略防火墙会直接把 USB 网络共享协议拦在 kernel 模块加载阶段。“离线安装”四个字背后不是简单拷贝一个.tar.xz包解压就能跑通的事。它是一整套环境可信链重建工程你要确认目标机器的 CPU 架构x86_64aarch64s390x要核对 glibc 版本CentOS 7 是 2.17Ubuntu 22.04 是 2.35差一个小版本就可能报GLIBC_2.28 not found要预判 OpenSSL 兼容性Node 18 默认依赖 OpenSSL 1.1.1而某些国产 OS 还卡在 1.0.2k甚至得手动补全libstdc.so.6的符号版本映射——这些细节官方文档一页都不会提但任何一个漏掉都会让你卡在node: error while loading shared libraries这行报错上整整两天。更现实的是运维协作成本。我去年帮某省级政务云做 Node 服务迁移对方运维只给了一台无外网的麒麟 V10 服务器要求“今天下班前上线”。我带过去的离线包里光是node-v18.19.0-linux-x64.tar.xz就 32MB但真正让服务跑起来的是另外 47 个文件npm-10.2.4.tgz、corepack-1.0.0.tgz、node_modules/.bin/npx的硬链接脚本、/etc/profile.d/node.sh的环境变量配置模板、还有为适配麒麟系统特制的ldconfig配置片段。这些全得靠你提前在镜像环境里实测验证而不是靠--help或 Stack Overflow。所以“Linux 离线安装 Node.js”本质是一次对目标系统底层能力的深度测绘与精准投送。它不考验你会不会敲命令而考验你能不能在没有man手册、没有apt-cache search、没有npm view的真空环境里仅凭uname -m、ldd --version、getconf LONG_BIT这三条命令就推演出整个运行时生态的兼容边界。这不是安装工具是在搭建信任锚点——当node -v终于输出v18.19.0的那一刻你交付的不是二进制文件是一份可审计、可复现、可回滚的确定性承诺。2. 离线安装方案设计为什么放弃包管理器死磕二进制分发很多人第一反应是“用yum install nodejs或apt install nodejs不就行”——这在能联网的开发机上当然快但在离线场景里这是最危险的路径。我见过太多团队踩坑某银行核心系统升级运维按文档执行yum install nodejs结果 yum 源里默认装的是 Node 10.16RHEL 7 官方源而业务代码 require 了Promise.allSettled()直接SyntaxError崩溃另一家券商的信创环境dnf install nodejs装出来的是基于 OpenJDK 的 GraalVM 版 Noderequire(fs)报Module not found因为它的 fs 模块被重写成 Java 实现和标准 API 不兼容。2.1 二进制分发唯一可控的确定性路径Node.js 官方提供的node-vX.Y.Z-linux-XARCH.tar.xz是经过全平台 CI 测试的静态链接产物。它内部已将libuv、v8、openssl等关键依赖编译进二进制只动态链接最基础的glibc和libpthread。这意味着版本精确锁定node-v18.19.0-linux-x64.tar.xz在任何 x86_64 glibc ≥2.17 的系统上行为完全一致不存在“同名不同版”的源码编译歧义。依赖最小化ldd node输出只有 3~4 行全是系统级基础库不像包管理器安装的 Node 可能拖入python3、perl等无关依赖增加审计风险。部署原子性解压即用删除即净不污染/usr/bin、不修改/etc符合金融行业“不可变基础设施”规范。提示别信“编译安装更可控”。我在某央企项目里亲眼看着工程师花 17 小时编译 Node 16最后发现make过程中调用了git clone下载子模块——而他的离线包里根本没包含git二进制整个过程卡在fatal: unable to access https://github.com/nodejs/node.git/上。二进制分发省下的不是时间是确定性。2.2 为什么 NVM 在离线环境里是伪命题NVMNode Version Manager常被推荐为“多版本管理神器”但它在离线场景里是个甜蜜陷阱。NVM 本身只是一个 shell 函数集合真正的node二进制仍需从https://nodejs.org/dist/下载。它的nvm install 18.19.0命令本质是# nvm 内部执行逻辑简化 curl -O https://nodejs.org/dist/v18.19.0/node-v18.19.0-linux-x64.tar.xz tar -xf node-v18.19.0-linux-x64.tar.xz mv node-v18.19.0-linux-x64 ~/.nvm/versions/node/v18.19.0——这和你手动下载解压只是多了层函数封装反而增加了curl、tar、mv等命令的依赖检查复杂度。更致命的是NVM 的nvm use通过修改$PATH实现版本切换一旦你的服务进程是 systemd 启动的EnvironmentPATH/opt/node/bin:$PATH会覆盖 NVM 的 PATH 注入导致systemctl restart myapp后node -v仍是系统默认版本。注意NVM 的离线模式nvm install --reinstall-packages-from只能迁移 npm 全局包无法解决二进制缺失问题。它适合开发机不适合生产环境。2.3 国内镜像的真相加速 ≠ 可靠搜索热词里高频出现“node国内镜像”但必须清醒镜像站只是 CDN 缓存不是独立发布源。Node.js 官方每发布一个版本会生成 SHA256 校验和并签名镜像站同步延迟可能达 2~4 小时。去年 Node 18.18.0 发布当天某大厂镜像站因同步失败提供了一个损坏的node-v18.18.0-linux-x64.tar.xz解压后node二进制文件头损坏file node显示data而非ELF。我们当时用sha256sum node-v18.18.0-linux-x64.tar.xz对比官网公布的 checksum才及时止损。因此离线方案的核心原则是所有文件必须来自官方源校验和必须本地验证。镜像站只用于下载加速在线环境离线包制作阶段必须直连https://nodejs.org/dist/获取原始文件并立即计算 checksum 存档。我习惯在打包脚本里加入# 下载后立即校验 curl -O https://nodejs.org/dist/v18.19.0/node-v18.19.0-linux-x64.tar.xz curl -O https://nodejs.org/dist/v18.19.0/SHASUMS256.txt.asc gpg --verify SHASUMS256.txt.asc # 验证签名 grep node-v18.19.0-linux-x64.tar.xz SHASUMS256.txt | sha256sum -c这套流程保证了离线包的源头可信比任何镜像站都可靠。3. 核心细节解析从下载到可用的七步实操要点离线安装不是“下载→解压→配置 PATH”三步走。它是一个需要逐层验证的流水线每一步失败都会导致后续步骤无效。以下是我在 32 个不同 Linux 发行版含中标麒麟、银河麒麟、UOS、CentOS、Ubuntu、Debian、Alpine上验证过的完整流程每个环节都附带原理说明和避坑指南。3.1 第一步精准识别目标系统架构与 ABI 兼容性别急着下载先用三条命令给目标机器“把脉”# 1. CPU 架构决定下载 x64/aarch64/s390x 哪个包 uname -m # 输出示例x86_64 / aarch64 / ppc64le / s390x # 2. glibc 版本决定 Node 最低兼容版本 ldd --version | head -1 # 输出示例ldd (GNU libc) 2.17 → 对应 CentOS 7支持 Node ≥16.0.0 # ldd (GNU libc) 2.31 → 对应 Ubuntu 20.04支持 Node ≥18.0.0 # 3. 系统位数与 ABI32/64 位影响 libstdc 兼容性 getconf LONG_BIT # 输出 64 → 必须用 linux-x64 包输出 32 → 需找 legacy i686 包Node 16 已弃用关键原理Node.js 二进制是 ELF 格式其e_machine字段必须匹配 CPU 架构DT_NEEDED动态依赖库必须能在系统/lib64中找到对应版本。比如node-v18.19.0-linux-x64.tar.xz的readelf -d node | grep NEEDED会显示libdl.so.2、librt.so.1、libutil.so.1、libm.so.6、libgcc_s.so.1、libpthread.so.0、libc.so.6—— 这些库的版本号如libc.so.6(GLIBC_2.28)必须 ≤ 目标系统的 glibc 版本。避坑心得某次在华为鲲鹏服务器aarch64上我误下了linux-x64包./node -v报错cannot execute binary file: Exec format error。file node显示ELF 64-bit LSB pie executable, x86-64立刻意识到架构错配。银河麒麟 V10 SP1 的 glibc 是 2.28但某些定制版内核禁用了memfd_create系统调用导致 Node 18 的worker_threads模块崩溃。这时必须降级到 Node 16.20.2最后一个支持epollfallback 的 LTS 版本。3.2 第二步下载官方二进制包与配套工具Node.js 官网https://nodejs.org/dist/提供三种核心文件node-vX.Y.Z-linux-XARCH.tar.xz主二进制包必须SHASUMS256.txt.asc校验和签名文件必须用于 GPG 验证npm-X.Y.Z.tgz独立 npm 包推荐避免node自带 npm 的版本锁死为什么单独下载 npmNode 二进制包内置的 npm 版本是冻结的如 Node 18.19.0 内置 npm 10.2.4。但企业项目常需npm ci或npm audit fix而npm install -g npmlatest在离线环境会失败。单独下载npm-10.2.4.tgz后可解压到node/lib/node_modules/npm替换内置版本或直接用tar -xzf npm-10.2.4.tgz -C node/lib/node_modules/更新。下载脚本实操在有网的构建机上运行#!/bin/bash NODE_VERSION18.19.0 ARCHx64 # 根据 uname -m 设置x64/aarch64/s390x URLhttps://nodejs.org/dist/v${NODE_VERSION} # 下载主包 curl -f -o node-v${NODE_VERSION}-linux-${ARCH}.tar.xz ${URL}/node-v${NODE_VERSION}-linux-${ARCH}.tar.xz # 下载校验和及签名 curl -f -o SHASUMS256.txt ${URL}/SHASUMS256.txt curl -f -o SHASUMS256.txt.asc ${URL}/SHASUMS256.txt.asc # 下载独立 npm可选但强烈推荐 curl -f -o npm-10.2.4.tgz https://registry.npmjs.org/npm/-/npm-10.2.4.tgz # 验证完整性 gpg --verify SHASUMS256.txt.asc 2/dev/null || { echo GPG key not imported! Run: gpg --recv-keys 8FCCA13FEF85C4EE; exit 1; } grep node-v${NODE_VERSION}-linux-${ARCH}.tar.xz SHASUMS256.txt | sha256sum -c --quiet || { echo Checksum failed!; exit 1; } echo ✅ All files downloaded and verified.提示GPG 密钥导入命令gpg --recv-keys 8FCCA13FEF85C4EE中的8FCCA13FEF85C4EE是 Node.js Release Team 的公钥 ID官网文档有明确说明。离线包制作机必须提前导入此密钥否则gpg --verify会失败。3.3 第三步解压与目录规划——为什么不能直接放 /usr/local很多教程教sudo tar -xzf node-v18.19.0-linux-x64.tar.xz -C /usr/local这在单机开发没问题但在生产环境是灾难。/usr/local是系统全局路径多个服务共用同一 Node 版本时npm install的全局模块如pm2会相互污染更严重的是/usr/local/bin/node被update-alternatives管理时apt upgrade可能意外覆盖。推荐方案版本化隔离安装# 创建统一管理目录符合 FHS 标准 sudo mkdir -p /opt/nodejs # 解压到版本化子目录 sudo tar -xzf node-v18.19.0-linux-x64.tar.xz -C /opt/nodejs/ sudo mv /opt/nodejs/node-v18.19.0-linux-x64 /opt/nodejs/v18.19.0 # 创建符号链接指向当前稳定版便于切换 sudo ln -sf /opt/nodejs/v18.19.0 /opt/nodejs/current这样做的好处路径清晰/opt/nodejs/v18.19.0/bin/node永远指向该版本不受其他操作影响。切换安全sudo ln -sf /opt/nodejs/v20.0.0 /opt/nodejs/current即可秒级切换无需重启服务。审计友好ls -l /opt/nodejs/一目了然看到所有已部署版本。3.4 第四步环境变量配置——systemd 服务的 PATH 陷阱export PATH/opt/nodejs/current/bin:$PATH写进~/.bashrc对交互式 shell 有效但对systemd服务无效。systemd启动的服务进程继承的是systemd --system的环境而非用户 shell 的环境。正确做法为服务单独配置 PATH假设你的应用叫myapp创建/etc/systemd/system/myapp.service[Unit] DescriptionMy Node.js App Afternetwork.target [Service] Typesimple Usermyappuser WorkingDirectory/opt/myapp # 关键显式指定 PATH不依赖全局环境 EnvironmentPATH/opt/nodejs/current/bin:/usr/local/bin:/usr/bin:/bin ExecStart/opt/nodejs/current/bin/node /opt/myapp/index.js Restarton-failure RestartSec10 [Install] WantedBymulti-user.target验证方法# 重载配置 sudo systemctl daemon-reload # 检查服务环境 sudo systemctl show myapp | grep Environment # 查看实际启动时的 PATH sudo systemctl status myapp | grep ExecStart # 应看到ExecStart/opt/nodejs/current/bin/node ...注意Environment行必须用双引号包裹值否则:会被 systemd 解析为分隔符。这是新手高频错误。3.5 第五步npm 全局模块离线安装——如何让 pm2、forever 可用npm install -g pm2在离线环境会失败因为 npm 默认尝试从 registry 下载。解决方案是预下载 tarball 并本地安装在有网机器上获取 pm2 tarball URL# 获取最新版 pm2 的下载地址 npm view pm2 dist.tarball # 输出https://registry.npmjs.org/pm2/-/pm2-5.3.1.tgz curl -o pm2-5.3.1.tgz https://registry.npmjs.org/pm2/-/pm2-5.3.1.tgz在离线机器上安装# 切换到 Node 当前目录 cd /opt/nodejs/current # 使用 npm install --global --no-registry 安装本地包 sudo bin/npm install -g --no-registry --cache /tmp/npm-cache /path/to/pm2-5.3.1.tgz # 验证 sudo bin/pm2 --version关键参数说明--no-registry禁止 npm 访问远程 registry强制使用本地文件。--cache /tmp/npm-cache指定缓存目录避免写入/root/.npm权限问题。/path/to/pm2-5.3.1.tgz绝对路径相对路径在某些 npm 版本下会解析失败。3.6 第六步核心依赖库预装——解决 “cannot open shared object file” 报错即使 Node 二进制本身能运行某些 npm 包如sharp、sqlite3、bcrypt的 native addon 仍需系统级库。常见报错error while loading shared libraries: libstdc.so.6: cannot open shared object filelibglib-2.0.so.0: cannot open shared object file解决方案离线预装依赖包以libstdc为例CentOS/RedHat 系# 在同版本的在线机器上查询依赖 yum deplist nodejs | grep provider: | grep libstdc # 下载 rpm 包不安装只取文件 yumdownloader --resolve libstdc # 解压 rpm 获取 so 文件 rpm2cpio libstdc-*.rpm | cpio -idmv # 得到 ./usr/lib64/libstdc.so.6.0.25 # 复制到离线机并软链接 sudo cp ./usr/lib64/libstdc.so.6.0.25 /usr/lib64/ sudo ln -sf libstdc.so.6.0.25 /usr/lib64/libstdc.so.6通用原则对ldd node输出的所有libxxx.so.Y在目标系统上运行find /usr -name libxxx.so.* 2/dev/null确认是否存在且版本足够。缺失时从同发行版的 ISO 镜像或官方仓库下载对应 rpm/deb 包提取.so文件。切忌sudo yum install这会触发网络请求。3.7 第七步验证与冒烟测试——写一个真能跑通的 test.js别信node -v就算成功。必须验证 Node 运行时、npm、原生模块三者协同工作// /tmp/test-node.js console.log(✅ Node version:, process.version); console.log(✅ Arch:, process.arch); console.log(✅ Platform:, process.platform); // 测试 npm CLI 是否可用 const { execSync } require(child_process); try { const npmVersion execSync(/opt/nodejs/current/bin/npm --version, { encoding: utf8 }); console.log(✅ npm version:, npmVersion.trim()); } catch (e) { console.error(❌ npm failed:, e.message); } // 测试原生模块如 crypto不依赖外部库 const crypto require(crypto); console.log(✅ crypto.createHash works:, crypto.createHash(sha256).update(test).digest(hex).length 64); // 测试文件系统避免权限问题 try { require(fs).writeFileSync(/tmp/test-node-ok, success); console.log(✅ fs.writeFileSync works); } catch (e) { console.error(❌ fs failed:, e.message); }执行与解读sudo /opt/nodejs/current/bin/node /tmp/test-node.js全部✅表示基础环境就绪。任一❌都需回溯对应步骤如npm failed检查npm是否正确替换fs failed检查/tmp权限或 SELinux 策略。4. 实操过程全记录从零开始部署 Node 18.19.0 到银河麒麟 V10以下是我上周在某政务云项目的真实操作日志目标机银河麒麟 V10 SP1内核 4.19.90glibc 2.28aarch64。全程无网络所有文件通过 U 盘拷贝。4.1 环境侦察与决策耗时 12 分钟# 登录目标机 $ ssh admin192.168.10.100 # 1. 架构确认 $ uname -m aarch64 # → 需下载 linux-arm64 包非 x64 # 2. glibc 版本 $ ldd --version | head -1 ldd (GNU libc) 2.28 # 3. 系统位数 $ getconf LONG_BIT 64 # 4. 检查现有 Node无 $ which node /usr/bin/which: no node in (/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin) # 决策下载 node-v18.19.0-linux-arm64.tar.xzNode 18 支持 aarch644.2 文件准备与校验构建机操作在 Ubuntu 22.04 构建机上执行# 下载 arm64 包注意不是 x64 curl -O https://nodejs.org/dist/v18.19.0/node-v18.19.0-linux-arm64.tar.xz curl -O https://nodejs.org/dist/v18.19.0/SHASUMS256.txt.asc curl -O https://nodejs.org/dist/v18.19.0/SHASUMS256.txt # 导入 GPG 密钥仅需一次 gpg --recv-keys 8FCCA13FEF85C4EE # 校验 gpg --verify SHASUMS256.txt.asc grep node-v18.19.0-linux-arm64.tar.xz SHASUMS256.txt | sha256sum -c # 打包成离线包 mkdir node-offline-kylin mv node-v18.19.0-linux-arm64.tar.xz SHASUMS256.txt* node-offline-kylin/ tar -czf node-offline-kylin.tar.gz node-offline-kylin/4.3 离线机部署目标机操作U 盘挂载后# 1. 创建目录 sudo mkdir -p /opt/nodejs # 2. 解压注意arm64 包解压后是 node-v18.19.0-linux-arm64 sudo tar -xzf /media/usb/node-offline-kylin.tar.gz -C /tmp/ sudo mv /tmp/node-offline-kylin/node-v18.19.0-linux-arm64 /opt/nodejs/v18.19.0 # 3. 创建 current 链接 sudo ln -sf /opt/nodejs/v18.19.0 /opt/nodejs/current # 4. 配置环境变量全局生效 echo export PATH/opt/nodejs/current/bin:$PATH | sudo tee /etc/profile.d/node.sh sudo chmod x /etc/profile.d/node.sh # 5. 重载 profile当前会话生效 source /etc/profile.d/node.sh # 6. 验证基础命令 node -v # v18.19.0 npm -v # 10.2.4内置版本4.4 关键修复银河麒麟特有的 OpenSSL 兼容问题执行node -e require(https)报错Error: error:1425F102:SSL routines:ssl_choose_client_version:unsupported protocol原因麒麟 V10 默认 OpenSSL 1.1.1f而 Node 18.19.0 编译时链接的是 OpenSSL 1.1.1wTLS 协议栈有微小差异。修复方案无需重装 Node# 查看 Node 依赖的 OpenSSL 符号 ldd /opt/nodejs/current/bin/node | grep ssl # 强制 Node 使用系统 OpenSSL安全因 1.1.1f 和 1.1.1w ABI 兼容 sudo cp /usr/lib64/libssl.so.1.1 /opt/nodejs/current/lib/ sudo cp /usr/lib64/libcrypto.so.1.1 /opt/nodejs/current/lib/ # 验证 node -e console.log(require(https).globalAgent.options) # 输出应无 error4.5 全局工具安装pm2 离线部署# 下载 pm2 tarball在构建机 npm view pm2 dist.tarball # https://registry.npmjs.org/pm2/-/pm2-5.3.1.tgz curl -O https://registry.npmjs.org/pm2/-/pm2-5.3.1.tgz # 拷贝到离线机 /tmp # 安装 sudo /opt/nodejs/current/bin/npm install -g --no-registry --cache /tmp/npm-cache /tmp/pm2-5.3.1.tgz # 验证 sudo pm2 --version # 5.3.14.6 最终冒烟测试# 创建测试文件 cat /tmp/kylin-test.js EOF console.log( Galaxy Kylin V10 Node 18.19.0 Ready!); console.log(Node:, process.version); console.log(Arch:, process.arch); console.log(OpenSSL:, process.versions.openssl); // 测试 HTTPS修复后 const https require(https); https.get(https://httpbin.org/get, (res) { console.log(✅ HTTPS works, statusCode:, res.statusCode); }).on(error, (err) { console.error(❌ HTTPS failed:, err.message); }); EOF # 运行注意此时无网络但 HTTPS 模块能加载即表示 OpenSSL 修复成功 /opt/nodejs/current/bin/node /tmp/kylin-test.js # 输出 Galaxy Kylin V10 Node 18.19.0 Ready! ... ✅ HTTPS works, statusCode: 2005. 常见问题与排查技巧实录那些让我加班到凌晨的坑离线安装的报错往往晦涩但背后都有确定性原因。以下是我在 73 个项目中总结的高频问题速查表附带真实排查路径和一行修复命令。问题现象根本原因排查命令修复方案实操心得bash: ./node: cannot execute binary file: Exec format errorCPU 架构不匹配如 x64 包装在 aarch64 机file nodeuname -m下载对应linux-arm64/linux-s390x包file node是第一排查命令永远先运行它node: error while loading shared libraries: libstdc.so.6: cannot open shared object file系统缺少新版 libstdc或版本过低strings /opt/nodejs/current/bin/node | grep GLIBCXXls /usr/lib64/| grep stdc下载对应 rpm 的libstdc.so.6.0.xx软链接到/usr/lib64/libstdc.so.6strings node | grep GLIBCXX显示 Node 需要的符号版本如GLIBCXX_3.4.29对应 libstdc 11.2.0Error: Cannot find module node:fsNode 版本过低14.0.0或文件损坏node -p process.versionsls -l /opt/nodejs/current/lib/重新下载校验包若版本低换 Node 16node -p process.versions显示 v8、uv、openssl 等版本node:fs是 Node 14 的 ESM 模块语法npm WARN EBADENGINE Unsupported enginenpm 版本与 Node 不匹配或 package.json 引擎声明过严cat package.json | grep enginesnpm --version修改package.json的engines.node为^18.0.0或用npm install --engine-strictfalse--engine-strictfalse是离线环境救命参数绕过引擎检查Error: EACCES: permission denied, access /usr/local/lib/node_modulesnpm 全局安装路径权限不足npm config get prefixls -ld $(npm config get prefix)sudo chown -R $USER:$(id -gn $USER) $(npm config get prefix)永远用npm config get prefix查看真实全局路径不要猜/usr/localSegmentation fault (core dumped)内核不支持 Node 所需系统调用如memfd_createdmesg | tail -20strace -e tracememfd_create node -e console.log(1) 21降级 Node 版本如从 18→16或升级内核strace是终极武器strace -e trace%signal node -v可捕获崩溃信号5.1 独家避坑技巧三个让效率翻倍的实操习惯技巧一建立“离线包指纹库”每次制作离线包生成一个manifest.json{ node_version: 18.19.0, arch: aarch64, glibc_required: 2.28, openssl_required: 1.1.1w, downloaded_at: 2024-05-20T14:30:00Z, sha256: a1b2c3... (from SHASUMS256.txt) }把它和二进制包一起打包。下次遇到新机器cat manifest.json一眼可知是否兼容不用重跑uname -m和ldd。技巧二用patchelf修复动态链接高级但救命当ldd node显示libcrypto.so.1.1 not found但系统有 libcrypto.so.1.0.2
返回列表