Skip to main content

Enable IPv6 on a VPC with a Private Subnet and Egress-Only Internet Gateway

Hands-On Lab

 

Photo of Tia  Williams

Tia Williams

AWS Training Architect II in Content

Length

01:00:00

Difficulty

Intermediate

All IPv6 addresses are public by default. But sometimes there's a need to keep instances private. In this hands-on lab we are going to enable IPv6 on a VPC. We will then configure a subnet to be private, and then validate that our instance will not be accessible over the internet over IPv6. NOTE: If you do not have IPv6 in your environment, please consider using Linux Academy Cloud Playground to validate the IPv6 connectivity.

What are Hands-On Labs?

Hands-On Labs are scenario-based learning environments where learners can practice without consequences. Don't compromise a system or waste money on expensive downloads. Practice real-world skills without the real-world risk, no assembly required.

Enable IPv6 on a VPC with a Private Subnet and Egress-Only Internet Gateway

Introduction

All IPv6 addresses are public by default. But sometimes there's a need to keep instances private. In this hands-on lab we are going to enable IPv6 on a VPC. We will then configure a subnet to be private, and then validate that our instance will not be accessible over the internet over IPv6.

Get logged in

Use the credentials and server IP in the hands-on lab overview page to log into AWS Console. Once we're in, let's make sure we're in the us-east-1 region, and then we can get moving.

Enable IPv6 on the VPC

First off, let's get into the VPC (by either browsing or searching the Services menu) and clicking Your VPCs in the left-hand menu. Highlight the one that's been provisioned for us (the only one there), then select Edit CIRDs from the Actions menu. In the screen that follows, click Add IPv6 CIDR. We'll get one, then we can click Close.

Farther down the left-hand menu, let's click on Network ACLs in the Security section. We've got one with two subnets in it. If we hover over its Name column, a pencil shows up that we can click on. We're just going to call it LA_NACL1.

NACL Inbound rules

Down in the lower half of the screen, we'll get into the Inbound Rules tab. We need ping traffic coming in, so click Edit inbound rules, then Add Rule. Give it these specs:

  • Rule #: 105
  • Type: ALL ICMP - IPv4
  • Protocol: ICMP (1)
  • Port Range: ALL
  • Source: 0.0.0.0/0
  • Allow / Deny: ALLOW

Now let's add another rule, this time with these specs:

  • Rule #: 110
  • Type: ALL ICMP - IPv6
  • Protocol: IPv6-ICMP (58)
  • Port Range: ALL
  • Source: ::/0
  • Allow / Deny: ALLOW

We're on a roll. Let's make another more:

  • Rule #: 115
  • Type: Custom TCP Rule
  • Protocol: TCP (6)
  • Port Range: 1024-65535
  • Source: ::/0
  • Allow / Deny: ALLOW

We can't stop there, we still need to allow IPv6 SSH:

  • Rule #: 120
  • Type: SSH (22)
  • Protocol: TCP (6)
  • Port Range: 22
  • Source: ::/0
  • Allow / Deny: ALLOW

Okay, we're done with inbound rules, for real this time.

NACL Outbound rules

We've only got to make two more, one each (IPv4 and v6) for ICMP. Set these two rules:

IPv4

  • Rule #: 105
  • Type: ALL ICMP - IPv4
  • Protocol: ICMP (1)
  • Port Range: ALL
  • Destination: 0.0.0.0/0
  • Allow / Deny: ALLOW

IPv6

  • Rule #: 110
  • Type: ALL ICMP - IPv6
  • Protocol: IPv6-ICMP (58)
  • Port Range: ALL
  • Destination: ::/0
  • Allow / Deny: ALLOW

We're going to create some rules for Security groups next, so navigate to them in the left-hand menu (they're right under Network ACLs).

Security group inbound rules

Just like in the NACL area, We need to be in the Inbound Rules tab and click Edit Rules. We're going to add five, with these specs:

1:

  • Type: SSH
  • Protocol: TCP
  • Port Range: 22
  • Source: 0.0.0.0/0
  • Allow / Deny: ALLOW

2:

  • Type: SSH
  • Protocol: TCP
  • Port Range: 22
  • Source: ::/0
  • Allow / Deny: ALLOW

3:

  • Type: ALL ICMP - IPv4
  • Protocol: ICMP
  • Port Range: ALL
  • Source: 0.0.0.0/0
  • Allow / Deny: ALLOW

4:

  • Type: ALL ICMP - IPv6
  • Protocol: IPV6 ICMP
  • Port Range: N/A
  • Source: ::/0
  • Allow / Deny: ALLOW

5:

  • Type: Custom...
  • Protocol: TCP
  • Port Range: 1024-65535
  • Source: ::/0
  • Allow / Deny: ALLOW

Security group outbound rules

There's only one outbound rule to make here, one for ICMP. Make it with these specs:

  • Type: ALL ICMP - IPv6
  • Protocol: IPV6 ICMP
  • Port Range: N/A
  • Destination: ::/0
  • Allow / Deny: ALLOW

Set up the appropriate routes to support IPv6 communication to the internet

Add IPv6 to the route tables

With our rules finished, we can start on the routing. Head over to Route Tables in the VPC Dashboard (the left-hand menu), and select the one that has two subnets in it. Let's give it a name, PublicRT. Now, down in the lower half of the screen, we can get into the Routes tab. Click Edit routes, and set these:

  • Destination: ::/0
  • Target: igw-xxxx (our internet gateway)

Click Save routes.

Add IPv6 to the subnets

Now, let's move to Subnets in the left-hand menu. To tell our two apart, we'll give them names. Call the x.x.1.0 one PublicSubnet, and the x.x.2.0 one will be PrivateSubnet. Highlight the public one, and the in the Actions menu, click Edit IPv6 CIDRs. In this screen, click Add IPv6 CIDR, and type 12 to complete the network part of the prefix. We can click Save, then go do the same thing in PrivateSubnet, except we're going to use 13 to complete the network part of the prefix.

Create EC2 instances

Ok, let's populate our subnets with some EC2 instances. These are fairly straight ahead. Let's get into the EC2 dashboard, then set a couple up.

The private instance

  1. Click Launch Instance.
  2. On the AMI page, select the Amazon Linux AMI (not Amazon Linux 2 AMI).
  3. Leave t2.micro selected, and click Next: Configure Instance Details.
  4. On the Configure Instance Details page:
    • Network: Leave it at our VPC
    • Subnet: PrivateSubnet
    • Auto-assign Public IP: Disable
    • Auto-assign IPv6 IP: Enable
  5. Click Next: Add Storage, and then click Next: Add Tags.
  6. On the Add Tags page, add the following tag:
    • Key: Name
    • Value: PrivateInstance
  7. Click Next: Configure Security Group.
  8. Click to Select an existing security group, and then select ours from the table below.
  9. Click Review and Launch, and then Launch.
  10. In the key pair popup, select Create a new key pair and give it a Key pair name of ipv6_keypair. Click Download Key Pair, and then Launch Instances.
  11. Click View Instances, and give it a few minutes to enter the running state.

The public instance

  1. Click Launch Instance.
  2. On the AMI page, select the Amazon Linux AMI (not Amazon Linux 2 AMI).
  3. Leave t2.micro selected, and click Next: Configure Instance Details.
  4. On the Configure Instance Details page:
    • Network: Leave it at our VPC
    • Subnet: PublicSubnet
    • Auto-assign Public IP: Enable
    • Auto-assign IPv6 IP: Enable
  5. Click Next: Add Storage, and then click Next: Add Tags.
  6. On the Add Tags page, add the following tag:
    • Key: Name
    • Value: PublicInstance
  7. Click Next: Configure Security Group.
  8. Click to Select an existing security group, and then select ours from the table below.
  9. Click Review and Launch, and then Launch.
  10. In the key pair popup, select Choose an existing key pair, pick ipv6_keypair, and check the I acknowledge... box. Click Launch Instances.
  11. Click View Instances, and give them a few minutes to enter the running state.

Verify IPv6 connectivity

We need to test whether or not IPv6 is set up properly. But before we can go pinging our EC2 instances, we need to make sure we can ping over IPv6 at all. From our command line, try this:

[user@host]$ ping6 ipv6.google.com

If we're not able to do that (because we don't have an IPv6 address on our own machine) then we'll have to test with something like an online utility, like the one Web Wiz provides.

Back over in the EC2 dashboard, click on the PrivateInstance, and copy the IPv6 address that's down in the lower part of the screen. Try pinging it with either the ping6 command, or from the online ping tool.

Now let's go try that process again for the PublicInstance. While we're at it, lets do a regular ping on the IPv4 address of our public instance.

This should all be working fine. Now let's change permissions on the pem file (chmod 400 ~/Downloads/ipv6keypair.pem), then log into PublicInstance with SSH (ssh ec2-user@&ltPublicInstance IP ADDRESS>).

Once we're in, trying pinging out:

[user@host]$ ping6 ipv6.google.com

We should be good to go here, so now get into PrivateInstance and try the same thing. Grab PrivateInstance's private IP address from the EC2 dashboard, then:

[ec2-user@host]$ ssh -A &ltPrivateInstance IP ADDRESS>

Once we're in, ping again:

[ec2-user@host]$ ping6 ipv6.google.com

Now that we've run these tests, we know IPv6 traffic is going in and out just fine. But we don't want it coming in to PrivateInstance, so let's fix that.

Egress only internet gateway

In the VPC dashboard, find Egress Only Internet Gateways in the left-hand menu. Click Create Egress Only Internet Gateway. Select our VPC from the dropdown list, click Create, then Close.

Head into Route Tables (in the left-hand menu again) and click Create route table. Call it PrivateRT, and pick our VPC from the dropdown. Click Create, and then Close.

Make sure PrivateRT is selected on the main Route Tables screen, and head down to the lower section. In the Routes tab, click Edit routes. On the next screen, click Add route. As a Destination, enter ::/0. As a Target, pick egw-..., which is the egress only internet gateway we just created. Click Save routes, then Close.

In the Subnet Associations tab, back out in the lower part of the Route Tables screen, click Edit subnet associations. Check the box next to our new PrivateSubnet, then click Save, and Close.

Let's test again. Back in our command line, we should still be logged into a PrivateInstance terminal. Try pinging out again:

[ec2-user@host]$ ping6 ipv6.google.com

It still works, right? Good. Now let's trying pinging PrivateInstance's IPv6 address again from the outside world. Launch a new terminal, or use the Web Wiz tool again, and see if we can reach PrivateInstance.

We can't. That's good though, since it's what we wanted. After all, we did name it PrivateInstance.

Conclusion

Well now, that was a bit of a ruckus. We're done though, and things look good. We have two EC2 instances. One is publicly-accessible with either IPv6 or IPv4, and the other is only accessible on its private network via IPv6 because we set up an egress only internet gateway. Congratulations!