OpenSSH 介绍及使用Lycium框架移植到鸿蒙 PC(OpenHarmony)平台的实践总结

本文基于在 tpc_c_cplusplus + Lycium 下将 OpenSSH 9.9p2 适配到 OpenHarmony 的实践。详细介绍了如何使用 Lycium(OpenHarmony 社区的三方库移植框架)这个三方库及命令行移植框架移植著名的OpenSSH开源工具。

相关资源地址:

开源鸿蒙通用三方库社区地址:https://gitcode.com/oh-tpc

tpc_c_cplusplus框架介绍地址:https://gitcode.com/openharmony-sig/tpc_c_cplusplus

lycium_plusplus框架地址:https://gitcode.com/OpenHarmonyPCDeveloper/lycium_plusplus

OpenHarmony PC Developer 社区:https://gitcode.com/OpenHarmonyPCDeveloper

构建成功截图:


构建产物

二进制可执行文件ssh、sftp、ssh-keygen、scp等。

一、OpenSSH 是什么

OpenSSH (Open Secure Shell)是 SSH 协议 的主流开源实现,由 OpenBSD 项目维护的 Portable OpenSSH 可在 Linux、BSD、macOS 等多种 Unix 类系统上编译运行。其核心组件包括:

组件 作用
ssh SSH 客户端,远程登录、端口转发等
sshd SSH 服务端守护进程
scp / sftp 基于 SSH 的安全文件传输
ssh-keygen / ssh-agent 密钥管理与辅助工具

协议层面提供加密信道、主机密钥校验、用户认证(密码、公钥等),广泛用于远程运维与加密传输。

openSSH的github仓https://github.com/openssh/openssh-portable

openSSH主页地址https://www.openssh.org/

鸿蒙 PC / OpenHarmony 场景下,通常通过 Lycium 等交叉编译框架,把 portable OpenSSH 编成 armeabi-v7a / arm64-v8a 等 ABI 的可执行文件,再集成到系统或用于设备侧验证;若应用仅需 SSH 协议库 ,也可优先考虑 libssh2 等库形态方案。

Lycium框架是什么?

它是一个专门为OpenHarmony打造的"自动代工厂"。

在没有这类框架时,你要移植一个开源软件(如 OpenSSH),需要自己手动改环境变量、写 ./configure 参数、处理依赖库路径,非常痛苦且容易出错。Lycium 把这些流程标准化了。

当你执行 Lycium 的编译命令时,它在后台帮你跑了这几件事:

  1. 环境初始化:自动把鸿蒙 SDK 里的编译器(如 clang)、链接器(如 ld)配置好。
  2. 依赖管理:如果你编译 OpenSSH 依赖 OpenSSL,Lycium 会先检查 OpenSSL 编好没,没编好就先跳过去编 OpenSSL。
  3. 路径转换:它会自动处理 --host=arm64-linux-ohos 等复杂的交叉编译参数。
  4. 产物收集:编译完后,它把 .so 和执行文件统一收集到一个目录下(比如你看到的 $LYCIUM_ROOT/usr),方便你直接拷贝到板子上。

Lycium框架地址: https://gitcode.com/OpenHarmonyPCDeveloper/lycium_plusplus


二、鸿蒙 PC 侧移植的总体思路

  1. 源码 :使用官方 Portable 压缩包(如 openssh-9.9p2.tar.gz),与 SHA512SUM 校验配套。
  2. 依赖 :OpenSSH 依赖 OpenSSL(libcrypto 等)zlib ,须先于 OpenSSH 在 Lycium 中安装到约定前缀(如 lycium/usr/openssl/<ARCH>lycium/usr/zlib/<ARCH>)。
  3. 工具链 :使用 OHOS NDK 中的 aarch64-linux-ohos-clangarm-linux-ohos-clang 等,由 Lycium 的 envset.sh 注入 CC、CFLAGS、LDFLAGS 等。
  4. 配置 :使用 Autoconf ./configure ,而不是误走 CMake 分支;--host 使用与 musl 一致的三元组(如 aarch64-linux-muslarm-linux-musleabihf),并显式 --with-ssl-dir / --with-zlib
  5. 安装 :交叉环境常用 make install-nosysconf ,避免在构建机创建 ssh 系统用户或写 /etc/ssh
  6. 验证 :构建产物以 可执行文件 为主;可在真机/模拟器上用 hdc 推送后执行 ssh -V 等做冒烟验证;Lycium 侧用 HPKCHECK 做产物存在性检查。

三、在 tpc_c_cplusplus + Lycium 中的目录与脚本职责

典型目录结构示例:

text 复制代码
thirdparty/openssh/
├── HPKBUILD          # 下载、解压、configure、make、install 逻辑
├── HPKCHECK          # 设备/CI 侧检查(如二进制是否存在)
├── SHA512SUM         # 源码包 SHA512 校验
├── README.md / README_zh.md
├── README.OpenSource # 开源说明 JSON
└── docs/
    ├── hap_integrate.md
    └── porting_openssh_ohos.md  # 本文

3.1 HPKBUILD 编写

完整构建脚本如下:

bash 复制代码
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Contributor: csdn猫哥 <534117529@qq.com>
# Maintainer: csdn猫哥 <534117529@qq.com>

pkgname=openssh
pkgver=9.9p2
pkgrel=0
pkgdesc="OpenSSH is the premier connectivity tool for remote login with the SSH protocol."
url="https://openssh.com"
archs=("armeabi-v7a" "arm64-v8a")
license=("BSD-style")
depends=("openssl" "zlib")
makedepends=()

# 修正为官方 CDN 压缩包路径
source="https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-9.9p2.tar.gz"

downloadpackage=true   # 启用下载
autounpack=true        # 启用自动解压
builddir=openssh-$pkgver
packagename=openssh-$pkgver.tar.gz

patchflag=false
cloneFlag=false        # 使用压缩包,不再需要 git clone

buildtools="configure"

source envset.sh
host=

prepare() {
    if [ $ARCH == "armeabi-v7a" ]
    then
        setarm32ENV
        # 与 OHOS(musl) 一致的三元组,避免按 glibc 探测;config.sub 可识别 *-linux-musl*
        host=arm-linux-musleabihf
    elif [ $ARCH == "arm64-v8a" ]
    then
        setarm64ENV
        host=aarch64-linux-musl
    else
        echo "${ARCH} not support"
        return -1
    fi

    cd $builddir
    if [ ! -f "configure" ]; then
        autoreconf -vif >> $publicbuildlog 2>&1
    fi
    cd $OLDPWD
    mkdir -p $builddir/$ARCH-build
}

build() {
    cd $builddir/$ARCH-build || return 1

    zroot=$LYCIUM_ROOT/usr/zlib/$ARCH
    sslroot=$LYCIUM_ROOT/usr/openssl/$ARCH

    ssl_ldflags="-L${sslroot}/lib"
    if [ -d "${sslroot}/lib64" ]; then
        ssl_ldflags="$ssl_ldflags -L${sslroot}/lib64"
    fi

    PKG_CONFIG_LIBDIR="${pkgconfigpath}" \
    CPPFLAGS="-DOPENSSL_API_COMPAT=0x10100000L $CPPFLAGS -I${sslroot}/include -I${zroot}/include" \
    LDFLAGS="$LDFLAGS $ssl_ldflags -L${zroot}/lib" \
    LIBS="-lcrypto -lz $LIBS" \
    CFLAGS="$CFLAGS -Wno-unused-command-line-argument" \
    ../configure "$@" --host=$host \
        --with-zlib=$zroot \
        --with-ssl-dir=$sslroot \
        --without-openssl-header-check \
        --disable-strip \
        --disable-etc-default-login \
        --with-libs \
        --without-pam \
        --without-shadow \
        --disable-utmp \
        --disable-utmpx \
        --with-sandbox=no >> $buildlog 2>&1

    cfg_ret=$?
    if [ $cfg_ret -ne 0 ]; then
        echo "$pkgname configure failed (exit $cfg_ret), see $buildlog"
        cd $OLDPWD
        return $cfg_ret
    fi

    ${MAKE} -j$(nproc) >> $buildlog 2>&1
    mk_ret=$?
    if [ $mk_ret -ne 0 ]; then
        echo "$pkgname make failed (exit $mk_ret), see $buildlog"
    fi
    cd $OLDPWD
    return $mk_ret
}

package() {
    cd $builddir/$ARCH-build
    ${MAKE} install-nosysconf >> $buildlog 2>&1
    ret=$?
    cd $OLDPWD
    unset host
    if [ $ARCH == "armeabi-v7a" ]
    then
        unsetarm32ENV
    elif [ $ARCH == "arm64-v8a" ]
    then
        unsetarm64ENV
    else
        echo "${ARCH} not support"
        return -1
    fi
    return $ret
}

check() {
    echo "The test must be on an OpenHarmony device!"
}

cleanbuild() {
    rm -rf ${PWD}/$builddir
}

3.2 HPKBUILD 编写要点

bash 复制代码
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# Contributor: csdn猫哥 <534117529@qq.com>
# Maintainer: csdn猫哥 <534117529@qq.com>

source HPKBUILD > /dev/null 2>&1
logfile=${LYCIUM_THIRDPARTY_ROOT}/${pkgname}/${pkgname}_${ARCH}_${OHOS_SDK_VER}_test.log

checkprepare() {
    return 0
}

# 在 OpenHarmony 设备或 CI 环境校验安装产物;不在构建机执行交叉二进制
openharmonycheck() {
    res=0
    prefix_inst=$LYCIUM_ROOT/usr/$pkgname/$ARCH
    bdir=$builddir/$ARCH-build

    echo "--- OpenSSH $pkgver post-build check ($ARCH) ---" > "${logfile}" 2>&1

    ssh_bin=""
    sshd_bin=""
    for d in "$prefix_inst" "$bdir"; do
        if [ -z "$ssh_bin" ]; then
            if [ -x "$d/bin/ssh" ]; then
                ssh_bin="$d/bin/ssh"
            elif [ -x "$d/ssh" ]; then
                ssh_bin="$d/ssh"
            fi
        fi
        if [ -z "$sshd_bin" ]; then
            if [ -x "$d/sbin/sshd" ]; then
                sshd_bin="$d/sbin/sshd"
            elif [ -x "$d/libexec/sshd" ]; then
                sshd_bin="$d/libexec/sshd"
            elif [ -x "$d/sshd" ]; then
                sshd_bin="$d/sshd"
            fi
        fi
    done

    if [ -n "$ssh_bin" ] && [ -n "$sshd_bin" ]; then
        echo "ssh: $ssh_bin" >> "${logfile}" 2>&1
        echo "sshd: $sshd_bin" >> "${logfile}" 2>&1
        echo "openssh binaries present: OK" >> "${logfile}" 2>&1
    else
        echo "openssh check failed: missing ssh or sshd (install dir: $prefix_inst, build: $bdir)" >> "${logfile}" 2>&1
        res=1
    fi

    # 可选:在真机/模拟器上通过 hdc 执行版本自检(需自行推送依赖 so)
    # hdc file send "$ssh_bin" /data/local/tmp/ssh
    # hdc shell "chmod 755 /data/local/tmp/ssh && /data/local/tmp/ssh -V" >> "${logfile}" 2>&1

    return $res
}
  1. 元数据

    • pkgnamepkgverarchslicensedepends(如 opensslzlib)。
    • makedepends 只写宿主机可执行工具名 (由 lycium/script/build_hpk.shwhich 检查);不要把 zlib/openssl 写进 makedepends ,否则会被当成「系统命令」要求安装,误报「请先安装 zlib 命令」。
  2. 源码与校验

    • sourcepackagenamedownloadpackageautounpack
    • SHA512SUM 中的文件名必须与 packagename 一致 (例如 openssh-9.9p2.tar.gz),不能混用其它包的条目(曾出现误写 acl-2.1.0.zip 导致 sha512sum: No such file)。
  3. 构建类型:必须声明 configure

    • Lycium 的 build_hpk.sh 中:若未设置 buildtools="configure",会走 CMake 分支,向 build 传入 -DCMAKE_...,与 OpenSSH 的 ./configure 流程不符,易导致后续失败或行为混乱。
    • 正确写法:buildtools="configure" ,这样会调用 configuredependpathbuildargs 变为 --prefix=... ,与 ../configure "$@" 衔接。
  4. 交叉环境与 --host

    • source envset.sh ,在 prepare() 里按 $ARCH 调用 setarm32ENV / setarm64ENV ,并设置 host= (与 OHOS musl 一致时可用 arm-linux-musleabihfaarch64-linux-musl)。
    • 不要使用未定义的 $HOST ,否则会出现 --host= 为空,configure 失败。
  5. configure 参数建议(按实际裁剪)

    • "$@" :承接 Lycium 传入的 --prefix,避免手写重复 prefix。
    • --with-zlib=--with-ssl-dir= :指向 $LYCIUM_ROOT/usr/zlib/$ARCH$LYCIUM_ROOT/usr/openssl/$ARCH
    • CPPFLAGS / LDFLAGS :增加 openssl、zlib 的 include / lib(含 lib64),便于链接探测通过。
    • 交叉 + OpenSSL 3:可设 CPPFLAGS=-DOPENSSL_API_COMPAT=0x10100000L ,并加 --without-openssl-header-check,避免无法运行测试程序时的头/库一致性误判。
    • 嵌入式/无 PAM、无 utmp:--without-pam--without-shadow--disable-utmp--disable-utmpx 等可减少对宿主特性的依赖。
    • 若暂不需要复杂沙箱:--with-sandbox=no 可简化交叉环境下的行为(上线前可按安全需求再评估)。
    • LIBS=-lcrypto -lz 等可在 configure 阶段帮助 libcrypto 链接测试。
  6. build() / package()

    • $builddir/$ARCH-build 下执行 ../configure ... >> $buildlog ,再 make
    • 区分 configure 失败make 失败 的日志提示,便于查 openssh-*-<ARCH>-lycium_build.log
    • package() 使用 install-nosysconf ;结束后 unsetarm*ENV,避免影响下一架构。

3.3 HPKCHECK 编写要点

  • source HPKBUILD ,定义 logfile (含 pkgnameARCHOHOS_SDK_VER)。
  • 可选 checkprepare() (无准备则 return 0)。
  • openharmonycheck() :OpenSSH 产物是 ssh / sshd 等二进制 ,不宜在 x86 构建机上直接执行 ARM 程序;可检查:
    • 安装前缀 $LYCIUM_ROOT/usr/openssh/$ARCH/bin/sshsbin/sshd (或 libexec/sshd);
    • 若尚未 install,则检查 $builddir/$ARCH-build/ssh./sshd
  • 真机验证可保留注释掉的 hdc file send + hdc shell ... ssh -V 示例。

3.3 其它文件

  • README.OpenSource :JSON 中填写 名称、版本、License 链接、上游 URL、维护者
  • README_zh.md / README.md:版本、依赖、构建顺序、与约束文档的链接。
  • docs/hap_integrate.md :说明 Lycium 输出路径、与 libssh2 等库的差异、HAP 与系统集成的注意点。

3.4 推荐编译顺序(命令级)

lycium 目录:

shell 复制代码
./build.sh zlib openssl openssh

或先保证 lycium/usr/zlib/<ARCH>lycium/usr/openssl/<ARCH> 已存在,再单独:

shell 复制代码
./build.sh openssh

四、本次移植中遇到的问题(FAQ)

现象 原因 处理
sha512sum: acl-2.1.0.zip: No such file,SHA512 校验失败 SHA512SUM 写错包名/条目 ,与当前下载的 openssh-9.9p2.tar.gz 不一致 按官方包重新计算并写入 openssh-9.9p2.tar.gz 的 SHA512 一行
「请先安装 zlib 命令」 且退出 makedepends=("openssl","zlib")checkmakedependswhich 当成宿主机命令 检查,系统 PATH 里没有名为 zlib 的命令 makedepends=() ;库依赖只放在 depends,由 Lycium 依赖顺序编译
未编 zlib 时路径不存在 工程内缺少 thirdparty/zlib 配方时,--with-zlib=$LYCIUM_ROOT/usr/zlib/... 无对应目录 增加 zlibHPKBUILD (如 CMake + CMAKE_INSTALL_PREFIX=$LYCIUM_ROOT/usr/zlib/$ARCH ),并先编 zlib
ERROR during : build -DCMAKE_... 未设 buildtools="configure" ,走了 CMake 分支 设置 buildtools="configure"
openssh configure error--host= 异常 source envset.sh$HOST/$host 未设 prepare() 中设 hostsetarm*ENVconfigure 使用 "$@" --host=$host
configure/make 仍偶发失败 OpenSSL 3、无 utmp/PAM、沙箱探测等与交叉环境不匹配 按需增加 OPENSSL_API_COMPAT--without-openssl-header-check--without-pam--disable-utmp--with-sandbox=no 等;并保证 SSL/ZLIB 的 lib/lib64 与头文件路径

五、真机验证

OpenSSH 集成说明(Lycium / OpenHarmony)

OpenSSH portable 产物以可执行程序 为主(sshsshdscpsftpssh-keygen 等),与以 .so 形式供应用链接的库类三方件用法不同:常见场景为系统组件集成 或通过 hdc 在设备上验证,而不是在 HAP 内直接 target_link_libraries(ssh)

  • 获取本仓库后,三方库目录为:

    text 复制代码
    tpc_c_cplusplus/thirdparty/openssh
    ├── docs
    │   └── hap_integrate.md
    ├── HPKBUILD
    ├── HPKCHECK
    ├── SHA512SUM
    ├── README.OpenSource
    ├── README.md
    └── README_zh.md
  • lycium 目录下先编依赖再编本库(示例):

    shell 复制代码
    cd lycium
    ./build.sh zlib openssl openssh
  • 编译成功后,安装前缀一般为:

    text 复制代码
    lycium/usr/openssh/<ARCH>/
    ├── bin/          # ssh, scp, sftp, ssh-keygen 等
    ├── sbin/         # sshd(若 configure 安装到 sbin)
    ├── libexec/      # 部分版本下的辅助程序
    └── share/        # 手册等(视配置而定)

    其中 <ARCH>armeabi-v7aarm64-v8a

设备侧验证

  1. bin/sbin/ 下所需二进制及 openssl、zlib 等运行所需 .so 推送到设备可执行路径(例如 /data/local/tmp/,如果真机系统已自带这些库如openssl和zlib库, 则该步骤省略)。

  2. 使用 hdc shell 执行(示例):

    shell 复制代码
    chmod 755 /data/local/tmp/ssh /data/local/tmp/sshd
    /data/local/tmp/ssh -V
  3. sshd 需在设备上配置 host key、监听地址与权限目录,并满足系统安全策略;具体以目标系统文档为准。

六、经验小结

  1. 先对齐 Lycium 语义depends vs makedependsbuildtools=configureSHA512SUM 文件名,可规避大量「表面像环境问题、实为脚本语义错误」的故障。
  2. 再对齐交叉编译语义工具链环境--host 与 musl/OHOSOpenSSL/zlib 的 prefix 与链接
  3. OpenSSH 是「程序集」而非单一 .so :文档与 HPKCHECK 应围绕二进制产物与设备侧验证 来写,与 libssh2 等库的集成文档区分开。
  4. 排障时优先查看thirdparty/openssh/openssh-<ver>-<ARCH>-lycium_build.log ,结合脚本里区分 configure / make 的提示,可快速定位。

七、参考与延伸阅读

  • OpenSSH 官网与发行说明:https://www.openssh.com/
  • Portable 源码镜像(示例):https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/
  • 同仓库内可参考脚本:thirdparty/gzip/HPKBUILD (configure + envset)、thirdparty/libssh2/HPKCHECK (测试目录)、lycium/script/build_hpk.shcheckmakedependsconfiguredependpath 行为)
  • 同目录集成说明:<hap_integrate.md>

最后,欢迎加入开源鸿蒙开发者社区交流:https://harmonypc.csdn.net/

相关推荐
轻口味2 小时前
HarmonyOS 6 轻相机应用开发2:贴纸效果实现
音视频·harmonyos·鸿蒙·播放器
HwJack202 小时前
跨模块资源共享的破局之道:HarmonyOS HSP 资源访问“避坑与升华”指南
华为·harmonyos
liulian09163 小时前
【Flutter for OpenHarmony】原生卡片 Widget 集成实战:从零构建待办清单桌面组件
flutter·华为·学习方法·harmonyos
想你依然心痛3 小时前
HarmonyOS 6游戏开发实战:基于悬浮导航与沉浸光感的“光影迷宫“解谜游戏
游戏·华为·harmonyos·悬浮导航·沉浸光感
liulian09164 小时前
Flutter 三方库 connectivity_plus 的鸿蒙化适配与网络状态管理实战
网络·flutter·华为·学习方法·harmonyos
liulian09165 小时前
【Flutter For OpenHarmony】Flutter 三方库 flutter_secure_storage 的鸿蒙化适配指南
flutter·华为·学习方法·harmonyos
liulian09166 小时前
【Flutter For OpenHarmony】Flutter 三方库 flutter_local_notifications 的鸿蒙化适配指南
flutter·华为·学习方法·harmonyos
IntMainJhy6 小时前
【Flutter 三方库 Provider 】flutter for open harmony的鸿蒙化适配与实战指南✨
flutter·华为·harmonyos
Swift社区6 小时前
鸿蒙游戏,会不会重演微信小游戏的爆发?
游戏·微信·harmonyos