Terraform在AWS创建公私钥连接私网EC2报公钥权限拒绝排查
问题场景
部署两台EC2实例,一台位于公有子网,一台位于私有子网,目前可正常连接公有子网EC2,期望通过私钥连接私有子网内的EC2。使用Terraform创建密钥的相关配置如下:
# 生成RSA私钥 resource "tls_private_key" "pk" { algorithm = "RSA" rsa_bits = 4096 } # 上传公钥到AWS创建密钥对 resource "aws_key_pair" "pk" { key_name = "myKey" public_key = tls_private_key.pk.public_key_openssh # 已尝试使用trimspace处理公钥 } # 私有子网EC2绑定上述密钥对 resource "aws_instance" "xxx" { # 其余实例配置省略 key_name = aws_key_pair.pk.key_name } # 私钥存储至SSM Parameter Store resource "aws_ssm_parameter" "priv_key" { # 参数名称等其余配置省略 value = tls_private_key.pk.private_key_pem }
实际操作流程:登录公有子网EC2后,通过GetParameter接口拉取SSM中存储的私钥,执行ssh -i /本地私钥路径 ec2-user@<私有EC2内网IP>尝试连接,返回报错:permission denied (public key)。
方案可行性结论
该架构方案本身完全可行,公钥认证失败均为配置细节错误导致,不存在逻辑层面的硬障碍。
故障原因排查
按出现概率从高到低排序:
- 私钥文件权限不符合SSH要求:SSH客户端默认会拒绝使用权限过宽的私钥文件,拉取私钥到公有EC2本地后,必须先执行
chmod 400 /本地私钥路径将私钥权限设置为仅所有者可读,否则SSH会直接忽略该私钥,导致认证失败。 - 私钥内容损坏/格式错误:从SSM拉取私钥时如果转义逻辑有误,很容易出现换行丢失、
\n被存为字面字符、首尾标记缺失的问题。正常PEM格式私钥必须以-----BEGIN RSA PRIVATE KEY-----开头、-----END RSA PRIVATE KEY-----结尾,所有换行符为实际换行而非转义字符串,可执行cat -A /本地私钥路径校验,若看到行尾出现字面的\n字符即可判定为格式错误。 - 实例默认登录用户名错误:不同发行版的AMI默认登录用户名存在差异,并非所有EC2都使用
ec2-user:- Amazon Linux 2/AL2023默认用户为
ec2-user - Ubuntu系列默认用户为
ubuntu - Debian系列默认用户为
admin - CentOS/RHEL系列默认用户为
centos或ec2-user
用户名不匹配时也会直接返回公钥认证拒绝报错。
- Amazon Linux 2/AL2023默认用户为
- 密钥对未正确注入实例:AWS仅在实例首次启动时,将绑定的密钥对公钥写入实例内对应用户的
~/.ssh/authorized_keys文件。如果实例是先启动、后绑定的密钥对,或者启动时绑定密钥失败,公钥根本没有写入实例系统,必然认证失败。该场景需要终止实例后使用正确密钥对重新启动,或手动通过其他方式将公钥写入实例的authorized_keys文件。 - 密钥版本不匹配:Terraform的
tls_private_key资源属于易失性资源,如果执行apply过程中触发了私钥重建,会出现SSM中存储的新私钥和实例启动时注入的旧公钥不匹配的问题,此时即使配置全部正确也无法通过认证。 - 网络层拦截:需确认公有EC2到私有EC2的22端口入方向规则在安全组、网络ACL层面已放通,路由可达,不存在防火墙拦截。
内容的提问来源于stack exchange,提问作者Judi
相关产品推荐
相关产品推荐

