Alpine容器中新增SSH用户无法通过密钥登录
问题根因
新增用户SSH密钥认证失败是3个实打实的配置错误导致的,和Fargate、SSH服务本身无关:
- 公钥根本没写到新用户的认证文件里。入口脚本只把S3拉下来的所有公钥写到了ops用户的
/home/ops/.ssh/authorized_keys路径下,完全没处理新用户的公钥同步。新增用户逻辑里的cat /home/$USER_NAME/authorized_keys/ > /home/$USER_NAME/.ssh/authorized_keys完全是无效命令:你从来没在新用户家目录下创建过authorized_keys目录,也没把对应公钥放进去,cat一个不存在的目录路径只会抛错,最后生成的authorized_keys是空文件,sshd根本读不到对应公钥。 - 新用户没指定可登录shell。创建默认ops用户时你加了
-s /bin/sh参数指定交互shell,但新增用户的adduser -g "$USER_NAME" $USER_NAME命令没加这个参数,Alpine的adduser默认给新用户分配的shell是/sbin/nologin,这类用户本身就不允许交互登录,sshd会直接跳过公钥认证逻辑,回退到密码输入提示。另外你写的if [[ "$USER_NAME" = $USER_NAME ]]是恒真判断,没有任何实际校验作用。 - 权限配置不符合SSH的严格模式校验规则。你给新用户加了root、disk、sys等一堆高权限附属组,也没给新用户的家目录设置正确权限:SSH公钥认证强制要求用户家目录、.ssh目录、authorized_keys文件不能有组可写、全局可写权限,属主必须对应用户本身,否则sshd会直接拒绝读取认证文件,自动跳过公钥认证流程。
修复方案
- 替换原有新增用户逻辑,补全shell指定、公钥同步、标准权限配置:
# 替换原来恒真的无效判断,先判断USER_NAME变量非空 if [[ -n "$USER_NAME" ]]; then # 校验用户是否已存在 if ! cut -d: -f1 /etc/passwd | grep -qx "$USER_NAME"; then echo "creating $USER_NAME user" # 必须加-D参数免交互密码、-s /bin/sh指定可登录shell adduser -D -s /bin/sh -g "$USER_NAME" "$USER_NAME" # 建议给普通用户配NOPASSWD sudo,避免密码问题 echo "$USER_NAME ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/"$USER_NAME" && chmod 0440 /etc/sudoers.d/"$USER_NAME" # 只加必要附属组即可,不要乱加无关高权限组,避免触发SSH权限校验失败 for g in wheel; do addgroup "$USER_NAME" $g; done # 按SSH要求创建.ssh目录,权限设为700 mkdir -p -m 700 /home/"$USER_NAME"/.ssh # 统一从S3同步下来的公钥目录读对应用户的公钥,公钥文件以用户名命名,例如zhangsan.pub if [ -f "/home/authorized_keys/${USER_NAME}.pub" ]; then cat "/home/authorized_keys/${USER_NAME}.pub" > /home/"$USER_NAME"/.ssh/authorized_keys fi # 严格按SSH规则设置权限,不要给多余权限 chmod 644 /home/"$USER_NAME"/.ssh/authorized_keys chown -R "$USER_NAME":"$USER_NAME" /home/"$USER_NAME" chmod 750 /home/"$USER_NAME" fi fi
- 修正入口启动脚本
entrypoint.sh,公钥统一同步到公共目录后,遍历所有待创建用户执行初始化,不要只处理ops用户:
echo "downloading user keys..." mkdir -p /home/authorized_keys # 同步S3上的公钥到统一公共目录,公钥按用户名命名 aws s3 sync s3://bucket/user-keys/ /home/authorized_keys/ # 初始化默认ops用户 mkdir -p /home/ops/.ssh cat /home/authorized_keys/ops.pub > /home/ops/.ssh/authorized_keys chown -R ops:ops /home/ops chmod 700 /home/ops/.ssh chmod 644 /home/ops/.ssh/authorized_keys chmod 750 /home/ops # 从环境变量读取待创建的用户列表,用逗号分隔,例如USER_LIST=zhangsan,lisi,wangwu IFS=',' read -ra USER_ARR <<< "$USER_LIST" for USER_NAME in "${USER_ARR[@]}"; do # 这里嵌入上面写好的新增用户逻辑即可 done # 以前台模式启动sshd,不要让容器启动后直接退出 /usr/sbin/sshd -D
校验方法
部署新镜像后进容器执行以下检查,没问题就能正常用密钥登录:
- 执行
grep 新用户名 /etc/passwd,看输出末尾的shell路径是不是/bin/sh,不能是/sbin/nologin - 执行
cat /home/新用户名/.ssh/authorized_keys,确认文件里有正确的公钥内容,不是空文件 - 客户端用
ssh -v 新用户名@堡垒机地址调试登录,日志里出现Accepted publickey字样就说明公钥认证走通了,不会再弹出密码输入提示。
内容的提问来源于stack exchange,提问作者nitish9912
相关产品推荐
相关产品推荐

