如何移植openssh到ARM开发板

最近因为公司安全的需求, 要修改openssh的源码, 将其移植到一个ARM的嵌入式系统上, 替换原有的预编译的版本. 参考了网上的一些移植openssh的资料, 如openssl官网编译安装说明; 移植openssh到arm-linux, 但是由于目标平台不一样, 实践起来并不能完全参考, 会有细微的差异. 这里把整个流程写下来, 总结一下, 方便后面移植相关开发工具.

下载源码

openssh的编译依赖于openssl, zlib两个库, 因此编译的第一步是把所有这些源码都下载过来, 三个开源仓库下载路径如下:

  • openssh: git仓库以及各个release版本, https://www.openssh.com/portable.html; 由于release版本才有Configure脚本, 因此我直接下载了一个v6.6p1的稳定版本
  • openssl: 包含github仓库以及文档说明, https://www.openssl.org/; github上的源码基本包含了历史分支信息, 因此可以直接通过git clone下载, 然后checkout到对应版本的分支(使用v1.0.1版本)
  • z-lib: 官网上有下载链接, https://zlib.net/; github上也有仓库, 但是没有历史分支信息, 所以下载了版本zlib-1.2.11的源码.

opensshINSTALL文档中对所要求的openssl/z-lib版本有具体说明, 可以参考.

由于目标移植平台已有的openssh使用的版本是OpenSSH_6.6p1, 因此实际下载的源码版本信息如下:

  • openssh: Openssh_6.6p1
  • openssl: OpenSSL_1_0_1-stable
  • z-lib: zlib-1.2.11
1
2
3
4

/usr/local/bin # ./ssh -V
OpenSSH_6.6p1, OpenSSL 1.0.1h 5 Jun 2014

编译源码

为了方便管理以及查看编译结果, 可以把三个软件包解压放到一个目录: /data/wxn/openSSH. 本地机器CPU是x86_64, 操作系统是Ubuntu16, 目标平台是armv7架构, 交叉编译使用的工具是arm-none-linux-gnueabi-gcc(gcc 4.6.2).

编译zlib

进入/data/wxn/openSSH/zlib-1.2.11, 通过./configure -h查看编译配置说明:

1
2
3
4
5
6
7

./configure -h
usage:
configure [--const] [--zprefix] [--prefix=PREFIX] [--eprefix=EXPREFIX]
[--static] [--64] [--libdir=LIBDIR] [--sharedlibdir=LIBDIR]
[--includedir=INCLUDEDIR] [--archs="-arch i386 -arch x86_64"]

如果只需要生成静态库, 就指定参数--static; 另外需要指定生成文件的路径:

1
2
3
4

./configure --static --prefix=/data/wxn/openSSH


上述指令生成编译的Makefile后, 修改其中的编译工具, 将其指向交叉编译工具所在的路径(需要修改gcc/ar两个工具的路径):

1
2
3
4

TOOL_PREFIX=/data/wxn/toolchainbin/arm-none-linux-gnueabi-
CC=$(TOOL_PREFIX)gcc

执行make;make install, 在目录/data/wxn/openSSH/lib下可以看到生成了一个libz.a的静态库.

编译openssl

编译openssl会稍微麻烦点. 同样查看./Configure -h可以看到, 需要配置目标平台的系统类型:

1
2
3
4
5
6

./Configure -h
Configuring for

Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [experimental-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-dso] [no-krb5] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--test-sanity] os/compiler[:flags]

编译配置Configure中已经添加了很多平台类型(./Configure LIST可以查看已经支持的平台), 但是好像并没有发现armv7架构的平台, openssl官网建议自己手动添加一个配置, 但看了其他地方说可以使用相似平台的配置, 看配置列表跟arm相关的有android-armv7/linux-armv4两个, 尝试了armv4发现是可以(android-armv7会出现编译错误):

1
2
3

./Configure linux-armv4 --prefix=/data/wxn/openSSH

修改生成的Makefile, 按照之前的zlib配置, 将其中gcc/nm/ar的地方都指向交叉编译工具所在的目录, 执行make; make install, 即可看到/data/wxn/openSSH生成了lib/bin两个目录, lib目录包含了libssl.a/libcrypto.a静态库, bin下包含了openssl工具.

编译openssh

编译openssh跟之前两个库的编译类似(具体可以参考INSTALL文档), 只不过需要指定生成的openssl/zlib所在目录(进入代码根目录):

1
2
3
4
5

GCC=/data/wxn/toolchain/arm-none-linux-gnueabi-gcc
AAR=/data/wxn/toolchain/arm-none-linux-gnueabi-ar
./configure --host=arm-linux --prefix=/usr/local --with-zlib=/data/wxn/openSSH --with-ssl-dir=/data/wxn/openSSH --disable-etc-default-login --disable-strip CC=$GCC AR=$AAR

接着执行make(不用执行安装指令make install), 可以看到根目录下多了ssh/sshd/scp等工具.将其拷贝到目标平台对应目录/usr/local/bin, 确认可以正常运行, 至此大功告成.