在 Terraform 管理的 AWS EC2 SSH 堡垒实例上处理多个用户的 SSH 密钥

Posted

技术标签:

【中文标题】在 Terraform 管理的 AWS EC2 SSH 堡垒实例上处理多个用户的 SSH 密钥【英文标题】:Handling SSH Keys for Multiple Users on Terraform-managed AWS EC2 SSH Bastion Instance 【发布时间】:2021-11-23 05:44:29 【问题描述】:

我有一堆使用 Terraform 管理的 AWS 基础设施。多个用户使用一个 EC2 SSH Bastion 实例来访问用于各种批处理任务的私有临时 EC2 实例。

Terraform 提供了一种机制,可以在创建时将单个 SSH 密钥包含到 EC2 实例中,但是我正在尝试找到一种解决方案,最好但不一定是基于 Terraform 的,它允许管理 SSH 堡垒的多个用户。

是否有一种解决方案允许 SSH Bastion 使用与 IAM 用户关联的 SSH 密钥,这样当(例如)bob 尝试 SSH 到 Bastion 时,Bastion 可以使用与 bob 关联的公钥应该bob 属于正确的组,有正确的权限,有正确的标签,还是其他一些识别特征?

如果上述问题暗示了解决问题的错误方法,是否有更好的方法来看待和解决问题?

提前谢谢你。

【问题讨论】:

您需要创建用户并将相应的密钥添加到 ~/.ssh/authorized_keys 您可以将其烘焙到 AMI 中(例如 Packer),或者您可以通过用户数据甚至使用一个 Terraform 供应商。但是,没有办法让您启动一个实例并直接说为他们添加用户和密钥,就像可以使用 GCP 我无法将 SSH 密钥烘焙到 AMI 中,因为将在 AWS 账户中添加和删除用户,或者授予和撤销对该系统的访问权限。每次发生这种情况时都重建 Bastion AMI 并为此重建基础设施是没有意义的。必须有一些合理的方法将 IAM 用户与某些权限关联起来,以允许 SSH 访问堡垒。 有,但 Terraform 无法为您管理它,因为 AWS 没有将它作为 API 公开。答案是每次您想更改盒子上的用户或密钥时,针对堡垒运行 Ansible/Chef/Puppet。或者让盒子自动下拉用户和密钥列表并自行配置。如果您将其放入 AMI 或用户数据中,那么 Terraform 将需要在每次更改时进行替换。 一般来说,尽管您可能需要考虑其他选项,例如 EC2 instance connect 或 SSM Session Manager。 听起来,无论我走哪条路,我都需要跳出纯 Terraform 解决方案。 EC2 Instance Connect 有一些承诺,但我怀疑理智的方法是完全放弃堡垒并允许用户直接进入他们的 EC2 实例进行批处理(这是堡垒允许访问的内容)。这是一种不同的蠕虫病毒,包括用尽弹性 IP。 【参考方案1】:

如果我理解这一点,你在这里问 2 个问题:

第一季度。有没有办法自动将用户添加到堡垒并设置他们的 ssh 凭据?

是的,您可以使用将在 ec2 创建期间运行的 userdata 脚本来执行此操作。

脚本应该添加用户。 假设您在堡垒服务器上运行 linux,添加用户的 sn-p 将类似于

useradd -m -s /bin/bash <username>
mkdir /home/<username>/.ssh
chmod 700 /home/<username>/.ssh/


Copy the ssh key from a pre-determined location. In my case i have ssh 
public keys for users in an S3 bucket (hey they are public keys)
aws s3 cp s3://path/pub-keys/user-id_rsa.pub /home/<username>/.ssh/authorized_keys

chmod 640 /home/<username>/.ssh/authorized_keys
chown -R <username>:<group> /home/<username>/.ssh/

Add the user to some group
usermod -a -G <somegroup> <username>

第二季度。 AWS IAM 凭证可以在某种单点登录上用于 ssh 吗? 为此,我建议阅读下面的文档,因为涉及到几件事,包括您正在使用的发行版。但我不确定这是否适合您描述的场景。

https://aws.amazon.com/blogs/compute/new-using-amazon-ec2-instance-connect-for-ssh-access-to-your-ec2-instances/

https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-connect-methods.html

【讨论】:

您的评估大致正确,但最终目标是堡垒采用与 IAM 用户关联的公共 SSH 密钥并将其用作授权用户的某种方式,当这些 IAM 用户或密钥发生更改时,那就是实时反映在堡垒上。我希望避免每次发生用户更改时都重建 AMI,或者通过脚本和 S3 管理公钥(这是您的建议,也是我考虑过的)。然而,似乎 EC2 Instance Connect 或类似方法可能是实现大多数目标的唯一明智的方法。 我最初误解了您的问题,并认为堡垒是短暂的,这就是我建议使用“userdata”脚本的原因。不幸的是,我看不到使用 terraform 的方法,我认为您将不得不使用 EC2 Instance Connect 或使用配置管理工具,例如 ansible。您还可以尝试使用 aws cli 并在堡垒上运行一些脚本,从 IAM 获取密钥,但这又是一个脚本。我想到的另一个想法是,在创建密钥时分发密钥,如果您使用一些自动化来创建密钥,那将很容易。 如果堡垒是短暂的,那会更容易,是的。对缺乏明确性表示歉意。看来我希望解决问题的方法是不现实的,所以我必须找到另一种方法。解决方案可能根本没有堡垒,并使用类似于 EC2 Direct Connect 的东西让用户直接附加到他们的临时批处理实例。 不,我为误读您的问题而道歉。我正在阅读您的其他 cmets,如果您只是将堡垒用作跳转主机,为什么不在 AWS 中创建 *** 并允许直接访问 EC2 实例。使用 ***,您可以保持 IP 的私密性,而您实际上并不需要堡垒。但老实说,您最初的问题要有趣得多:) 哈哈,同意,最初的问题更有趣,但我会在一周中的任何一天把简单的事情放在有趣的地方。 :-) 也许 *** 解决方案(或类似的东西,这样的公共子网,只允许流量进出我们控制的一组 IP 地址)是要走的路。

以上是关于在 Terraform 管理的 AWS EC2 SSH 堡垒实例上处理多个用户的 SSH 密钥的主要内容,如果未能解决你的问题,请参考以下文章

terraform 将文件复制/上传到 aws ec2 实例

通过Terraform aws ec2 import-image

使用 Terraform 代码创建 Ec2 实例,其中私钥将存储在 AWS 参数存储中(类型-安全字符串)

在另一个模块中为 EC2 添加指定子网 - AWS Terraform -

Terraform aws_autoscaling_group 启动的 AWS EC2 实例的动态命名

我可以在 terraform 创建的 ec2 实例中执行 ssh 吗?