OpenSSH 10.4 已经发布。对大多数管理员来说,SSH 升级通常不是“换个客户端”这么简单:它会碰到配置审计、基线扫描、容器镜像、CI 检查和运维脚本。这个版本里一个明确的兼容性变化值得先看:sshd -G 的配置转储输出不再全部使用小写指令名,而是改为大小写混合形式,例如 PubkeyAuthentication。
这次变化影响谁
OpenSSH 是完整的 SSH 协议 2.0 实现,也包含 sftp 客户端和服务器支持。10.4 的发布本身意味着客户端、服务端和文件传输组件都可能随发行版或基础镜像一起进入生产环境。
这次摘要里明确提到的潜在不兼容点集中在 sshd(8):
sshd -G以前输出小写配置项名,例如pubkeyauthentication yes。- 现在输出大小写混合的配置项名,例如
PubkeyAuthentication yes。
如果你只是手写 /etc/ssh/sshd_config,这个变化可能没有感觉;但如果你有脚本用 grep '^pubkeyauthentication '、awk '$1 == "passwordauthentication"' 或 JSON 转换器读取 sshd -G,就可能误判配置。
sshd -G 为什么容易被脚本依赖
sshd -G 常用于“展开最终配置”。它会把默认值、包含文件、命令行参数和配置文件合并后输出,适合做审计和回归检查。
典型用途包括:
- 检查是否关闭密码登录。
- 检查公钥登录是否启用。
- 检查某个镜像里的 sshd 默认配置是否符合基线。
- 在配置变更前后生成 diff。
问题在于,很多脚本把配置项名当成固定小写字符串。OpenSSH 10.4 改变输出大小写后,这类脚本并不一定报错,而是静默返回“没找到”。这比失败更危险,因为 CI 可能继续通过,审计结果却已经不可信。
可以这样实践:把解析逻辑改成大小写无关
下面这个脚本可以直接用于检查本机 sshd -G 输出中的关键配置。它不会假设配置项名大小写,因此同时兼容旧版和 OpenSSH 10.4 的输出形式。
运行前确认机器上有 sshd,并且当前用户有权限读取 sshd 配置。不同系统上 sshd 路径可能是 /usr/sbin/sshd 或 /usr/local/sbin/sshd,按需修改 SSHD_BIN。
#!/usr/bin/env bash
set -euo pipefail
SSHD_BIN="${SSHD_BIN:-/usr/sbin/sshd}"
get_sshd_value() {
local key="$1"
"$SSHD_BIN" -G 2>/dev/null | awk -v wanted="${key,,}" '
tolower($1) == wanted { print $2; found=1; exit }
END { if (!found) exit 2 }
'
}
pubkey_auth="$(get_sshd_value PubkeyAuthentication || true)"
password_auth="$(get_sshd_value PasswordAuthentication || true)"
printf 'PubkeyAuthentication=%s\n' "${pubkey_auth:-MISSING}"
printf 'PasswordAuthentication=%s\n' "${password_auth:-MISSING}"
if [[ "${password_auth:-}" == "yes" ]]; then
echo "ERROR: PasswordAuthentication is enabled" >&2
exit 1
fi
保存为 check-sshd-baseline.sh 后运行:
chmod +x ./check-sshd-baseline.sh
./check-sshd-baseline.sh
如果你的系统 sshd 不在 /usr/sbin/sshd:
SSHD_BIN=/usr/local/sbin/sshd ./check-sshd-baseline.sh
这个改法的关键点不是“把新名字写进去”,而是统一用 tolower($1) 比较。这样旧输出 pubkeyauthentication 和新输出 PubkeyAuthentication 都能命中。
CI 里更稳的写法
如果你在构建基础镜像时检查 SSH 配置,可以把脚本接到 CI 里。下面是一个最小 GitHub Actions 示例,可以按你的镜像构建流程改造。
name: sshd-config-check
on:
pull_request:
push:
branches: [main]
jobs:
check-sshd:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install OpenSSH server
run: |
sudo apt-get update
sudo apt-get install -y openssh-server
- name: Check effective sshd configuration
run: |
sudo /usr/sbin/sshd -G | awk '
tolower($1) == "passwordauthentication" { password=$2 }
tolower($1) == "pubkeyauthentication" { pubkey=$2 }
END {
print "PasswordAuthentication=" password
print "PubkeyAuthentication=" pubkey
if (password == "yes") exit 1
if (pubkey != "yes") exit 1
}
'
这段示例假设你的基线要求是“关闭密码登录,开启公钥登录”。如果你的环境需要跳板机、临时救援账号或特定内网策略,就不要照抄判断条件,应该把期望值改成自己的安全基线。
还要留意 Linux seccomp 沙箱
摘要还提到 Linux 上启用 seccomp 沙箱时,sshd(8) 有相关变化,但给出的信息不完整。这里不应该凭空推断具体行为。
实际升级时可以把它当成一个测试提醒:如果你的生产环境运行在 Linux,并且依赖发行版默认的 OpenSSH sandbox 行为,升级后至少要覆盖这些路径:
- 普通公钥登录。
sftp上传和下载。- 使用
ProxyJump或堡垒机的连接。 - 自动化任务里的非交互式 SSH 命令。
- 容器或最小化系统镜像里的 sshd 启动。
可以用下面的命令做基本冒烟测试。把 host.example.com、用户名和测试路径替换成你的环境。
ssh -o BatchMode=yes user@host.example.com 'id && uname -a'
printf 'openssh-10.4-smoke-test\n' > /tmp/ssh-smoke.txt
sftp user@host.example.com <<'SFTP'
put /tmp/ssh-smoke.txt /tmp/ssh-smoke.txt
get /tmp/ssh-smoke.txt /tmp/ssh-smoke.downloaded
rm /tmp/ssh-smoke.txt
SFTP
diff /tmp/ssh-smoke.txt /tmp/ssh-smoke.downloaded
升级建议
OpenSSH 属于基础设施里的低调核心组件,升级策略应该偏保守:先找自动化解析点,再滚动到非关键环境,最后进入生产。
一份实用检查清单:
- 搜索仓库里是否有
sshd -G、pubkeyauthentication、passwordauthentication等字符串。 - 把解析
sshd -G的脚本改为大小写无关。 - 对 SSH 登录、
sftp、跳板机链路和批处理任务做冒烟测试。 - 在 Linux 环境里关注 seccomp sandbox 相关行为,尤其是最小化镜像和自定义系统调用策略。
- 不要只看 sshd 是否启动成功,要验证真实登录和文件传输路径。
这次 10.4 的已知兼容性变化不复杂,但很容易藏在审计脚本和 CI 规则里。升级前花十分钟修掉大小写假设,比升级后排查“为什么基线检查突然失明”要便宜得多。