
SerenityOS SSH Server 每次重启后客户端提示主机密钥变化如何用静态主机密钥修复【免费下载链接】serenityThe Serenity Operating System 项目地址: https://gitcode.com/GitHub_Trending/se/serenity如果你通过 SSH 连接 SerenityOS 的 SSH 服务器会发现一个反复出现的问题每次重启系统或重新构建磁盘镜像后SSH 客户端都会报告服务器主机身份发生了变化如WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED必须再次清除本地known_hosts里的旧记录才能连接。原因是 SerenityOS 自带的 SSHServer 目前只支持生成 ephemeral临时主机密钥每次启动时现场生成一对新的 ED25519 密钥作为服务器身份客户端检测到身份变化后会将其视为中间人攻击的迹象并中止连接。修复方法来自官方文档 Documentation/SSHServer.md手动生成一对 ED25519 密钥对作为固定主机密钥通过sync-local.sh构建脚本把它写进磁盘镜像的/etc/ssh/目录。重启后服务器加载的始终是同一对密钥客户端就不会再提示身份变化。为什么每次重启主机密钥都会变服务端实现可以印证这一行为。ServerConfiguration.cpp 中ensure_ssh_ed25519_keys()的逻辑是优先从/etc/ssh/host_ed25519私钥和/etc/ssh/host_ed25519.pub公钥加载静态主机密钥两个文件都不存在时回退到Crypto::Curves::Ed25519::generate_private_key()现场生成一对临时密钥——这就是每次重启密钥都变化的根源如果文件存在但加载失败例如公私钥不匹配服务器会打印Unable to use the host key from /etc/ssh/:加具体错误同样回退到临时密钥。其中公私钥不匹配对应 源码 中的Corrupted host key错误服务器启动时会在控制台输出对应的dbgln信息可作为排查依据。因此只要把正确的密钥对放进镜像的/etc/ssh/问题就能根治。准备条件已按 BuildInstructions.md 完成 SerenityOS 构建并习惯用Meta/serenity.sh run等方式运行/重建磁盘镜像宿主机上有ssh-keygen用于生成密钥对项目根目录下可以创建sync-local.sh。AdvancedBuildInstructions.md 说明该脚本的用途构建时向磁盘镜像的文件系统中添加、修改或删除文件且变更可以在镜像重建后持久生效。Meta/build-root-filesystem.sh 在每次构建根文件系统时执行它# Run local sync script, if it exists if [ -f ${SERENITY_SOURCE_DIR}/sync-local.sh ]; then sh ${SERENITY_SOURCE_DIR}/sync-local.sh fisync-local.sh在构建环境中以mnt目录为磁盘镜像根目录执行脚本内的mnt/...路径对应 SerenityOS 内的/...路径无需替换其他变量。第一步在宿主机生成 ED25519 主机密钥对Documentation/SSHServer.md 明确只支持 ED25519 密钥其他类型RSA、ECDSA 等不可用。主机密钥与客户端认证用的密钥对相互独立文档建议不要放在~/.ssh下而是单独存一个目录例如ssh-keygen -t ed25519 -f path/to/serenity/ssh_keys/host_ed25519命令中的path/to/serenity/ssh_keys/host_ed25519是文档给出的示例路径你可以换成任何自己指定的位置但后文sync-local.sh里的路径必须与这里一致。执行后会生成两个文件host_ed25519私钥和host_ed25519.pub公钥两者都要放进镜像。第二步配置 sync-local.sh把密钥对写入镜像如果项目根目录还没有sync-local.sh先创建它参照 AdvancedBuildInstructions.md 的示例加上#!/bin/sh与set -e然后把下面这段文档给出的命令追加进去。cp后面的*会同时拷走私钥和公钥两个文件chown/chmod将文件属主设为 root、权限收敛为属主只读ur,g,o因为镜像中 root 的 umask 相关配置由构建脚本统一管理这一步按文档原样保留即可mkdir -p mnt/etc/ssh/ cp path/to/serenity/ssh_keys/host_ed25519* mnt/etc/ssh/ chown root:root mnt/etc/ssh/host_ed25519* chmod ur,g,o mnt/etc/ssh/host_ed25519*mkdir -p保证目录已存在时不会报错所以这段内容在后续镜像重建时反复执行是安全的。第三步重建磁盘镜像保存好sync-local.sh后按你平时的方式重建镜像例如Meta/serenity.sh run。镜像构建过程中各build-image-*.sh脚本都会调用 Meta/build-root-filesystem.sh其中会在安装完基础系统后执行你的sync-local.sh密钥对随之写入镜像的/etc/ssh/目录。注意该机制依赖每次重建都执行sync-local.sh。如果镜像是在没有该脚本的情况下构建的/etc/ssh/host_ed25519不存在服务器仍会回退到临时密钥问题依旧。验证重启后客户端不再提示身份变化重建镜像后启动系统用与之前相同的方式建立 SSH 连接。重启 SerenityOS再次连接。预期现象不再出现“远程主机身份已变化”的警告无需再删除客户端known_hosts中的旧条目。这正是文档描述的目标状态——“If this identity changes between two connections, clients will detect it and abort”而静态密钥让身份在多次连接之间保持不变。如果警告依旧出现检查服务器启动时的控制台输出出现Unable to use the host key from /etc/ssh/: ...说明密钥文件缺失或不合法例如Corrupted host key表示公钥与私钥不匹配此时服务器已悄悄回退为临时密钥。对照确认两点sync-local.sh中的路径是否指向真实存在的密钥文件私钥与公钥是否出自同一次ssh-keygen。限制与边界主机密钥只支持 ED25519ServerConfiguration在读取静态密钥后会对密钥类型做SSH_ED25519校验公钥文件还要求恰好一行、且公钥必须能由私钥推导出来否则按加载失败处理并回退临时密钥。客户端认证是另一个独立问题该服务器只支持publickey认证客户端公钥需要安装到用户主目录的.config/ssh/authorized_keys例如通过sync-local.sh追加mnt/home/anon/.config/ssh/authorized_keys。本文只处理主机密钥这一侧如果连接在认证阶段失败属于客户端授权密钥的问题需按 Documentation/SSHServer.md 的 “Authentication” 一节另行配置。【免费下载链接】serenityThe Serenity Operating System 项目地址: https://gitcode.com/GitHub_Trending/se/serenity创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考