通过UserData在Linux AMI创建带SSH权限的额外EC2用户遇异常
解决EC2 UserData仅创建用户但未完成密钥授权的问题
我之前也碰到过一模一样的情况!手动执行命令一切正常,但放到UserData里就掉链子,核心原因是UserData的执行环境和你手动登录后的环境有本质差异——它默认是以root身份在无交互的环境下运行的,很多你手动操作时默认的路径、权限、环境变量都不一样。
先给你一个能正常工作的UserData脚本
#!/bin/bash -e # 创建带家目录的test-user用户 useradd -m test-user # 确保test-user的.ssh目录存在(手动执行时可能自动生成,但UserData里不会) mkdir -p /home/test-user/.ssh # 复制ec2-user的授权密钥到test-user的目录(必须用绝对路径!) cp /home/ec2-user/.ssh/authorized_keys /home/test-user/.ssh/ # 严格设置SSH要求的权限(这步非常关键,权限不对SSH会直接拒绝登录) chown -R test-user:test-user /home/test-user/.ssh chmod 700 /home/test-user/.ssh chmod 600 /home/test-user/.ssh/authorized_keys # (可选)如果需要给test-user sudo权限,加上这两句 echo "test-user ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/test-user chmod 440 /etc/sudoers.d/test-user
为什么你的原脚本会失败?
我猜你踩了这几个坑:
- 路径问题:手动执行时你在ec2-user的家目录,用
~/.ssh/authorized_keys没问题,但UserData以root运行时,~指向的是root的家目录,根本找不到ec2-user的密钥文件,复制命令直接失败。 - 目录缺失:创建用户时如果没加
-m参数,/home/test-user目录都不会生成,更别说.ssh目录了,后续复制自然失败。 - 权限不达标:SSH对
.ssh目录和authorized_keys的权限要求极严——目录必须是700(只有所有者能读写),文件必须是600(只有所有者能读),而且所有者必须是test-user。手动执行时你可能自然就设置对了,但UserData里如果漏了这几步,就算复制了密钥也无法登录。 - 错误无感知:默认情况下,UserData执行时某一步出错不会终止,会继续跑后面的命令,所以你只看到用户被创建,后面的步骤其实都失败了。加
-e参数(#!/bin/bash -e)可以让脚本在出错时立刻停止,方便排查。
排查方法
如果还是有问题,去EC2实例里看UserData的执行日志:
cat /var/log/cloud-init-output.log
这个日志会把脚本执行的所有输出和错误都记录下来,一看就知道哪一步出问题了。另外,你也可以切换到root身份(sudo -i),手动执行你的脚本,模拟UserData的运行环境,就能复现问题了。
内容的提问来源于stack exchange,提问作者Gunjan Sharma
相关产品推荐
相关产品推荐

