

# NAT 实例
<a name="VPC_NAT_Instance"></a>

NAT 实例提供网络地址转换（NAT）。您可以使用 NAT 实例允许私有子网中的资源与虚拟私有云（VPC）之外的目标通信，例如互联网或本地网络。私有子网中的资源可以向互联网发起出站 IPv4 流量，但它们无法接收在互联网上发起的入站流量。

**重要**  
NAT AMI 基于 Amazon Linux AMI 的最新版本（2018.03）构建，该版本于 2020 年 12 月 31 日终止标准支持，并于 2023 年 12 月 31 日终止维护支持。有关更多信息，请参阅以下博客文章：[Amazon Linux AMI 生命周期终止](https://aws.amazon.com/blogs/aws/update-on-amazon-linux-ami-end-of-life/)。  
如果您使用现有的 NAT AMI，AWS建议您[迁移到 NAT 网关](vpc-nat-comparison.md#nat-instance-migrate)。NAT 网关可提供更高的可用性、更高的带宽，并且所需的管理工作更少。有关更多信息，请参阅 [比较 NAT 网关和 NAT 实例](vpc-nat-comparison.md)。  
如果 NAT 实例比 NAT 网关更适合您的使用案例，您可以从当前版本的 Amazon Linux 创建自己的 NAT AMI，如 [3. 创建 NAT AMI](work-with-nat-instances.md#create-nat-ami) 中所述。

**Topics**
+ [NAT 实例基础知识](#basics)
+ [允许私有资源在 VPC 外部进行通信](work-with-nat-instances.md)

## NAT 实例基础知识
<a name="basics"></a>

下图展示了 NAT 实例的基本信息。路由表与私有子网关联，并将来自私有子网中实例的互联网流量发送到公有子网中的 NAT 实例。然后，NAT 实例再将流量发送到互联网网关。流量由 NAT 实例的公有 IP 地址产生。NAT 实例为响应指定了一个较高的端口号；响应返回后，NAT 实例会根据响应的端口号将其发送给私有子网中的相应实例。

NAT 实例必须具有互联网访问权限，因此它必须位于公有子网（路由表中包含通往互联网网关的路由的子网）中，并且必须具有公有 IP 地址或弹性 IP 地址。

![\[该图显示的是在 VPC 中设置 NAT 实例\]](http://docs.aws.amazon.com/zh_cn/vpc/latest/userguide/images/nat-instance_updated.png)


要开始使用 NAT 实例，请创建 NAT AMI，为 NAT 实例创建安全组，然后将 NAT 实例启动到您的 VPC 中。

您的 NAT 实例配额取决于您在该区域的实例配额。有关更多信息，请参阅 *AWS 一般参考* 中的 [Amazon EC2 服务配额](https://docs.aws.amazon.com/general/latest/gr/ec2-service.html#limits_ec2)。

# 允许私有资源在 VPC 外部进行通信
<a name="work-with-nat-instances"></a>

本节旨在介绍如何创建并使用 NAT 实例，让私有子网中的资源能够在虚拟私有云之外进行通信。

**Topics**
+ [1. 为 NAT 实例创建 VPC](#create-vpc-subnets)
+ [2. 为 NAT 实例创建安全组](#NATSG)
+ [3. 创建 NAT AMI](#create-nat-ami)
+ [4. 启动 NAT 实例](#NATInstance)
+ [5. 禁用源/目标检查](#EIP_Disable_SrcDestCheck)
+ [6. 更新路由表](#nat-routing-table)
+ [7. 测试您的 NAT 实例](#nat-test-configuration)

## 1. 为 NAT 实例创建 VPC
<a name="create-vpc-subnets"></a>

使用以下过程创建具有公有和私有子网的 VPC。

**创建 VPC**

1. 通过 [https://console.aws.amazon.com/vpc/](https://console.aws.amazon.com/vpc/) 打开 Amazon VPC 控制台。

1. 选择**创建 VPC**。

1. 对于 **Resources to create**（要创建的资源），选择 **VPC and more**（VPC 等）。

1. 对于 **Name tag auto-generation**（名称标签自动生成），为 VPC 输入名称。

1. 若要配置子网，请执行以下操作：

   1. 对于 **Number of Availability Zones**（可用区域数量），根据您的需求选择 **1** 或 **2**。

   1. 对于 **Number of public subnets**（公有子网数量），确保每个可用区有一个公有子网。

   1. 对于 **Number of private subnets**（私有子网数量），确保每个可用区有一个私有子网。

1. 选择**创建 VPC**。

## 2. 为 NAT 实例创建安全组
<a name="NATSG"></a>

使用下表中描述的规则创建安全组。这些规则允许您的 NAT 实例从私有子网中的实例接收互联网范围流量以及来自您的网络的 SSH 流量。NAT 实例也可以向 Internet 发送流量，即允许私有子网中的实例获取软件更新。

以下是推荐的入站规则。


| 来源 | 协议 | 端口范围 | 注释 | 
| --- | --- | --- | --- | 
| 私有子网 CIDR | TCP | 80 | 允许来自私有子网服务器的入站 HTTP 数据流 | 
| 私有子网 CIDR | TCP | 443 | 允许来自私有子网服务器的入站 HTTPS 数据流 | 
| 您的网络的公有 IP 地址范围 | TCP | 22 | 允许从您的网络到 NAT 实例的入站 SSH 访问（通过互联网网关） | 

以下是推荐的出站规则。


| 目标 | 协议 | 端口范围 | 注释 | 
| --- | --- | --- | --- | 
| 0.0.0.0/0 | TCP | 80 | 允许对 Internet 进行出站 HTTP 访问 | 
| 0.0.0.0/0 | TCP | 443 | 允许对 Internet 进行出站 HTTPS 访问 | 

**创建安全组**

1. 通过 [https://console.aws.amazon.com/vpc/](https://console.aws.amazon.com/vpc/) 打开 Amazon VPC 控制台。

1. 在导航窗格中，选择**安全组**。

1. 选择**Create security group**（创建安全组）。

1. 输入安全组的名称和描述。

1. 对于 **VPC**，选择用于 NAT 实例的 VPC 的 ID。

1. 在**入站规则**下添加入站流量规则，如下所示：

   1. 选择**添加规则**。在**类型**中选择 **HTTP**，并在**源**中输入私有子网的 IP 地址范围。

   1. 选择**添加规则**。在**类型**中选择 **HTTPS**，并在**源**中输入私有子网的 IP 地址范围。

   1. 选择**添加规则**。在**类型**中选择 **SSH**，并在**源**中输入网络的 IP 地址范围。

1. 在**出站规则**下添加出站流量规则，如下所示：

   1. 选择**添加规则**。在**类型**中选择 **HTTP**，并在**目的地**中输入 0.0.0.0/0。

   1. 选择**添加规则**。在**类型**中选择 **HTTPS**，并在**目的地**中输入 0.0.0.0/0。

1. 选择**创建安全组**。

有关更多信息，请参阅 [安全组](vpc-security-groups.md)。

## 3. 创建 NAT AMI
<a name="create-nat-ami"></a>

NAT AMI 被配置为在 EC2 实例上运行 NAT。您必须先创建 NAT AMI，然后使用您的 NAT AMI 启动 NAT 实例。

如果您计划为 NAT AMI 使用 Amazon Linux 以外的操作系统，请参阅该操作系统的文档了解如何配置 NAT。请务必保存这些设置，以便其在实例重启后依然保持不变。

**为 Amazon Linux 创建 NAT AMI**

1. 启动运行 AL2023 或 Amazon Linux 2 的 EC2 实例。请务必指定为 NAT 实例创建的安全组。

1. 连接到实例并在实例上运行以下命令以启用 iptables。

   ```
   sudo yum install iptables-services -y
   sudo systemctl enable iptables
   sudo systemctl start iptables
   ```

1. 在实例上执行以下操作以启用 IP 转发，使其在重启后仍然存在：

   1. 使用文本编辑器（例如 **nano** 或 **vim**）创建以下配置文件：`/etc/sysctl.d/custom-ip-forwarding.conf`。

   1. 将以下行添加到配置文件。

      ```
      net.ipv4.ip_forward=1
      ```

   1. 保存配置文件，退出文本编辑器。

   1. 运行以下命令以应用配置文件。

      ```
      sudo sysctl -p /etc/sysctl.d/custom-ip-forwarding.conf
      ```

1. 在实例上运行以下命令，并记下主网络接口的名称。您在下一步中需要此信息。

   ```
   netstat -i
   ```

   在以下示例输出中，`docker0` 是 docker 创建的网络接口，`eth0` 是主网络接口，`lo` 是环回接口。

   ```
   Iface      MTU    RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg
   docker0   1500        0      0      0 0             0      0      0      0 BMU
   eth0      9001  7276052      0      0 0       5364991      0      0      0 BMRU
   lo       65536   538857      0      0 0        538857      0      0      0 LRU
   ```

   在以下示例输出中，主网络接口为 `enX0`。

   ```
   Iface      MTU    RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg
   enX0      9001     1076      0      0 0          1247      0      0      0 BMRU
   lo       65536       24      0      0 0            24      0      0      0 LRU
   ```

   在以下示例输出中，主网络接口为 `ens5`。

   ```
   Iface      MTU    RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg
   ens5      9001    14036      0      0 0          2116      0      0      0 BMRU
   lo       65536       12      0      0 0            12      0      0      0 LRU
   ```

1. 在实例上运行以下命令以配置 NAT。如果主网络接口不是 `eth0`，请将 *eth0* 替换为您在上一步中记下的主网络接口。

   ```
   sudo /sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
   sudo /sbin/iptables -F FORWARD
   sudo service iptables save
   ```

1. 然后，从 EC2 实例创建 NAT AMI。有关更多信息，请参阅《*Amazon EC2 用户指南*》中的[从实例创建 Linux AMI](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/creating-an-ami-ebs.html#how-to-create-ebs-ami)。

## 4. 启动 NAT 实例
<a name="NATInstance"></a>

按照以下步骤使用您创建的 VPC、安全组和 NAT AMI 启动 NAT 实例。

**启动 NAT 实例**

1. 通过以下网址打开 Amazon EC2 控制台：[https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/)。

1. 在控制面板上，选择**启动实例**。

1. 对于**名称**，输入您的 NAT 实例名称。

1. 对于**应用程序和操作系统映像**，选择您的 NAT AMI（选择**浏览更多 AMI**、**我的 AMI**）。

1. 对于**实例类型**，选择选择一个实例类型，以提供 NAT 实例所需的计算、内存和存储资源。

1. （可选）对于**密钥对**，选择一个现有密钥对或选择**创建新密钥对**。

1. 对于 **Network settings**（网络设置），执行以下操作：

   1. 选择**编辑**。

   1. 对于 **VPC**，选择已创建的 VPC。

   1. 对于**子网**，选择您创建的公有子网。

   1. 对于 **Auto-assign public IP**（自动分配公有 IP），选择 **Enable**（启用）。或者在启动 NAT 实例后，分配一个弹性 IP 地址并将其分配给 NAT 实例。

   1. 对于**防火墙**，选择**选择现有安全组**，然后选择您创建的安全组。

1. 选择**启动实例**。选择实例 ID 以打开实例详细信息页面。等待实例状态变为**正在运行**，并等待状态检查成功。

1. 禁用 NAT 实例的源/目的地检查（参阅 [5. 禁用源/目标检查](#EIP_Disable_SrcDestCheck)）。

1. 更新路由表以将流量发送至 NAT 实例（参阅 [6. 更新路由表](#nat-routing-table)）。

## 5. 禁用源/目标检查
<a name="EIP_Disable_SrcDestCheck"></a>

每项 EC2 实例都会默认执行源/目标检查。这意味着实例必须为其发送或接收的数据流的源头或目标。但是，NAT 实例必须能够在源或目标并非其本身时发送和接收数据流。因此，您必须禁用 NAT 实例的源/目标检查。

**禁用源/目的地检查**

1. 通过以下网址打开 Amazon EC2 控制台：[https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/)。

1. 在导航窗格中，选择 **Instances (实例)**。

1. 选择 NAT 实例。

1. 依次选择**操作**、**联网**、**更改源/目的地检查**。

1. 对于**源/目的地检查**，请选择**停止**。

1. 选择**保存**。

1. 如果 NAT 实例有辅助网络接口，请从**联网**选项卡上的**网络接口**选择接口。选择接口 ID 以转至网络接口页面。选择**操作**、**更改源/目标检查**，清除**启用**，然后选择**保存**。

## 6. 更新路由表
<a name="nat-routing-table"></a>

私有子网的路由表必须有一个将互联网流量发送到 NAT 实例的路由。

**更新路由表**

1. 通过 [https://console.aws.amazon.com/vpc/](https://console.aws.amazon.com/vpc/) 打开 Amazon VPC 控制台。

1. 在导航窗格中，选择 **Route tables**（路由表）。

1. 选择私有子网的路由表。

1. 在**路由**选项卡中选择**编辑路由**，然后选择**添加路由**。

1. 在**目的地**中输入 0.0.0.0/0，并在**目标**中输入 NAT 实例的实例 ID。

1. 选择**保存更改**。

有关更多信息，请参阅 [配置路由表](VPC_Route_Tables.md)。

## 7. 测试您的 NAT 实例
<a name="nat-test-configuration"></a>

启动 NAT 实例并完成以上配置步骤之后，您可以测试私有子网中的实例是否可以通过将 NAT 实例用作堡垒机服务器来访问互联网。

**Topics**
+ [步骤 1：更新 NAT 实例安全组](#nat-test-security)
+ [步骤 2：在私有子网中启动测试实例](#nat-test-launch-instance)
+ [步骤 3：Ping 启用了 ICMP 的网站](#nat-test-ping)
+ [步骤 4：清除](#nat-test-clean-up)

### 步骤 1：更新 NAT 实例安全组
<a name="nat-test-security"></a>

如需允许私有子网中的实例向 NAT 实例发送 ping 流量，请添加一个规则来允许入站和出站 ICMP 流量。要允许 NAT 实例用作堡垒机服务器，请添加一个规则以允许出站 SSH 流量流向私有子网。

**更新 NAT 实例安全组**

1. 通过 [https://console.aws.amazon.com/vpc/](https://console.aws.amazon.com/vpc/) 打开 Amazon VPC 控制台。

1. 在导航窗格中，选择**安全组**。

1. 选择与 NAT 实例关联的安全组的复选框。

1. 在 **Inbound Rules (入站规则)** 选项卡上，选择 **Edit inbound rules (编辑入站规则)**。

1. 选择 **Add rule**。对于**类型**，选择**所有 ICMP - IPv4**。对于**源**，选择**自定义**，输入您的私有子网的 IP 地址范围。选择**保存规则**。

1. 在**出站规则**选项卡上，选择**编辑出站规则**。

1. 选择 **Add rule**。对于**类型**，选择 **SSH**。对于**目的地**，选择**自定义**，并输入您的私有子网的 IP 地址范围。

1. 选择 **Add rule**。对于**类型**，选择**所有 ICMP - IPv4**。为 **Destination (目的地)** 选择 **Anywhere - IPv4 (任何位置 – IPv4)**。选择**保存规则**。

### 步骤 2：在私有子网中启动测试实例
<a name="nat-test-launch-instance"></a>

在您的私有子网中启动实例。您必须允许从 NAT 实例进行 SSH 访问，并且必须使用用于 NAT 实例的相同密钥对。

**在私有子网中启动测试实例**

1. 通过以下网址打开 Amazon EC2 控制台：[https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/)。

1. 在控制面板上，选择**启动实例**。

1. 选择您的私有子网。

1. 请勿向此实例分配公有 IP 地址。

1. 确保此实例的安全组允许来自您的 NAT 实例或公有子网的 IP 地址范围的入站 SSH 访问以及出站 ICMP 流量。

1. 选择用于 NAT 实例的相同密钥对。

### 步骤 3：Ping 启用了 ICMP 的网站
<a name="nat-test-ping"></a>

要验证私有子网中的测试实例是否可以使用 NAT 实例与互联网通信，请运行 **ping** 命令。

**从您的私有实例测试互联网连接**

1. 在本地计算机上，配置 SSH 代理转发，以便您可以将 NAT 实例用作堡垒机服务器。

------
#### [ Linux and macOS ]

   ```
   ssh-add key.pem
   ```

------
#### [ Windows ]

   [下载并安装 Pageant](https://www.chiark.greenend.org.uk/~sgtatham/putty/)（如果尚未安装）。

   [使用 PuTTYgen 转换私有密钥](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/connect-linux-inst-from-windows.html#putty-private-key)。

   启动 Pageant，右键单击任务栏上的 **Pageant** 图标（可能已隐藏），并选择**添加密钥**。选择您创建的 .ppk 文件，输入密码（如果需要），然后选择**打开**。

------

1. 从本地计算机连接到您的 NAT 实例。

------
#### [ Linux and macOS ]

   ```
   ssh -A ec2-user@nat-instance-public-ip-address
   ```

------
#### [ Windows ]

   使用 PuTTY 连接到您的 NAT 实例。对于**身份验证**，您必须选择**允许代理转发**，然后将**用于身份验证的私有密钥文件**留空。

------

1. 在 NAT 实例中，运行 **ping** 命令，指定启用 ICMP 的网站。

   ```
   [ec2-user@ip-10-0-4-184]$ ping ietf.org
   ```

   要确认您的 NAT 实例可以访问互联网，请验证您是否收到了如下输出，然后按 **Ctrl\$1C** 取消 **ping** 命令。否则，验证 NAT 实例是否在公有子网中（其路由表有通往互联网网关的路由）。

   ```
   PING ietf.org (104.16.45.99) 56(84) bytes of data.
   64 bytes from 104.16.45.99 (104.16.45.99): icmp_seq=1 ttl=33 time=7.88 ms
   64 bytes from 104.16.45.99 (104.16.45.99): icmp_seq=2 ttl=33 time=8.09 ms
   64 bytes from 104.16.45.99 (104.16.45.99): icmp_seq=3 ttl=33 time=7.97 ms
   ...
   ```

1. 从您的 NAT 实例，使用私有 IP 地址连接到您私有子网中的实例。

   ```
   [ec2-user@ip-10-0-4-184]$ ssh ec2-user@private-server-private-ip-address
   ```

1. 从您的私有实例，通过运行 **ping** 命令来测试您是否可以连接到互联网：

   ```
   [ec2-user@ip-10-0-135-25]$ ping ietf.org
   ```

   要确认您的私有实例可以通过 NAT 实例访问互联网，请验证您是否收到了如下输出，然后按 **Ctrl\$1C** 取消 **ping** 命令。

   ```
   PING ietf.org (104.16.45.99) 56(84) bytes of data.
   64 bytes from 104.16.45.99 (104.16.45.99): icmp_seq=1 ttl=33 time=8.76 ms
   64 bytes from 104.16.45.99 (104.16.45.99): icmp_seq=2 ttl=33 time=8.26 ms
   64 bytes from 104.16.45.99 (104.16.45.99): icmp_seq=3 ttl=33 time=8.27 ms
   ...
   ```

**问题排查**

如果从私有子网中的服务器发出的 **ping** 命令失败，请使用以下步骤来进行问题排查：
+ 验证您对启用了 ICMP 的网站执行了 Ping 操作。如果未执行，您的服务器将无法接收应答数据包。要对此进行测试，请从您自己计算机上的命令行终端运行相同的 **ping** 命令。
+ 验证 NAT 实例的安全组是否允许来自私有子网的入站 ICMP 流量。如果不允许，则您的 NAT 实例无法从私有实例接收 **ping** 命令。
+ 验证您对 NAT 实例禁用了源/目的地检查。有关更多信息，请参阅 [5. 禁用源/目标检查](#EIP_Disable_SrcDestCheck)。
+ 验证您正确配置了路由表。有关更多信息，请参阅 [6. 更新路由表](#nat-routing-table)。

### 步骤 4：清除
<a name="nat-test-clean-up"></a>

如果您不再需要私有子网中的测试服务器，请终止该实例，这样您就不再为此付费。有关更多信息，请参阅《Amazon EC2 用户指南》中的 [终止实例](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/terminating-instances.html)**。

如果您不再需要 NAT 实例，则可以停止或终止它，这样您就不再为此付费。如果您创建了一个 NAT AMI，则可以在需要时创建新的 NAT 实例。