如何在sshd_config中基于SSH公钥类型配置Match规则以跳过PAM认证
我明白你的需求——想用sshd的Match规则根据用户使用的SSH公钥类型(比如FIDO安全密钥)来跳过PAM认证,但你尝试用PubkeyAcceptedAlgorithms作为Match条件时遇到了报错,这是因为这个配置项并不支持作为Match的判断条件。sshd的Match块只能识别特定的属性(比如User、Group、Host等),PubkeyAcceptedAlgorithms属于全局配置项,没法用来做Match的匹配条件。
下面给你几个可行的替代方案,你可以根据自己的场景选择:
方案一:通过authorized_keys文件的选项控制认证方式
这是最直接的方法,针对FIDO类型的公钥,在用户的~/.ssh/authorized_keys文件中添加authentication-methods选项,指定仅使用公钥认证,跳过PAM:
authentication-methods="publickey" sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29t...
这样,当用户使用这条FIDO密钥登录时,sshd只会进行公钥认证,不会触发PAM;而其他没有添加该选项的密钥,会遵循全局的PAM配置。
优点:配置简单,针对单个密钥精确控制;缺点:需要逐个修改用户的authorized_keys文件,不适合大规模用户场景。
方案二:用用户组结合Match规则批量控制
如果你的用户数量不多,可以把所有使用FIDO密钥的用户加入同一个用户组(比如fido-users),然后在sshd_config中通过Match规则关闭该组的PAM认证:
首先创建用户组:
groupadd fido-users
把目标用户加入组:
usermod -aG fido-users username
然后在sshd_config中添加:
Match Group fido-users UsePAM no
这样,属于fido-users组的用户登录时会跳过PAM,其他用户则遵循全局的PAM配置。
优点:批量控制,无需修改每个用户的authorized_keys;缺点:需要手动维护用户组,用户密钥类型变更时要同步调整组归属。
方案三:用AuthorizedKeysCommand动态生成配置
如果需要大规模自动化控制,可以写一个脚本,动态检测用户公钥的类型,并自动添加authentication-methods选项,然后通过sshd的AuthorizedKeysCommand来调用这个脚本。
比如,写一个名为authorized_keys_fido.sh的脚本:
#!/bin/bash USER="$1" AUTH_KEYS_FILE="/home/${USER}/.ssh/authorized_keys" # 检查文件是否存在 if [ -f "${AUTH_KEYS_FILE}" ]; then while read -r LINE; do # 跳过注释和空行 if [[ "${LINE}" =~ ^#.*$ || -z "${LINE}" ]]; then echo "${LINE}" continue fi # 判断是否为FIDO类型密钥 if echo "${LINE}" | grep -qE 'sk-ssh-ed25519@openssh.com|sk-ecdsa-sha2-nistp256@openssh.com'; then # 添加仅公钥认证的选项 echo "authentication-methods=\"publickey\" ${LINE}" else echo "${LINE}" fi done < "${AUTH_KEYS_FILE}" fi
给脚本添加执行权限:
chmod +x /path/to/authorized_keys_fido.sh
然后在sshd_config中配置:
AuthorizedKeysCommand /path/to/authorized_keys_fido.sh AuthorizedKeysCommandUser root
这样,sshd在读取用户的authorized_keys时,会自动为FIDO密钥添加authentication-methods="publickey"选项,实现跳过PAM的效果,其他密钥则保持原有配置。
优点:自动化大规模控制,无需手动修改用户文件;缺点:需要编写和维护脚本,对运维能力有一定要求。
备注:内容来源于stack exchange,提问作者perrze

