DEV Community

Cover image for IPv6 on AWS - Flat network connection between my local computer lab and the cloud
Cristian Paul Peñaranda Rojas
Cristian Paul Peñaranda Rojas

Posted on

IPv6 on AWS - Flat network connection between my local computer lab and the cloud

I like playing and building on the AWS cloud, but also enjoy developing and prototyping on my local lab full mostly of Raspberry Pi + other embedded devices.

From time to time I managed to follow a common pattern. Deploying a load balancer either in AWS or from my public IPv4 address as a way to expose to the world my applications and also communicate back and forth between the cloud and my local network.

I always keep in mind that the internet was designed as a flat data network, delivering a multitude of protocols and services between equal peers [1].

One of the benefits of IPv6 is not having NAT, this simplifies the current client server model inherit from IPv4 and gives back peer to peer communication which is something I appreciated and use in my local network, and now I can also do against the AWS Cloud.

This is my setup:

I started by creating a IPv6 tunnel (since my ISP still doesn't provide IPv6 addresses), I signed up with https://tunnelbroker.net/

And created a tunnel against their closest tunnel server:

Image description

I also assigned a /48 prefix to the tunnel, this is important for the next steps as I'll not just get the tunnel working on a single server but also routing and assigning ipv6 addresses to my Linux devices lab.

Image description

Getting tunnel setup is simple as copying their instructions for my OS.

Image description

(note that local address it's replaced from your public IPv4 address to the local IPv4 of your system)

In order to get IPv6 address from my routed prefixes (the /48 one) have to install radvd and configure it as follows:

Image description

*After that, everything is set up on my network which is now IPv6 ready.*

Image description

Now is time to create a network in AWS Cloud, for this I'll use the following Typescript code snippet so that AWS CDK will create a VPC with 3 public subnets. This a really good abstraction and time saver:

import * as cdk from '@aws-cdk/core';
import * as ec2 from '@aws-cdk/aws-ec2';


export class NetStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // The code that defines your stack goes here
    const vpc = new ec2.Vpc(this, 'VPC', {
       subnetConfiguration: [
          {
            cidrMask: 24,
            name: 'public',
            subnetType: ec2.SubnetType.PUBLIC,
          }
       ]
    });  }
}

Enter fullscreen mode Exit fullscreen mode

IPv6 support in CDK is not ready, so I'll enable IPv6 in my VPC and subnets using the AWS CLI as follows:

Requesting IPv6 CIDR:

Get the VPC ID first

aws cloudformation describe-stack-resources --stack-name YourNamedStack --region us-east-2 | grep -oP "vpc-\w+" 
Enter fullscreen mode Exit fullscreen mode

Then request IPv6 CIDR

aws ec2 associate-vpc-cidr-block --vpc-id vpc-00000000000000000 --amazon-provided-ipv6-cidr-block
Enter fullscreen mode Exit fullscreen mode

And save the IPv6 /56 block, this is needed next.

aws ec2 describe-vpcs --vpc-id vpc-00000000000000000 --region us-east-2 | grep "Ipv6CidrBlock"
Enter fullscreen mode Exit fullscreen mode

The /56 block is split in smaller /64 prefixes, then we assigned two of them to our subnets.

We'll need to get the subnets IDs first:

aws cloudformation describe-stack-resources --stack-name NetStack --region us-east-2 | grep -oP "subnet-\w+"
Enter fullscreen mode Exit fullscreen mode

Then assign two IPv6 /64 blocks to our previous listed subnets.

aws ec2 associate-subnet-cidr-block --subnet-id subnet-00000000000000000 --ipv6-cidr-block 2600:1f16:dd9:e100::/64 
aws ec2 associate-subnet-cidr-block --subnet-id subnet-00000000000000001 --ipv6-cidr-block 2600:1f16:dd9:e101::/64 
Enter fullscreen mode Exit fullscreen mode

Enable IPv6 automatic addressing (very important for later)

aws ec2 modify-subnet-attribute --subnet-id subnet-00000000000000000 --assign-ipv6-address-on-creation
aws ec2 modify-subnet-attribute --subnet-id subnet-00000000000000001 --assign-ipv6-address-on-creation
Enter fullscreen mode Exit fullscreen mode

Routing is also necessary and our last step before start using IPv6 on an instance

Once again, we just need resources ID, this time route tables and internet gateway:

aws cloudformation describe-stack-resources --stack-name NetStack --region us-east-2 | grep -oP "rtb-\w+"
Enter fullscreen mode Exit fullscreen mode

Internet gateway is important when modifying the route tables.

aws cloudformation describe-stack-resources --stack-name NetStack --region us-east-2 | grep -oP "igw-\w+"
Enter fullscreen mode Exit fullscreen mode

And then adding IPv6 default route (::/0) to reach the internet.

aws ec2 create-route --route-table-id rtb-00000000000000000 --destination-ipv6-cidr-block ::/0 --gateway-id igw-00000000000000000
aws ec2 create-route --route-table-id rtb-00000000000000001 --destination-ipv6-cidr-block ::/0 --gateway-id igw-00000000000000000 
Enter fullscreen mode Exit fullscreen mode

Now, if I launch an ec2 instance either from the console or with the following snippet:

aws ec2 run-instances --image-id ami-08e6b682a466887dd --count 1 --instance-type t4g.micro  --iam-instance-profile Name=AWSCloud9SSMInstanceProfile  --subnet-id subnet-00000000000000000
Enter fullscreen mode Exit fullscreen mode

Get a session against it, I can validate that it actually got a IPv6 address.

Image description

Image description

If I run netcat on either side of my network (cloud and local), I can communicate between both servers as if they were in the same network, in some way they are now :D.

Now I can communicate with my AWS really easily, and I'm also on my way to transition to IPv6.

It's important to *modify Security Groups* to allow connections from my /48 IPv6 network segment, or the whole IPv6 internet if you want to just host some web applications there too with AAAA records ;-)

I'm planning to use this setup to play with ECS Anywhere soon.

There are some considerations to keep in mind:

  • Latency is around 200ms, I might be due to my physical location.
  • Security Groups needs to be adjusted on the instance that run in AWS side
  • Review your local IPv6 router firewall as well for security reasons
  • Use TLS all the times, this is not a VPN.
  • I'm using my pi-hole box to host the tunnel and provide IPv4 to IPv6 routing on my local lab.

I hope you enjoy reading this.

[1] http://luca.ntop.org/n2n.pdf

Discussion (1)

Collapse
moose profile image
moose

Thanks for the writeup. I've been looking to get into more embedded development. AWS a good place to host those type apps?