使用 Amazon CLI 创建双栈 VPC 和子网 - Amazon Virtual Private Cloud
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

使用 Amazon CLI 创建双栈 VPC 和子网

以下示例使用 Amazon CLI 命令创建具有 IPv6 CIDR 块的非默认 VPC、公有子网和只有出站互联网访问权限的私有子网。在您创建了 VPC 和子网后,您可以在公有子网中启动实例,然后连接到该实例。您可以在私有子网中启动实例,并验证其能否连接到 Internet。

您将创建以下Amazon资源:

  • 一个 VPC

  • 两个子网

  • 一个互联网网关

  • 一个路由表

  • 一个 EC2 实例

先决条件

在开始之前,请安装并配置 Amazon CLI。在配置 Amazon CLI 时,指定您的 Amazon 凭证。本教程中的示例假定您已配置默认区域。否则,请为每个命令添加 --region 选项。有关更多信息,请参阅安装或更新 Amazon CLI配置 Amazon CLI

步骤 1:创建 VPC 和子网

第一步是创建 VPC 和两个子网。此示例对 VPC 使用 IPv4 CIDR 块 10.0.0.0/16,但您可以选择其他 CIDR 块。有关更多信息,请参阅VPC CIDR 块

使用 Amazon CLI 创建 VPC 和子网
  1. 创建具有 10.0.0.0/16 CIDR 块的 VPC,并向此 VPC 关联 IPv6 CIDR 块。

    aws ec2 create-vpc --cidr-block 10.0.0.0/16 --amazon-provided-ipv6-cidr-block

    在返回的输出中,记录 VPC ID。

    { "Vpc": { "VpcId": "vpc-2f09a348", ... }
  2. 描述您的 VPC 以获取与 VPC 关联的 IPv6 CIDR 块。

    aws ec2 describe-vpcs --vpc-id vpc-2f09a348
    { "Vpcs": [ { ... "Ipv6CidrBlockAssociationSet": [ { "Ipv6CidrBlock": "2001:db8:1234:1a00::/56", "AssociationId": "vpc-cidr-assoc-17a5407e", "Ipv6CidrBlockState": { "State": "ASSOCIATED" } } ], ... }
  3. (从上一步中返回的范围) 创建具有 10.0.0.0/24 IPv4 CIDR 块和 2001:db8:1234:1a00::/64 IPv6 CIDR 块的子网。

    aws ec2 create-subnet --vpc-id vpc-2f09a348 --cidr-block 10.0.0.0/24 --ipv6-cidr-block 2001:db8:1234:1a00::/64
  4. 在 VPC 中创建第二个具有 10.0.1.0/24 IPv4 CIDR 块和 2001:db8:1234:1a01::/64 IPv6 CIDR 块的子网。

    aws ec2 create-subnet --vpc-id vpc-2f09a348 --cidr-block 10.0.1.0/24 --ipv6-cidr-block 2001:db8:1234:1a01::/64

步骤 2:配置公有子网

在创建 VPC 和子网后,您可以将互联网网关连接到您的 VPC,创建自定义路由表,并为子网配置到互联网网关的路由,从而使其中一个子网成为公有子网。此示例创建一个将所有 IPv4 流量和 IPv6 流量路由到互联网网关的路由表。

使您的子网成为公有子网
  1. 创建互联网网关。

    aws ec2 create-internet-gateway

    在返回的输出中,记录互联网网关 ID。

    { "InternetGateway": { ... "InternetGatewayId": "igw-1ff7a07b", ... } }
  2. 使用上一步中的 ID 将互联网网关连接到您的 VPC。

    aws ec2 attach-internet-gateway --vpc-id vpc-2f09a348 --internet-gateway-id igw-1ff7a07b
  3. 为您的 VPC 创建自定义路由表。

    aws ec2 create-route-table --vpc-id vpc-2f09a348

    在返回的输出中,记录路由表 ID。

    { "RouteTable": { ... "RouteTableId": "rtb-c1c8faa6", ... } }
  4. 在路由表中创建一个将所有 IPv6 流量 (::/0) 指向互联网网关的路由。

    aws ec2 create-route --route-table-id rtb-c1c8faa6 --destination-ipv6-cidr-block ::/0 --gateway-id igw-1ff7a07b
    注意

    如果要将公有子网用于 IPv4 流量,则需要再添加一个用于指向互联网网关的 0.0.0.0/0 流量的路由。

  5. 要确认您的路由已创建并且处于活动状态,您可以描述路由表并查看结果。

    aws ec2 describe-route-tables --route-table-id rtb-c1c8faa6
    { "RouteTables": [ { "Associations": [], "RouteTableId": "rtb-c1c8faa6", "VpcId": "vpc-2f09a348", "PropagatingVgws": [], "Tags": [], "Routes": [ { "GatewayId": "local", "DestinationCidrBlock": "10.0.0.0/16", "State": "active", "Origin": "CreateRouteTable" }, { "GatewayId": "local", "Origin": "CreateRouteTable", "State": "active", "DestinationIpv6CidrBlock": "2001:db8:1234:1a00::/56" }, { "GatewayId": "igw-1ff7a07b", "Origin": "CreateRoute", "State": "active", "DestinationIpv6CidrBlock": "::/0" } ] } ] }
  6. 路由表当前未与任何子网相关联。将它与您 VPC 中的子网进行关联,以便将来自该子网的流量路由到互联网网关。首先,描述您的子网,以便获得它们的 ID。您可以使用 --filter 选项仅返回新 VPC 的子网,使用 --query 选项仅返回子网 ID 及其 IPv4 和 IPv6 CIDR 块。

    aws ec2 describe-subnets --filters "Name=vpc-id,Values=vpc-2f09a348" --query "Subnets[*].{ID:SubnetId,IPv4CIDR:CidrBlock,IPv6CIDR:Ipv6CidrBlockAssociationSet[*].Ipv6CidrBlock}"
    [ { "IPv6CIDR": [ "2001:db8:1234:1a00::/64" ], "ID": "subnet-b46032ec", "IPv4CIDR": "10.0.0.0/24" }, { "IPv6CIDR": [ "2001:db8:1234:1a01::/64" ], "ID": "subnet-a46032fc", "IPv4CIDR": "10.0.1.0/24" } ]
  7. 您可以选择将哪个子网与自定义路由表进行关联,例如 subnet-b46032ec。此子网将是您的公有子网。

    aws ec2 associate-route-table --subnet-id subnet-b46032ec --route-table-id rtb-c1c8faa6

步骤 3:配置仅出口私有子网

您可以将 VPC 中的第二个子网配置为 IPv6 仅出口私有子网。在此子网中启动的实例能够通过仅出口互联网网关经由 IPv6 访问 Internet(如获取软件更新),但 Internet 上的主机无法访问您的实例。

使子网成为仅出口私有子网
  1. 为您的 VPC 创建仅出口互联网网关。在返回的输出中,记录 网关 ID。

    aws ec2 create-egress-only-internet-gateway --vpc-id vpc-2f09a348
    { "EgressOnlyInternetGateway": { "EgressOnlyInternetGatewayId": "eigw-015e0e244e24dfe8a", "Attachments": [ { "State": "attached", "VpcId": "vpc-2f09a348" } ] } }
  2. 为您的 VPC 创建自定义路由表。在返回的输出中,记录路由表 ID。

    aws ec2 create-route-table --vpc-id vpc-2f09a348
  3. 在路由表中创建一个将所有 IPv6 流量 (::/0) 指向仅出口 Internet 网关的路由。

    aws ec2 create-route --route-table-id rtb-abc123ab --destination-ipv6-cidr-block ::/0 --egress-only-internet-gateway-id eigw-015e0e244e24dfe8a
  4. 将路由表与 VPC 中的第二个子网 (上一节描述的子网) 关联。此子网将成为具有仅出口 IPv6 Internet 访问权限的私有子网。

    aws ec2 associate-route-table --subnet-id subnet-a46032fc --route-table-id rtb-abc123ab

步骤 4:修改子网的 IPv6 寻址行为

您可以修改子网的公有 IP 寻址行为,以便在子网中启动的实例能够自动接收 IPv6 地址。当您在子网中启动实例时,系统将子网范围中的一个 IPv6 地址分配给该实例的主网络接口 (eth0)。

aws ec2 modify-subnet-attribute --subnet-id subnet-b46032ec --assign-ipv6-address-on-creation
aws ec2 modify-subnet-attribute --subnet-id subnet-a46032fc --assign-ipv6-address-on-creation

步骤 5:在公有子网中启动实例

要测试您的公有子网是公有子网并且其中的实例可通过 Internet 访问,请在您的公有子网中启动一个实例,然后连接到该实例。首先,您必须创建一个与您实例进行关联的安全组,以及在您连接到该实例时将使用的密钥对。有关安全组的更多信息,请参阅 使用安全组控制到资源的流量。有关密钥对的更多信息,请参阅适用于 Linux 实例的 Amazon EC2 用户指南 中的 Amazon EC2 密钥对

在您的公有子网中启动并连接到一个实例
  1. 创建一个密钥对,使用 --query 选项和 --output 文本选项将您的私有密钥通过管道直接发送到扩展名为 .pem 的文件中。

    aws ec2 create-key-pair --key-name MyKeyPair --query "KeyMaterial" --output text > MyKeyPair.pem

    在此示例中,启动一个 Amazon Linux 实例。如果您在 Linux 或 OS X 操作系统上使用 SSH 客户端连接到您的实例,请使用以下命令设置您的私有密钥文件的权限,以确保只有您可以读取该文件。

    chmod 400 MyKeyPair.pem
  2. 使用 create-security-group 命令为您的 VPC 创建安全组。

    aws ec2 create-security-group --group-name SSHAccess --description "Security group for SSH access" --vpc-id vpc-2f09a348
    { "GroupId": "sg-e1fb8c9a" }

    使用 authorize-security-group-ingress 命令,添加允许从任意 IPv6 地址访问 SSH 的规则。请注意,以下语法仅适用于 Linux 和 macOS。对于适用于 Windows 的语法,请参阅 Amazon CLI 命令参考中的示例部分。

    aws ec2 authorize-security-group-ingress --group-id sg-e1fb8c9a --ip-permissions '[{"IpProtocol": "tcp", "FromPort": 22, "ToPort": 22, "Ipv6Ranges": [{"CidrIpv6": "::/0"}]}]'
    注意

    如果使用 ::/0,则可以允许所有 IPv6 地址使用 SSH 访问您的实例。对于这个简短的练习来说这是可接受的,但在生产中,仅授权特定 IP 地址或地址范围访问您的实例。

  3. 使用您创建的安全组和密钥对在您的公有子网中启动一个实例。在输出中,记录您实例的实例 ID。

    aws ec2 run-instances --image-id ami-0de53d8956e8dcf80 --count 1 --instance-type t2.micro --key-name MyKeyPair --security-group-ids sg-e1fb8c9a --subnet-id subnet-b46032ec
    注意

    在此示例中,AMI 是美国东部(弗吉尼亚北部)区域中的 Amazon Linux AMI。如果您在其他区域,则需要适合您区域的 AMI 的 AMI ID。有关更多信息,请参阅适用于 Linux 实例的 Amazon EC2 用户指南中的查找 Linux AMI

  4. 您的实例必须处于 running 状态才能连接到该实例。描述您的实例并确认其状态,然后记录其 IPv6 地址。

    aws ec2 describe-instances --instance-id i-0146854b7443af453

    下面是示例输出。

    { "Reservations": [ { ... "Instances": [ { ... "State": { "Code": 16, "Name": "running" }, ... "NetworkInterfaces": { "Ipv6Addresses": { "Ipv6Address": "2001:db8:1234:1a00::123" } ... } ] } ] }
  5. 当您的实例处于运行状态时,您可以通过使用以下命令,在 Linux 或 OS X 计算机上使用 SSH 客户端连接到该实例。您的本地计算机必须已配置 IPv6 地址。

    ssh -i "MyKeyPair.pem" ec2-user@2001:db8:1234:1a00::123

    如果您从 Windows 计算机连接,请遵循以下说明:使用 PuTTY 从 Windows 连接到您的 Linux 实例

步骤 6:在私有子网中启动实例

要测试仅出口私有子网中的实例能否访问 Internet,请在私有子网中启动一个实例,并使用公有子网中的堡垒实例连接该实例 (可以使用在上节中启动的实例)。首先,您必须为此实例创建安全组。此安全组必须具有允许您的堡垒实例使用 SSH 进行连接的规则,以及允许使用 ping6 命令 (ICMPv6 流量) 来确保实例不能从 Internet 访问的规则。

  1. 使用 create-security-group 命令在您的 VPC 中创建安全组。

    aws ec2 create-security-group --group-name SSHAccessRestricted --description "Security group for SSH access from bastion" --vpc-id vpc-2f09a348

    使用 authorize-security-group-ingress 命令,添加允许从公有子网中实例的 IPv6 地址进行入站 SSH 访问的规则,以及允许所有 ICMPv6 流量的规则。请注意,以下语法仅适用于 Linux 和 macOS。对于适用于 Windows 的语法,请参阅 Amazon CLI 命令参考中的示例部分。

    { "GroupId": "sg-aabb1122" }
    aws ec2 authorize-security-group-ingress --group-id sg-aabb1122 --ip-permissions '[{"IpProtocol": "tcp", "FromPort": 22, "ToPort": 22, "Ipv6Ranges": [{"CidrIpv6": "2001:db8:1234:1a00::123/128"}]}]'
    aws ec2 authorize-security-group-ingress --group-id sg-aabb1122 --ip-permissions '[{"IpProtocol": "58", "FromPort": -1, "ToPort": -1, "Ipv6Ranges": [{"CidrIpv6": "::/0"}]}]'
  2. 使用您创建的安全组和用于在公有子网中启动实例的密钥对在私有子网中启动一个实例。

    aws ec2 run-instances --image-id ami-a4827dc9 --count 1 --instance-type t2.micro --key-name MyKeyPair --security-group-ids sg-aabb1122 --subnet-id subnet-a46032fc

    使用 describe-instances 命令验证您的实例正在运行并获取其 IPv6 地址。

  3. 在本地计算机上配置 SSH 代理转发,然后连接到公有子网中的实例。

    对于 Linux,请使用以下命令:

    ssh-add MyKeyPair.pem ssh -A ec2-user@2001:db8:1234:1a00::123

    对于 OS X,请使用以下命令:

    ssh-add -K MyKeyPair.pem ssh -A ec2-user@2001:db8:1234:1a00::123

    对于 Windows,请使用以下说明:针对 Windows (PuTTY) 配置 SSH 代理转发。使用 IPv6 地址连接公有子网中的实例。

  4. 从公有子网中的实例 (堡垒实例),使用 IPv6 地址连接私有子网中的实例:

    ssh ec2-user@2001:db8:1234:1a01::456
  5. 在私有实例中,通过对支持 ICMP 的网站运行 ping6 命令来测试是否可以连接到 Internet,例如:

    ping6 -n ietf.org
    PING ietf.org(2001:1900:3001:11::2c) 56 data bytes 64 bytes from 2001:1900:3001:11::2c: icmp_seq=1 ttl=46 time=73.9 ms 64 bytes from 2001:1900:3001:11::2c: icmp_seq=2 ttl=46 time=73.8 ms 64 bytes from 2001:1900:3001:11::2c: icmp_seq=3 ttl=46 time=73.9 ms ...
  6. 要测试 Internet 上的主机能否访问私有子网中的实例,请在启用 IPv6 的计算机上使用 ping6 命令。您应收到超时响应。如果您获得有效响应,则可从 Internet 访问您的实例 — 检查与私有子网关联的路由表,并验证此表是否没有针对流入互联网网关的 IPv6 流量的路由。

    ping6 2001:db8:1234:1a01::456

步骤 7:清除

在验证您可以连接到公有子网中的实例,并且私有子网中的实例能够访问 Internet 后,如果不再需要这些实例,可将其终止。要执行此操作,请使用 terminate-instances 命令。要删除您在此示例中创建的其他资源,请按列出的顺序使用以下命令:

  1. 删除您的安全组:

    aws ec2 delete-security-group --group-id sg-e1fb8c9a
    aws ec2 delete-security-group --group-id sg-aabb1122
  2. 删除您的子网:

    aws ec2 delete-subnet --subnet-id subnet-b46032ec
    aws ec2 delete-subnet --subnet-id subnet-a46032fc
  3. 删除您的自定义路由表:

    aws ec2 delete-route-table --route-table-id rtb-c1c8faa6
    aws ec2 delete-route-table --route-table-id rtb-abc123ab
  4. 将您的互联网网关与您的 VPC 分离:

    aws ec2 detach-internet-gateway --internet-gateway-id igw-1ff7a07b --vpc-id vpc-2f09a348
  5. 删除您的互联网网关:

    aws ec2 delete-internet-gateway --internet-gateway-id igw-1ff7a07b
  6. 删除您的仅出口互联网网关:

    aws ec2 delete-egress-only-internet-gateway --egress-only-internet-gateway-id eigw-015e0e244e24dfe8a
  7. 删除您的 VPC:

    aws ec2 delete-vpc --vpc-id vpc-2f09a348