In this exercise we will build a NAT instance using the Cisco CSR1000v AMI.
This is exercise 2.1 for the AWS Advanced Networking Specialty training. For an explanation and overview of all exercises, see the overview post.
The exercises are built on the assumption that you’re already familiar with the AWS basics and have achieved at least one associate level AWS certification.
Exercise scope
In this exercise we will use the Cisco Cloud Services Router (CSR) 1000v to build a NAT instance. This serves a number of purposes:
- Getting experience with the Cisco IOS software without purchasing expensive hardware
- Learning the differences between NAT instances and managed NAT gateways
- Getting experience with instances with multiple network interfaces in AWS
Additionally, this setup mimics a common datacenter setup, with a single router / firewall between the internet and a private network.
The Cisco CSR is a virtual appliance that can run in almost any private or public cloud, and offers most of the features of a physical router. For the purposes of this exercise it’s a great way to build and experiment with a ‘real’ router without the need of purchasing an actual device. The cost model is pay-as-you-go, so you pay only for the hours you have it running.
Important note: The Cisco CSR1000v has a 30 day trial for a single instance. For anything above that you will pay the hourly license fee, which is about $0.55 per hour on a t2.medium.
End result
By the end of this exercise we will have built the following setup:
VPC setup
As displayed in the diagram above, we will need a VPC with three subnets and an Internet Gateway. We will also need three different route tables.
Let’s start by creating the VPC. Navigate to the VPC console, click Your VPCs on the left, then click the Create VPC button.
In the next screen, give the VPC a recognizable name like cisco-vpc, and click Create.
Then navigate to the Route Tables section and rename the table that has been automatically created for your VPC to ‘local-only’.
Then create an additional two Route Tables, named ‘internet-route-table’ and ‘private-route-table’. When that is done, create an Internet Gateway named ‘cisco-igw’ and attach it to your VPC.
Next up: creating three subnets. Navigate to the Subnets section and click the Create subnet button.
Then create the subnets cisco-public-1a
, cisco-private-1a
and application-private-1a
, all of them in availability zone 1a, and with CIDRs 10.0.0.0/24
, 10.0.1.0/24
and 10.0.2.0/24
, respectively.
When the subnets have been created, assign the following Route Tables to them:
- assign
internet-route-table
to subnetcisco-public-1a
- assign
local-only
to subnetcisco-private-1a
- assign
private-route-table
to subnetapplication-private-1a
Lastly, add a route for 0.0.0.0/0
to your Internet Gateway to the internet-route-table
:
With that, our current setup looks like this:
Deploying a Cisco CSR1000v
The CSR is available as a subscription from the AWS Marketplace. There are a few variants (BYOL, Security, AX and others). For more information about the different licenses, see the Cisco Cloud Services Router 1000v Data Sheet.
For this exercise we can use the cheapest license, which is the
Cisco Cloud Services Router (CSR) 1000V - Security Pkg. Max Performance. Click that link and follow the steps to subscribe.
Once you have confirmed your subscription you can launch an instance either through the AWS Marketplace console or the EC2 console. We will use the second option. Navigate to the EC2 console for your region and click Launch Instance. In the AMI selection screen, click AWS Marketplace and search for Cisco Cloud Services Router (CSR) 1000V - Security Pkg. Max Performance
.
In the Instance Type selection screen, select t2.medium. Other instance types are either not supported or much more expensive.
In the Configure Instance Details screen, select the VPC and the public subnet we created in the previous step. Make sure Auto-assign Public IP is disabled; we will use an Elastic IP instead.
At the bottom of the same screen, add an additional network interface, and select the private cisco subnet for it.
Click through the next few screens until you get to Step 6: Configure Security Group. Create a new Security Group that allows SSH from your IP and all traffic from the VPC (10.0.0.0/16
).
Then launch the instance. Make sure you select a valid key pair.
When the instance is launching, navigate to the Network Interfaces section in the EC2 console and disable Source / Destination checking for both ENIs.
The last step in this section is to allocate an Elastic IP address and associate it to the primary (public) interface of the CSR. Make sure you copy the ENI ID from the Network Interfaces section, and paste it in the Associate Elastic IP address dialog.
When these steps have been completed, the infrastructure looks like this:
Deploy an application instance and bastion host
To verify that our NAT instance works as intended by the end of this exercise, we’re going to need an instance in a private subnet. We’ll call that the application instance. To reach this private instance, we will also need a bastion host. In this section, we will deploy both and open an SSH connection to the application instance.
For both instances, use the latest Amazon Linux 2 AMI and a small instance type (eg. t2.micro). Make sure you deploy the bastion in the cisco-public-1a
subnet, and the application instance in the application-private-1a
subnet. Set ‘Auto-assign Public IP’ to enabled for the bastion host, but to disabled for the application instance.
When configuring the security group for the instances, allow your own IP to access port 22 on the bastion host, and allow 10.0.0.0/24
to access port 22 on the application host. In other words; you should be able to SSH to the bastion, and the bastion should be able to SSH to the application instance.
When you’re ready, SSH to the application instance.
From the application instance, try to connect to the internet. For example, try a curl google.com
. Of course you’ll find that it doesn’t work, because no routes to the outside world have been set up yet.
For now, type ping google.com
and leave it running. This will continously ping Google, and should show output as soon as we complete our NAT setup.
Configuring NAT
To make connectivity from the application instance work, it needs a route to the Cisco CSR, and the CSR needs to route that traffic to the internet.
Let’s apply the route to the CSR first. Navigate back to the VPC console and select the Route Table private-route-table
. Then select the Routes tab and click the Edit routes button.
In the next screen, add a route for 0.0.0.0/0 to the secondary (private) network interface of the Cisco.
That’s all we need to route traffic to the CSR. Let’s go to the final step; configuring the Cisco itself.
Open an SSH connection to the Elastic IP address we created earlier.
When you see this screen, you have successfully connected to the Cisco CSR. This is not your average Linux host. Instead it runs a dedicated networking operating system called IOS. Most of your familiar linux commands won’t work - for more information about IOS commands, see Basic Router Commands and Tasks.
A few commands to get you started:
show running-config
will get you the full configuration of the routerconfig terminal
will allow you to change the configshow interfaces
will tell you about connected interfacesshow ip route
will show you the routes known to the router
To configure NAT, first enter configuration mode by executing config terminal
.
Then type the following instructions, line by line:
interface GigabitEthernet1
ip address dhcp
ip nat outside
no shutdown
interface GigabitEthernet2
ip address dhcp
ip nat inside
no shutdown
ip nat inside source list 10 interface GigabitEthernet1 overload
ip route 10.0.2.0 255.255.255.0 GigabitEthernet2 10.0.1.1
access-list 10 permit 10.0.2.0 0.0.0.255
When you typed the last command, the ping command you left running should suddenly start working! This means that the application server can now connect to the internet. You can run some additional connectivity tests by running curl google.com
or a sudo yum update
.
You can exit the Cisco configuration mode by typing end [enter]
. You can see what the CSR is doing by running show ip nat statistics
and show ip nat translations
.
Conclusion
In this exercise we’ve set up a NAT instance running on Cisco IOS. We have worked with Cisco IOS and configured the interfaces on the virtual router. This setup will be used as a baseline for more complex configurations, using VPN and BGP.
Getting hands-on with a NAT instance might also have made you appreciate the AWS managed NAT gateway, which does all we did today in just a few clicks, and will automatically scale with your traffic too!