In this lecture we will demonstrate creating a Statically Routed IPsec VPN between 2 VPCs. The demonstration will use VYOS to act as our Customer Gateway appliance. This demonstration will require us to manually configure static routes. We will use CloudFormation templates to provision a fresh environment that contains 2 new VPCs deployed within the same region. CloudFormation will prepare for us all the foundational networking infrastructure - , however we will walk you through the process of creating and configuring the IPsec tunnels manually. The end result will allow us to forward privately routed network traffic across a pair of redundant IPsec tunnels created between the 2 VPCs.
Let's now put our IPsec theory to test and build a statically routed IPsec VPN between two VPCs. The CloudFormation templates used within the following demonstrations are hosted online at Cloud Academy's public GitHub repository. In our first demonstration, we'll be creating a statically routed IPsec VPN between two VPCs. We'll use CloudFormation to provision a fresh environment that contains two new VPCs in the same region. CloudFormation prepares for us all the foundational network infrastructure, but does not create the IPsec tunnels. That is for us to do manually. As you can see, our demonstration will consist of a left-hand side VPC and a right-hand side VPC, each created by their own dedicated CloudFormation template. The left-hand side VPC will simulate a corporate on-prem network, meaning that it will host a firewall device. In this case, we'll be using VyOS. VyOS is a Linux-based network operating system that provides software-based network routing, firewall, and VPN functionality. Our VyOS instance will be configured with two elastic network interfaces: external and internal facing. The external facing ENI will have an elastic IP address attached. This elastic IP address will become the customer gateway IP address in our VPN configuration. The right-hand side VPC will act as our typical AWS Cloud site. Within this VPC, we'll provision the VPN componentry: that is the customer gateway, the virtual private gateway, and the VPN connection itself. Once the environment is up, we'll manually configure the IPsec tunnel within VyOS, set up static routes within our VPCs, and update respective security groups to allow inbound ICMP requests. Both VPCs will contain an EC2 test instance. The test instances will be used to perform ICMP ping requests to each other, using only their privately assigned IP addresses. If all goes well, we'll be able to see traffic go across our newly provisioned IPsec VPN tunnels. Navigate to the GitHub URL, as seen here. Next, copy the HTTPS clone URL. Within your own terminal, create a new directory. Move into that directory, and perform a git clone with the URL you previously copied. Let's now list the contents of the current directory. Next, navigate down into the VPC VPN CloudFormation directory. Listing the contents of the CloudFormation directory, we see two CloudFormation templates, which we will now use to provision our left-hand and right-hand side VPCs. We'll now take a quick look at the contents of each CloudFormation template. First, let's open up the left-hand side VPC CloudFormation template. This template's function is to build a corporate private network with a firewalling device. In this case, we're using VyOS. Here the VyOS instance that we'll launch is configured with two elastic network interfaces. The eth0 interface is considered to be externally facing and has an elastic IP address attached to it. The elastic IP address used here is effectively the customer gateway IP address that will be referenced by the right-hand side CloudFormation template to establish the customer gateway endpoint. The eth1 interface is considered to be internally facing, and has a private IP address only. Next, let's open up the right-hand side VPC CloudFormation template. This template's function is to build a VPC that will act as a typical AWS VPC, in that this VPC will host our customer gateway, virtual private gateway, and our VPN connection components. Here, this is our customer gateway component. Recall that the customer gateway will be configured with the elastic IP address that we need to set up and assign to the VyOS eth0 externally facing elastic network interface in the left-hand side CloudFormation template. Here, this is our virtual gateway component. And here, this is our VPN component that references the previously mentioned two gateway endpoints. First up, we'll build a statically routed VPN environment by launching each CloudFormation stack. The first CloudFormation stack will create the left-hand side VPC in our network schematic. This will represent and simulate our corporate on-prem network. The left-hand side VPC will have three subnets. The first two subnets will be provisioned to host the external and internal elastic network interfaces used by VyOS. The third subnet will host a privately zoned EC2 test instance from which we'll perform ICMP ping tests to the EC2 test instance hosted in the right-hand side VPC. Within the left-hand side VPC, the CloudFormation template launches a VyOS instance, which will act as our corporate firewall. In AWS VPN terminology, VyOS is the customer gateway. The VyOS instance will have dual ENIs. The first interface will be externally facing, deployed in the external subnet, and will have an elastic IP assigned to it. The second interface will be internally facing, deployed in the internal subnet, having only a private IP. An internet gateway is attached to allow us to SSH in to manage and set up the VyOS VPN config. The second CloudFormation stack will create the right-hand side VPC. This represents our AWS side of things. The right-hand side VPC will be provisioned with a virtual private gateway and a customer gateway. A VPN connection will be created referencing both these gateways. Having provisioned the VPN connection, we'll then download the VPN configuration file. This will then be imported into the VyOS instance, which will establish our two IPsec tunnels. The right-hand side VPC will be created with a single subnet, and into which we'll launch a single EC2 test instance. Starting from within the AWS console, select an appropriate region into which you will launch both CloudFormation stacks. Before we launch either CloudFormation stack, ensure that an SSH key pair exists within the chosen region, and for which you are in possession of the private key, as this will be referenced by both CloudFormation templates. To do this, starting from the AWS console home, click on the EC2 service link. Next, click the Key Pairs link under Network & Security. Confirm that an existing SSH key pair exists, and if not, create a new one. We'll now launch the first CloudFormation stack. Recall that this will build the left-hand side corporate on-prem simulating network. Navigate to the CloudFormation service. Now click the Create New Stack button. We then select the Upload option. And then click the Choose File button. Navigate to and select the CloudAcademy.vpc.vyos.vpn.yaml from our recently git cloned repository. Click the Next button. Give the CloudFormation stack a name. Here we've chosen to call ours VPC-CORP. Select the appropriate SSH KeyName from the drop down, and then click Next. Leave all defaults as is, and click Next again. Finally, click the Create button. This will launch our left-hand side VPC. This will take approximately five to 10 minutes to complete. After this CloudFormation stack launch completes successfully, signaled by the CREATE_COMPLETE status, navigate to the Outputs tab, and take note of the outputs. These will be important to us in the coming steps. Next, let's launch the second CloudFormation stack. Recall that this will build the right-hand side network. Click the Create Stack button. We then select the Upload option, and then click the Choose File button. Navigate to and select the cloudacademy.vpc.cloud.vpn.yaml from our recently git cloned repository. Click the Next button near the bottom of the current page. Give the CloudFormation stack a name. Here we've chosen to call ours VPC-Cloud. Select the appropriate SSH KeyName from the dropdown. Ensure that the StaticRoutesOnlyForVPN option is set to true. Set the VPCCORPCustomerGatewayIP to be the public IP assigned to the VyOS instance, created in previous CloudFormation stack. This is the VyOS instance public IP output value. And then click Next. Leave all the defaults as is and click Next again. Finally, click the Create button. This will launch our right-hand side VPC. This will take approximately five to 10 minutes to complete. After this CloudFormation stack launch completes successfully, as represented by the CREATE_COMPLETE status, navigate to the Outputs tab and take note of the public IP. This we will use to SSH onto the EC2 test instance. Now let's head over to the VPC service. Under Services, select the VPC Service. Next, on the left-hand side menu, click the VPN Connections link. Select the recently created VPN connection, and then click the Download Configuration button. In the Download Configuration popup window, we choose Generic for the vendor. The rest of the options are left as is. Click the Yes, Download button. This downloads the VPN configuration file. We'll now import this into our VyOS instance. Let's now log in to the VyOS instance and set up the IPsec tunnels. We do so by SSH-ing into the instance using its assigned elastic IP. Before we do this, let's add our SSH key to our SSH authentication agent. We do so as we will later hop from the VyOS instance down to the EC2 instance in the same VPC. Okay, now let's SSH into the VyOS instance. The first thing we need to do within VyOS is set up a configure the eth1 internal interface. If we run the Show Interfaces command, you can see that the eth1 interface does not currently have a private IP set. Let's set this up now. We need to first determine the private IP address assigned by AWS to the eth1 interface. We do this by examining it within the EC2 console. Back within the VyOS console, enter into configuration mode by typing conf, and hitting Enter. Next, enter set interfaces ethernet eth1 address, using the /24 private IP address we just collected, and then hit Enter. We'll now prepare a VyOS specific IP set configuration file. First, open within a text editor, both the VyOS.static.vpn.template file, and the AWS generic VPN file we previously downloaded. We now need to copy and replace all of the tokens with their respective values as documented within the token name. We now start to paste in the VPN configuration blocks into conf mode within VyOS. Next, we commit and save the changes to make them effective. Let's now take a quick look to see whether we've successfully established an IPsec security association with the AWS virtual private gateway. To do so, by exiting the configuration mode, and running the following command: show VPN like SA. Here you can see that an SA has been successfully established, and that both IPsec tunnels are up. We can also take a quick look within the AWS VPC console to check its view of our VPN tunnels. Under VPN Connections, click on our VPN connection, and select the Tunnel Details tab. Here the tunnel status of both tunnels is up. Right, next we need to set up some static routes in VyOS, and in our VPCs. Let's reenter into configuration mode. Within VyOS, we'll create two new static interface routes, one for each of the two virtual interfaces, vti0, and vti1. The route is for 192.168.0.0/20. This is the address space for the right-hand side VPC. Again, commit and save these changes. Let's now jump back into the AWS console. We have a few routing and security group updates we need to make. The first is on the VPN connection. Head over to the VPC console, and click on the VPN connection's menu link. Next, click the VPN connection that the first CloudFormation template created for us. Clicking on the Static Routes tab, we can see that no static routes have been added. Let's add in a static route for the left-hand side VPC: 10.0.0.0/18. Now, click on the route tables menu link. Order the route tables by name. This makes it easier for us to identify them. We need to make a few route table changes. The first route table we will update is the VPC-CORP Private Subnet Route Table. This route table hosts a test instance from which we will use to initiate ICMP ping tests from. We need to update this route table to route network traffic destined for the other VPC across the VyOS IPsec tunnels. Therefore, we need to add the route 192.168.0.0/20, and point it at the VyOS internal eth1 interface. Next, we need to update the VPCCLOUD Subnet Route Table. Rather than add the required routing manually, we can extract the VPG to propagate the static route 10.0.0.0/18 that we set up earlier, into this route table, by clicking on the Route Propagation tab, clicking the Edit button, and then enabling the propagate setting. Finally, click on the Save button, and then return to the Routes tab. You should now see the 10.0.0.0/18 route, and with the propagated value set to Yes. One final piece of set up we need to do, is update our security groups to allow inbound ICMP ping requests. Specifically, we need to allow inbound ICMP on the security groups attached to both EC2 test instances on either side. Additionally, we need to update the security group attached to the VyOS internal eth1 interface, to also allow inbound ICMP. Let's go ahead and do each of these. We'll set the source to be anywhere just to speed up the course. Finally, everything's in place. We should now be up to SSH into each private EC2 test instance within either VPC, and perform a ping across to the opposing instance. The network traffic generated, will flow across the IPsec VPN tunnels and back, utilizing the static routes that we've manually set up. Let's SSH in to the left-hand side test instance, and ping the right-hand side instance. To SSH into the left-hand side instance, we bounce there via the VyOS instance. Now that we're in our test instance, let's ping the private IP of the right-hand side test instance. Great, it looks like traffic is flowing across our IPsec tunnels successfully. Let's just pause here for a second to give an explanation of how the ICMP packets are being routed from the left-hand side sender, to the right-hand side receiver. The following sequence takes place. One, packets exit the EC2 test private instances interface, and are sent to the AWS cloud router. Two, the AWS cloud router looks up its routing table, and then forwards them to the VyOS internal interface. Three, VyOS looks up its internal routing table, and forwards the packets internally to the IPsec virtual tunnel interface. Four, the packets get encrypted and routed across the IPsec tunnel. Five, the IPsec encrypted packets actually go out the VyOS external interface, and head to the virtual private gateway attached to the right-hand side VPC. Six, the VPG VPN connected decrypts the packets and forward to the AWS cloud router. Seven, the AWS cloud router looks up its routing table, and then forwards them to the EC2 test instance's private interface. Okay, we'll now repeat the same test, but in the reverse direction. SSH into the right-hand side test instance via its elastic IP. Now that we're in our test instance, let's ping the private IP of the left-hand side test instance. Great, again our traffic is flowing across our IPsec tunnels successfully. Again, let's analyze and give an explanation of how the ICMP packets are being routed from right-hand side sender, to left-hand side receiver. The following sequence takes place. One, packets exit the EC2 test private instance's interface, and are sent to the AWS cloud router. Two, the AWS cloud router looks up its routing table, and then forwards them to the virtual private gateway attached to the right-hand side VPC. Three, the VPG VPN concentrator encrypts the packets, and are routed across one of the IPsec tunnels. Four, the IPsec generated packets arrive on the left-hand side via the VyOS external interface, and are logically processed by the respective virtual interface, where they are decrypted. Five, VyOS looks up its internal routing table, and forwards the decrypted packets to the local AWS cloud router, via the VyOS internal interface. Six, the AWS cloud router looks up its routing table, and forwards them to the EC2 test instance's private interface.
Jeremy is a Content Lead Architect and DevOps SME here at Cloud Academy where he specializes in developing DevOps technical training documentation.
He has a strong background in software engineering, and has been coding with various languages, frameworks, and systems for the past 25+ years. In recent times, Jeremy has been focused on DevOps, Cloud (AWS, Azure, GCP), Security, Kubernetes, and Machine Learning.
Jeremy holds professional certifications for AWS, Azure, GCP, Terraform, Kubernetes (CKA, CKAD, CKS).