IPv6 on AWS - Flat network connection between my local computer lab and the cloud
Tags: aws, devops, cloud, cli
Published: 2021-10-26 02:46:34

---
title: IPv6 on AWS - Flat network connection between my local computer lab and the cloud
published: true
description: Simplifying network connections between on-premise and cloud by using IPv6 
tags: aws, devops, cloud, cli
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7z3svkwr3oz4zklvoko8.JPG
---

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i4huvc2viy1qncivlg6q.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3xnpg4w6jma0u3vl0ewu.png)
  
Getting tunnel setup is simple as copying their instructions for my OS.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3acupq6sx4nhvvvraen4.png)

(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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/71qfncgq1tbsfdsbhary.png)
   
****After that, everything is set up on my network which is now IPv6 ready.****

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/81zyn3b4a1uoyqngsxgc.png)

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,
          }
       ]
    });  }
}

```
 
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+" 
```

Then request IPv6 CIDR
   
```
aws ec2 associate-vpc-cidr-block --vpc-id vpc-00000000000000000 --amazon-provided-ipv6-cidr-block
```
And save the IPv6 /56 block, this is needed next.

```
aws ec2 describe-vpcs --vpc-id vpc-00000000000000000 --region us-east-2 | grep "Ipv6CidrBlock"
```

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+"
```
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 
```

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
```

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+"
```
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+"
```

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 
```
  
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
```

Get a session against it, I can validate that it actually got a IPv6 address.
  
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zqkxguflrtj6mjunhvjo.png)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ux0zg98fsnnw4bveskxc.png)

**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