A Taxonomy of IP Addresses in the AWS VPC
Whether you are a developer or network engineer, designing and implementing services in the AWS VPC requires an understanding of IP networking. My objective in this post about classifying IP addresses in the AWS VPC is to teach you one thing you didn’t previously know. Let’s dive in.
The first way that IP addresses can be classified is by protocol. At the time of launch, the VPC supported only IPv4 addresses. AWS has incrementally added support for IPv6 although it currently lacks parity with the legacy version of the protocol. (For more on IPv6 in the VPC, check out this post). In this article, I will reference the protocol version if it is relevant to the point I’m making. If I use “IP” by itself, the statement applies to both protocol versions.
If you’ve studied for AWS certification, you may expect me to jump into discussing public and private IP addresses. I’m going to suggest that you think about classifying IP addresses differently. Let’s go with internal and external.
Internal IP Addresses
Internal IP addresses are tied to your VPC at the time of creation. They are used to uniquely identify endpoints of the components in the VPC from a networking perspective. You will see the internal IP addresses when you log into an EC2 instance and display the state of the network interfaces.
[ec2-user@ip-100-64-15-154 ~]$ ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
link/ether 12:31:da:d4:36:47 brd ff:ff:ff:ff:ff:ff
inet 100.64.15.154/20 brd 100.64.15.255 scope global dynamic eth0
valid_lft 3151sec preferred_lft 3151sec
inet6 2600:1f18:5cc:2900:a18b:129d:3082:4fa0/128 scope global dynamic
valid_lft 395sec preferred_lft 95sec
inet6 fe80::1031:daff:fed4:3647/64 scope link
valid_lft forever preferred_lft forever
In the above output, there is one internal IPv4 address, 100.64.15.154, that is tied to the Elastic Network Interface (ENI) of this EC2 instance.
AWS places few restrictions on what internal addresses can be used within the VPC. The most common choice is one that’s been carried over from traditional “big iron” networking: private IPv4 addresses documented in RFC1918. These IPv4 prefixes are 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16.
I’m a proponent of using RFC6598 IPv4 addresses as internal addresses. This block was reserved by the IETF–the Internet standards body–for carrier-grade NAT but there’s no harm in using it for the VPC. I like that these addresses stand out from IPv4 addresses in corporate networks, data centers and home networks. For companies that maintain hybrid infrastructure, there’s no concern for IPv4 address overlap as you don’t see RFC6598 IPv4 addresses outside of service provider networks.
Get this. You can use public IPv4 address to number your VPC. This has nothing to do with Bring Your Own IP (BYOIP), which I’ll touch on later. Don’t believe me? Try it. Since this address space is internal to your VPC, AWS allows you to use these addresses. You don’t have to own the IPv4 address space although “squatting” on other companies’ IPv4 addresses is ill-advised.
External IP Addresses
External IP addresses are addresses capable of being routed on the public Internet. Typically these addresses are owned by Amazon and tied to a particular AWS region.
I classify external IPv4 addresses into ephemeral and Elastic IPs. You won’t see the term ephemeral in AWS documentation. Instead, you’ll see “public” used in AWS documentation and the reader is expected to know from the context whether these are EIPs or not. I like to make this distinction for clarity’s sake.
Ephemeral IP addresses are assigned by AWS for VPC components such as EC2 instances. These IPv4 addresses can change and should not be expected to be fixed. For many use cases, that these IP address can change is acceptable. We use the indirection that is DNS for a reason.
EIPs are fixed IPv4 addresses that are assigned to VPC components when a static address is needed. You may have used these for EC2 instances or load balancers. EIPs were previously used exclusively in public subnets. Following the introduction of VPC ingress routing, you can assign EIPs to instances in private subnets in advanced architectures in which services are protected by a firewall.
You can port public IPv4 addresses that you own to be used as EIPs in the VPC. AWS refers to this as BYOIP, which is available in most but not all AWS regions. Once AWS verifies that you own this IPv4 address space, the pool will show up in your account to be used as EIPs. BYOIP isn’t relevant to the majority of AWS customers although it has interesting use cases for some enterprises. You can also port IPv6 addresses but this an advanced topic that I’m going to omit from this article.
External IPv4 addresses will not show up when examining the state of network interfaces on an EC2 instance. The instance is not aware of these addresses. There are discovery mechanisms available, the most simple being the use of curl at the command line to sites such as https://ifconfig.me.
External IP addresses are the key to outbound Internet access. To perform basic tasks on an EC2 instance such as downloading OS packages, python modules or git repos, the instance must have an external IP or use another component in the VPC that has a public IP (e.g., NAT Gateway, NAT instance, firewall) as transit device.
You may be wondering how an EC2 instance with an internal IPv4 address communicates with the IPv4 Internet. The VPC enables this communication using Network Address Translation (NAT) bindings at the Internet Gateway (IGW). The internal address is converted to the external address for outbound traffic and vice versa for the return traffic.
Let’s return to our discussion of IPv6. IPv6 is not easily classified into internal or external. To understand why, consider the availability of IP addresses. Public IPv4 addresses are scarce and can no longer be obtained from the regional Internet registries such as ARIN and RIPE. We’ve consumed the approximately four billion addresses at a fast clip and the only reason IPv4 is still viable is that we’ve gotten really good at NAT.
IPv6 addresses are plentiful given the 128 available bits for addressing. When you create a VPC with an IPv6 prefix, AWS provides a globally unique /56 IPv6 prefix. For those not familiar with Classless Interdomain Routing (CIDR) notation, the “/56” denotes the number of bits that specify the network portion of the addresses. Unlike IPv4, IPv6 has a standard subnet size of /64. This means a /56 can accommodate 2**8, or 256, /64s. If your VPC requires more than 256 subnets, you can assign a secondary IPv6 prefix although you may instead want to contact us to discuss your infrastructure design. 😉
IPv6 addresses are used for communication within the VPC and the Internet. There is no concept of EIPs with IPv6. The IGW does not do address translation. If you are not comfortable with using security groups and NACLs as the sole protection from inbound Internet access, you may want to use AWS’s Egress-Only Gateway. It is analogous to a NAT Gateway as it is horizontally-scaled and redundant. Internet end systems will not be able to initiate communication with instances behind an Egress-Only Gateway.
When I was throwing around ideas about writing about IP addresses in the VPC, I considered using a title along the lines of “Everything you need to know about IP addresses in the VPC” but I decided to scrap that as a comprehensive guide to IP addresses would be a very long blog article. Instead, I took the route of classifying IP addresses in a way that you may not have considered. My hope is that the classification I’ve presented gives you a mental model of IP addressing that provides a foundation for understanding networking in the VPC.