Debian 12 手动编译 openssh-7.4 openssl-1.0.2u

By | 2026年5月14日

编译背景

SSH到客户华为防火墙报错:shell request failed on channel 0。至于警告 ‘Negotiated key exchange algorithm is not safe 可忽略:

但是使用另一台机器访问确可以(版本是 openssh 7.4 openssl 1.0.2k-fips)。k 代表该版本在 1.0.2 系列中的第 11 次安全修复与补丁更新(按字母 a-z 顺序排列),fips 则表示该版本集成了符合美国联邦信息处理标准(FIPS)的加密模块,能够满足政府或高安全场景的合规要求。

因此尝试自己编译个 openssh 7.4 openssl 1.0.2 版本。

注意:在此之前,听网工同事反馈,客户改了权限后采集成功过一次的,我猜可能客户也动过华为墙的配置吧:

编译环境

我直接使用了客户生产环境用的 Debian 12 的 docker 容器来编译:

root@28b553e21867:/zeehome/ssh7/openssl-1.0.2# cat /etc/os-release 
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

编译 openssl-1.0.2

下载地址:https://openssl-library.org/source/old/1.0.2/

编译命令:

cd /zeehome/ssh7
tar -xzvf openssl-1.0.2u.tar.gz
cd openssl-1.0.2

# 由于要打一个独立的可执行 ssh 文件到客户那,因此必须加 no-shared,
# 加上 no-shared 后,OpenSSL 在编译时只会生成静态库文件(即 libcrypto.a 和 libssl.a),而不会生成动态库(.so 文件)。
./config no-shared --prefix=/zeehome/ssh7/openssl_final --openssldir=/zeehome/ssh7/openssl_final/ssl

# 多CPU编译,速度比 make && make install 快很多
make -j$(nproc) && make install

/zeehome/ssh7/openssl_final 生成的内容:

编译 openssh-7.4

下载地址:https://cdn.openbsd.org./pub/OpenBSD/OpenSSH/portable/openssh-7.4p1.tar.gz
如果要下载 7.9 只需要将上面链接里的数字 7.4 改成 7.9。

编译命令:

cd /zeehome/ssh7/openssh-7.4p1

# 1. 清理缓存并解密 512 位限制
# 在网络运维的底层通信中,海南中行、上海电力等现场的一些老旧华为交换机或路由器,由于出厂年代久远且从未升级过固件,它们在进行 SSH 加密握手时,随身携带的 RSA 设备公钥长度仅仅只有 512 位。
make clean || true && rm -f config.h config.status Makefile
sed -i 's/#define SSH_RSA_MINIMUM_MODULUS_SIZE.*/#define SSH_RSA_MINIMUM_MODULUS_SIZE 512/g' sshkey.h 2>/dev/null || true

# 2. 运行隔离配置,通过 CPPFLAGS 强行让 gcc 抛弃系统自带的 3.0,只看前面编译好的 1.0.2 老库(下面的 /zeehome/ssh7/etc 目录是空的不用关心)
# 加 -static 是为了把所有依赖的加密演算法(OpenSSL 1.0.2u)直接打包熔铸进单个档案中,让它变成一个无须安装任何依赖库、拿到客户任何无网路环境下都能直接运行的绿色免安装单档案程序。
./configure \
--prefix=/zeehome/ssh7/ \
--sysconfdir=/zeehome/ssh7/etc \
--with-ssl-dir=/zeehome/ssh7/openssl_final \
--without-openssl-header-check \
CPPFLAGS="-I/zeehome/ssh7/openssl_final/include" \
CFLAGS="-I/zeehome/ssh7/openssl_final/include -Wno-error=deprecated-declarations" \
LDFLAGS="-L/zeehome/ssh7/openssl_final/lib -static"

# 3. 编译全静态单文件
make ssh

# 4.查看编辑好的 ssh 文件的版本
./ssh -V

编译完成后,会在当前目录下生成一个 ssh 文件,大小是 4MB,使用它查看版本并测试成功:

使用编译的SSH还是报同样错误

将 ssh 拷贝到客户那后问题依旧,这是通过添加 ssh -vvv 参数输出的连接信息:

做一些功课,发现与 ACL有关:

为什么华为会发 Failure 拒绝分配 Shell?在华为交换机(VRP系统)的架构中,SSH 登录分为两个完全独立的层级:

  • (1)第一层:SSH 进程认证。 负责校验账号和密码。不论是成功的还是失败的机器,我的日志里都印着 Authentication succeeded,说明华为已经认可了我的账号密码。
  • (2)第二层:VTY 线路分配(关键点)。 当密码正确后,SSH 进程会向系统申请打开一个 Shell(命令行交互界面)。此时,华为的 VTY 接口上配置的安全策略(ACL 防火墙)才会介入检查

现在怀疑是设备没有设置白名单导致的,借助可以SSH访问华为设备的那台机器执行了下面步骤:

第一步:揪出拦截您的 ACL 编号

<SHPIC-SH-JQ-CORE-015-CE12804-01> display current-configuration | begin user-interface vty

注意看输出的内容,里面 100% 有类似这样的一行:

user-interface vty 0 4
  acl 2000 inbound     <--- 注意这个 2000(也可能是别的数字或名字)
  authentication-mode aaa

第二步:查看白名单内容

<SHPIC-SH-JQ-CORE-015-CE12804-01> display acl 2000

这时候会列出一堆 rule 5 permit source 10.100.240.x 0.0.0.0。
您会发现,您这台连不上的 Debian 12 的机器 IP,肯定不在这份列表里!

根据上面AI的回答,看了下这台华为设备的 acl。vpn-instance 的 acl 40 是后来让客户加的,IP已经放行了但是还是不行:

排查到怀疑人生,开始打起了 aaa 认证的注意,不过最终也排除了。

真凶浮现

排查了整整一天,客户说没做NAT,权限也方通了。

最后在华为设备上执行 dis tcp status | include 22 总算找到问题的根源了:竞争对手安博通 在客户那配了条NAT:

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注