

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 使用会话管理器和 Amazon Instance Connect 访问堡垒主 EC2 机
<a name="access-a-bastion-host-by-using-session-manager-and-amazon-ec2-instance-connect"></a>

*Piotr Chotkowski 和 Witold Kowalik，Amazon Web Services*

## Summary
<a name="access-a-bastion-host-by-using-session-manager-and-amazon-ec2-instance-connect-summary"></a>

*堡垒主机*（有时也称为*跳转盒*）是一种服务器，提供从外部网络到位于专用网络中的资源的单点访问。暴露在外部公共网络（如互联网）中的服务器会给未经授权的访问带来潜在的安全风险。保护和控制对这些服务器的访问非常重要。

此模式描述了如何使用[会话管理器](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager.html)和 [Amazon EC2 Instance Connect 安全地连接到](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Connect-using-EC2-Instance-Connect.html)部署在您的 AWS 账户中的亚马逊弹性计算云 (Amazon EC2) 堡垒主机。会话管理器是一项功能 AWS Systems Manager。此模式的优点包括：
+ 部署的堡垒主机没有任何向公共互联网公开的开放入站端口。这就减少了潜在的攻击面。
+ 您无需在中存储和维护长期安全外壳 (SSH) 密钥 AWS 账户。相反，每位用户每次连接到堡垒主机时都会生成一个新的 SSH key pair。 AWS Identity and Access Management 附加到用户 AWS 证书的 (IAM) 策略控制对堡垒主机的访问权限。

**目标受众**

这种模式适用于对亚马逊 EC2、亚马逊虚拟私有云（亚马逊 VPC）和 Hashicorp Terraform 有基本了解的读者。

## 先决条件和限制
<a name="access-a-bastion-host-by-using-session-manager-and-amazon-ec2-instance-connect-prereqs"></a>

**先决条件**
+ 活跃的 AWS 账户
+ AWS Command Line Interface (AWS CLI) 版本 2，[已安装](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html)并[配置](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html)
+ 的会话管理器插件 AWS CLI，[已安装](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html)
+ Terraform CLI，[已安装](https://developer.hashicorp.com/terraform/cli)
+ Terraform [状态](https://developer.hashicorp.com/terraform/language/state)的存储，例如充当远程后端来存储 Terraform 状态的 Amazon Simple Storage Service (Amazon S3) 桶和 Amazon DynamoDB 表。有关使用远程后端获得 Terraform 状态的更多信息，请参阅 [Amazon S3 后端](https://www.terraform.io/language/settings/backends/s3)（Terraform 文档）。有关使用 Amazon S3 后端设置远程状态管理的代码示例，请参阅 [remote-state-s3 后端](https://registry.terraform.io/modules/nozaq/remote-state-s3-backend/aws/latest)（Terraform Registry）。请注意以下要求：
  + Amazon S3 存储桶和 DynamoDB 表必须在同一个 AWS 区域中。
  + 创建 DynamoDB 表时，分区键必须为 `LockID`（区分大小写），并且分区键类型必须为 `String`。将所有其他设置保留为默认值。有关更多信息，请参阅 DynamoDB 文档中的[关于主键](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html#HowItWorks.CoreComponents.PrimaryKey)和[创建表](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/getting-started-step-1.html)。
+ SSH 客户端，已安装

**限制**
+ 该模式旨在作为概念证明(PoC)，或作为进一步开发的基础。不得将其当前形式用于生产环境。在部署之前，请调整存储库中的示例代码以满足您的要求和用例。
+ 此模式假定目标堡垒主机使用 Amazon Linux 2 作为其操作系统。虽然可以使用其他 Amazon 系统映像 (AMIs)，但其他操作系统超出了这种模式的范围。
**注意**  
即将终止对 Amazon Linux 2 的支持。欲了解更多信息，请参阅[亚马逊 Linux 2 FAQs](https://aws.amazon.com/amazon-linux-2/faqs/)。
+ 在此模式中，堡垒主机位于没有 NAT 网关和互联网网关的私有子网中。这种设计将 Amazon EC2 实例与公共互联网隔离开来。您可以添加特定的网络配置，使其能够与互联网进行通信。有关更多信息，请参阅 Amazon VPC 文档中的[将虚拟私有云（VPC）连接到其他网络](https://docs.aws.amazon.com/vpc/latest/userguide/extend-intro.html)。同样，遵循[最低权限原则](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege)， AWS 账户 除非您明确授予权限，否则堡垒主机无权访问您的任何其他资源。有关更多信息，请参阅 IAM 文档中的[基于资源的策略](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_resource-based)。

**产品版本**
+ AWS CLI 版本 2
+ Terraform 版本 1.3.9

## 架构
<a name="access-a-bastion-host-by-using-session-manager-and-amazon-ec2-instance-connect-architecture"></a>

**目标技术堆栈**
+ 具有单个私有子网的 VPC
+ 以下[接口 VPC 端点](https://docs.aws.amazon.com/vpc/latest/privatelink/create-interface-endpoint.html)：
  + `amazonaws.<region>.ssm`— AWS Systems Manager 服务的终端节点。
  + `amazonaws.<region>.ec2messages` – Systems Manager 使用此端点从 SSM 代理调用到 Systems Manager 服务。
  + `amazonaws.<region>.ssmmessages`— 会话管理器使用此终端节点通过安全数据通道连接到您的 Amazon EC2 实例。
+ 运行`t3.nano`亚马逊 Linux 的亚马逊 EC2 实例 2
+ IAM 角色与实例配置文件
+ 终端节点和亚马逊 EC2 实例的 Amazon VPC 安全组和安全组规则

**目标架构**

![\[使用会话管理器访问堡垒主机的架构图。\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/images/pattern-img/a02aed20-1852-4c91-902f-f553795006e2/images/819c503b-7eec-4a9c-862b-b87107d50dc1.png)


该图显示了以下过程：

1. 用户假定的 IAM 角色拥有执行以下操作的权限：
   + 对 Amazon EC2 实例进行身份验证、授权和连接
   + 使用会话管理器启动会话

1. 用户通过会话管理器启动 SSH 会话。

1. 会话管理器对用户进行身份验证，验证关联的 IAM policy 中的权限，检查配置设置，并向 SSM 代理发送消息以打开双向连接。

1. 用户通过 Amazon EC2 元数据将 SSH 公钥推送到堡垒主机。这必须在每次连接之前完成。SSH 公钥在 60 秒内保持可用。

1. 堡垒主机与 Systems Manager 和 Amazon 的接口 VPC 终端节点通信。 EC2

1. 用户使用 TLS 1.2 加密的双向通信通道通过会话管理器访问堡垒主机。

**自动化和扩缩**

以下选项可用于自动部署或扩缩此架构：
+ 您可以通过持续集成和持续交付（CI/CD）管道部署体系结构。
+ 您可以修改代码以更改堡垒主机的实例类型。
+ 您可以修改代码以部署多个堡垒主机。在 `bastion-host/main.tf` 文件的 `aws_instance` 资源块中，添加 `count` 元参数。有关更多信息，请参阅[ Terraform 文档](https://developer.hashicorp.com/terraform/language/meta-arguments/count)。

## 工具
<a name="access-a-bastion-host-by-using-session-manager-and-amazon-ec2-instance-connect-tools"></a>

**AWS 服务**
+ [AWS Command Line Interface (AWS CLI)](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) 是一个开源工具，可帮助您 AWS 服务 通过命令行 shell 中的命令进行交互。
+ [亚马逊弹性计算云 (Amazon EC2)](https://docs.aws.amazon.com/ec2/) 在中提供可扩展的计算容量 AWS 云。您可以根据需要启动任意数量的虚拟服务器，并快速纵向扩展或缩减这些服务器。
+ [AWS Identity and Access Management (IAM)](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html) 通过控制谁经过身份验证并有权使用 AWS 资源，从而帮助您安全地管理对资源的访问权限。
+ [AWS Systems Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/what-is-systems-manager.html) 可帮助您管理在 AWS 云端运行的应用程序和基础设施。它简化了应用程序和资源管理，缩短了检测和解决操作问题的时间，并帮助您大规模安全地管理 AWS 资源。此模式使用 [Session Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager.html)，这是 Systems Manager 的一项功能。
+ [Amazon Virtual Private Cloud（亚马逊 VPC）](https://docs.aws.amazon.com/vpc/latest/userguide/what-is-amazon-vpc.html)可帮助您将 AWS 资源启动到您定义的虚拟网络中。该虚拟网络类似于您在数据中心中运行的传统网络，并具有使用 AWS的可扩展基础设施的优势。

**其他工具**
+ [HashiCorp Terraform](https://www.terraform.io/docs) 是一款基础设施即代码（IaC）工具，可帮助您使用代码来预调配和管理云基础设施和资源。此模式使用 [Terraform CLI](https://developer.hashicorp.com/terraform/cli)。

**代码存储库**

此模式的代码可在[使用会话管理器 GitHub 访问堡垒主机和 Amazon EC2 Instance Connect](https://github.com/aws-samples/secured-bastion-host-terraform) 存储库中找到。

## 最佳实践
<a name="access-a-bastion-host-by-using-session-manager-and-amazon-ec2-instance-connect-best-practices"></a>
+ 我们建议使用自动代码扫描工具来提高代码的安全性和质量。使用 IaC 的静态代码分析工具 [Checkov](https://www.checkov.io/) 对该模式进行了扫描。我们至少建议您使用 `terraform validate` 和 `terraform fmt -check -recursive` Terraform 命令执行基本验证和格式检查。
+ 为 IaC 添加自动化测试是一种很好的做法。有关测试 Terraform 代码的不同方法的更多信息，请参阅[测试 Terraform（ HashiCorp Terraform 博客](https://www.hashicorp.com/blog/testing-hashicorp-terraform)文章）。
+ 在部署过程中，每次检测到新版本的亚马逊 [Linux 2 AMI 时，Terraform 都会使用替换的亚马逊 EC2 ](https://aws.amazon.com/marketplace/pp/prodview-zc4x2k7vt6rpu?sr=0-1&ref_=beagle&applicationId=AWSMPContessa)实例。这将部署新版本的操作系统，包括补丁和升级。如果未及时安排部署计划，可能会由于实例没有最新补丁而带来安全风险。经常更新已部署的 Amazon EC2 实例并对其应用安全补丁非常重要。有关更多信息，请参阅 [Amazon 中的更新管理 EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/update-management.html)。
+ 由于此模式是一种概念验证，因此它使用 AWS 托管策略，例如`AmazonSSMManagedInstanceCore`。 AWS 托管策略涵盖常见用例，但不授予最低权限权限。根据您的使用案例需要，我们建议您创建自定义策略，以便为此架构中部署的资源授予最低权限许可。有关更多信息，请参阅[开始使用 AWS 托管策略并转向最低权限权限](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#bp-use-aws-defined-policies)。
+ 使用密码来保护对 SSH 密钥的访问，并将密钥存储在安全位置。
+ 为堡垒主机设置日志记录和监控。从操作和安全角度来看，日志和监控都是维护系统的重要组成部分。有多种方法可以监控堡垒主机中的连接和活动。有关更多信息，请参阅 Systems Manager 文档中的以下主题：
  + [监控 AWS Systems Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/monitoring.html)
  + [登录和监控 AWS Systems Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/logging-and-monitoring.html)
  + [审核会话活动](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-auditing.html)
  + [记录会话活动](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-logging.html)

## 操作说明
<a name="access-a-bastion-host-by-using-session-manager-and-amazon-ec2-instance-connect-epics"></a>

### 部署资源
<a name="deploy-the-resources"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 克隆代码存储库。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/access-a-bastion-host-by-using-session-manager-and-amazon-ec2-instance-connect.html) | DevOps 工程师、开发人员 | 
| 初始化 Terraform 工作目录。 | 只有首次部署时才需要这一步骤。如果您要重新部署模式，请跳至下一步。在克隆存储库的根目录中，输入以下命令，其中：[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/access-a-bastion-host-by-using-session-manager-and-amazon-ec2-instance-connect.html)<pre>terraform init \<br />    -backend-config="bucket=$S3_STATE_BUCKET" \<br />    -backend-config="key=$PATH_TO_STATE_FILE" \<br />    -backend-config="region=$AWS_REGION</pre>您也可以打开 **config.tf** 文件，在 `terraform` 部分中手动填入这些值。 | DevOps 工程师、开发人员、Terraform | 
| 部署资源 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/access-a-bastion-host-by-using-session-manager-and-amazon-ec2-instance-connect.html) | DevOps 工程师、开发人员、Terraform | 

### 设置本地环境
<a name="set-up-the-local-environment"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 配置 SSH 连接。 | 更新 SSH 配置文件，允许通过会话管理器进行 SSH 连接。有关说明，请参阅[会话管理器允许的 SSH 连接](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-getting-started-enable-ssh-connections.html#ssh-connections-enable)。这允许授权用户输入启动会话管理器会话并通过双向连接传输所有数据的代理命令。 | DevOps 工程师 | 
| 生成 SSH 密钥。 | 输入以下命令生成本地私密和公共 SSH 密钥对。您可使用此密钥对连接到堡垒主机。<pre>ssh-keygen -t rsa -f my_key</pre> | DevOps 工程师、开发人员 | 

### 使用会话管理器连接到堡垒主机
<a name="connect-to-the-bastion-host-by-using-sesh"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 获取实例 ID。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/access-a-bastion-host-by-using-session-manager-and-amazon-ec2-instance-connect.html) | 常规 AWS | 
| 发送 SSH 公有密钥。 | 在本部分中，您需要将公有密钥上传到堡垒主机的[实例元数据](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html)中。上传密钥后，您有 60 秒的时间启动与堡垒主机的连接。60 秒后，公有密钥将被删除。有关更多信息，请参阅本模式的[疑难解答](#access-a-bastion-host-by-using-session-manager-and-amazon-ec2-instance-connect-troubleshooting)部分。快速完成后续步骤，以防止在连接到堡垒主机之前密钥被删除。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/access-a-bastion-host-by-using-session-manager-and-amazon-ec2-instance-connect.html) | 常规 AWS | 
| 连接到堡垒主机。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/access-a-bastion-host-by-using-session-manager-and-amazon-ec2-instance-connect.html)还有其他选项可用于打开与堡垒主机的 SSH 连接。有关更多信息，请参阅此模式的[其他信息](#access-a-bastion-host-by-using-session-manager-and-amazon-ec2-instance-connect-additional)部分中*与堡垒主机建立 SSH 连接的替代方法*。 | 常规 AWS | 

### (可选)清除
<a name="optional-clean-up"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 删除已部署的资源。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/access-a-bastion-host-by-using-session-manager-and-amazon-ec2-instance-connect.html) | DevOps 工程师、开发人员、Terraform | 

## 问题排查
<a name="access-a-bastion-host-by-using-session-manager-and-amazon-ec2-instance-connect-troubleshooting"></a>


| 问题 | 解决方案 | 
| --- | --- | 
| 尝试连接到堡垒主机时出现 `TargetNotConnected` 错误 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/access-a-bastion-host-by-using-session-manager-and-amazon-ec2-instance-connect.html) | 
| 尝试连接到堡垒主机时出现 `Permission denied` 错误 | 将公有密钥上传到堡垒主机后，您只有 60 秒的时间来启动连接。60 秒后，密钥将自动删除，您将无法使用它连接到实例。如果发生这种情况，您可以重复该步骤以将密钥重新发送到实例。 | 

## 相关资源
<a name="access-a-bastion-host-by-using-session-manager-and-amazon-ec2-instance-connect-resources"></a>

**AWS 文档**
+ [AWS Systems Manager Session Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager.html)（Systems Manager 文档）
+ [安装 AWS CLI的会话管理器插件](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html)（Systems Manager 文档）
+ [允许会话管理器的 SSH 连接](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-getting-started-enable-ssh-connections.html#ssh-connections-enable)（Systems Manager 文档）
+ [关于使用 Instan EC2 ce Connect](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Connect-using-EC2-Instance-Connect.html)（亚马逊 EC2 文档）
+ [使用 Instanc EC2 e Connect 进行连接](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-connect-methods.html)（亚马逊 EC2 文档）
+ 亚马逊@@ [的身份和访问管理 EC2（亚马逊](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/security-iam.html) EC2 文档）
+ [使用 IAM 角色向在 Amazon EC2 实例上运行的应用程序授予权限](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2.html)（IAM 文档）
+ [IAM 中的安全最佳实践](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html)（IAM 文档）
+ [使用安全组控制流量](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-security-groups.html)（Amazon VPC 文档）

**其他资源**
+ [Terraform 开发人员网页](https://developer.hashicorp.com/terraform)
+ [命令：验证](https://developer.hashicorp.com/terraform/cli/commands/validate)（Terraform 文档）
+ [命令：fmt](https://developer.hashicorp.com/terraform/cli/commands/fmt)（Terraform 文档）
+ [测试 HashiCorp Terraform](https://www.hashicorp.com/blog/testing-hashicorp-terraform)（HashiCorp 博客文章）
+ [Checkov 网页](https://www.checkov.io/)

## 附加信息
<a name="access-a-bastion-host-by-using-session-manager-and-amazon-ec2-instance-connect-additional"></a>

**与堡垒主机建立 SSH 连接的替代方法**

*端口转发*

您可以使用 `-D 8888` 选项打开具有动态端口转发的 SSH 连接。有关更多信息，请参阅 explainshell.com 上的[说明](https://explainshell.com/explain?cmd=ssh+-i+%24PRIVATE_KEY_FILE+-D+8888+ec2-user%40%24INSTANCE_ID)。以下是使用端口转发打开 SSH 连接的命令示例。

```
ssh -i $PRIVATE_KEY_FILE -D 8888 ec2-user@$INSTANCE_ID
```

此类连接会打开 SOCKS 代理，该代理可通过堡垒主机转发来自本地浏览器的流量。如果您使用的是 Linux 或 MacOS，要查看所有选项，请输入 `man ssh`。这将显示 SSH 参考手册。

*使用提供的脚本*

您可以使用代码存储库中包含的 **connect.sh** 脚本，无需手动运行[操作说明](#access-a-bastion-host-by-using-session-manager-and-amazon-ec2-instance-connect-epics)部分中*使用会话管理器连接到堡垒主机*中所描述的步骤。此脚本生成 SSH 密钥对，将公钥推送到 Amazon EC2 实例，并启动与堡垒主机的连接。运行脚本时，将标签和键名作为参数传递。以下是运行脚本的命令示例。

```
./connect.sh sandbox-dev-bastion-host my_key
```