IPv6 Part 14: Provider-independent addressing

IP addresses can be divided into two categories depending on who assigns them. Most users will get their addresses from their Internet service provider (ISP): these are Provider-Assigned or Provider-Aggregatable (PA) addresses. As anyone who has been through a switch of ISP knows (I’ve been through two) it’s a painful process if you have PA addresses. With IPv4 and NAPT, your internal hosts will be using private addressing so you only need to readdress your public-facing systems, but IPv6 assumes that all hosts are addressed with global unique addresses (GUAs), so a switch of ISP means readdressing every interface in your enterprise. This is a huge operational problem; there are IPv6 features that make this process a bit easier, but it would still be very disruptive.

One solution to this is to obtain your own IP addresses that are independent of any ISP, so-called Provider-Independent (PI) addresses; you thus become an Autonomous System (AS) in your own right. The main disadvantage of this is that your address range can’t be conveniently aggregated into an ISP’s allocation, and so routes to your PI address block have to be advertised separately across the Internet using Border Gateway Protocol (BGP, the Internet’s global routeing protocol). One of the main goals of IPv6 was to manage address allocation more efficiently in order to limit the size of the global routeing tables, so this cuts across that. In fact, many providers will not accept routes to small PI address blocks and so in practice PI addressing is mainly confined to large enterprises.

RFC 4193 introduced Unique Local Addresses (ULAs) for IPv6. These can be assigned in parallel with global unique addresses (GUAs), so that connections within your site use ULAs, and only connections to or from the global Internet use GUAs. Your internal DNS should serve ULAs to internal queries. An important detail is that ULAs are “global” in scope just like GUAs, so rules in the IPv6 stack on each host need to be configured to handle selection of the appropriate source address [UPDATE: the default source address selection rules should handle this without modification]. Migration from one ISP’s PA addressing to another’s is still painful, but at least your local traffic should be uninterrupted during the process.

ULAs begin with the prefix fd00::/8 (in principle the prefix is fc00::/7 but in practice the eighth (“L”) bit is always set to 1). Forty additional bits (e.g. 2f e8 b7 61 3f) should be randomly generated to make a /48 prefix suitable for a site (e.g. fd2f:e8b7:613f::/48). You can generate five random bytes in hex for this purpose at https://www.random.org/bytes/. Generating them randomly makes it almost certain that you will never share a ULA prefix with another site, which could cause problems if for example you merge two organisations. It’s tempting to choose something easy to remember like fd00:cafe:f00d::/48 but this is not recommended as it’s much more likely to produce a collision.

ULAs are often described as being the equivalent of IPv4 private addresses, but they’re not quite the same, at least not as originally intended. IPv4 private addresses are combined with NAPT to enable communication with the Internet. However, an IPv6-enabled host might have both a ULA and a GUA, using them for local and global communication respectively. An approach that’s much closer to IPv4+NAPT is Network Prefix Translation for IPv6 (NPTv6), defined in RFC 6296. With NPTv6 you use only ULAs internally; at your boundary an NPTv6 gateway translates between your ULA prefix and your globally-routeable prefix, in a way that is one-to-one and stateless. By some clever maths it also succeeds in avoiding the modification of transport-layer checksums.

One of the most important benefits of NPTv6 is that it enables multi-homing for smaller enterprises. Multi-homing means connecting to the Internet via two or more ISPs, for resilience and load-balancing. Conventional multi-homing requires you to become an AS and deploy BGP routes to your networks, which as we have seen is impractical for smaller sites. With IPv4, NAPT provides a separation between internal and external addressing that makes it possible to multi-home using PA addressing; NPTv6 plays the same rôle for IPv6.

NPTv6, like any form of NAT, has limitations: it can cause problems for applications and for IPsec (see my previous posts on NAT and applications and NAT and IPsec). It is also limited in practice to /48 global prefixes because this is always the length of ULA prefixes. Nevertheless it does offer a solution to those smaller sites that want provider independence and multi-homing and can’t operate as an AS.

In my next post (the last in my series) I’ll sum up my thoughts on IPv6.

IPv6 Part 7: No more NAT

One of the biggest culture shocks for me as a security professional is the assumption that IPv6 addressing is end-to-end; in other words, no more network address translation (NAT). Untranslated addresses expose both the host identity and the topology of the local network to the outside world. If an auto-configured IPv6 address is based on the interface MAC address (see IPv6 Part 3: Address auto-configuration) then the hardware vendor of the interface is exposed too (there are alternatives to this as we shall see). However, what I find even more shocking is the level of hostility to NAT within the IPv6 world: it seems to be an article of IPv6 faith that NAT is bad, often without giving any real case against it. I want here to take a good look at NAT and the arguments for and against, without prejudice.

One of the sources of confusion and ignorance there is about NAT comes from confusion of terminology, so I’ll start off by trying to cut through that in this post. It’s important to understand that there are two main different types of NAT. The first is usually referred to as one-to-one NAT (bi-directional NAT according to RFC 2663, Static NAT in the Check Point world). As the name suggests, there is a one-to-one mapping between addresses in the public domain and the private domain. As datagrams pass through the NAT gateway that lies between the two, the source or destination address is rewritten accordingly, and for TCP, UDP and ICMP (and IPv4 datagrams) the header checksum is recalculated. IPv6 will simplify this slightly because there is no longer a datagram checksum to recalculate. One-to-one NAT was first used in the early days of the Internet to handle cases where end-users had changed providers and hadn’t completed the process of readdressing all their hosts using the new (provider-assigned) prefix. An experimental form of prefix translation has now been defined for IPv6 (RFC 6296).

If the NAT gateway uses static rules to map between private and global addresses then the process is stateless: the gateway simply translates addresses packet by packet. However RFC 3022 defines a method called Basic NAT, where bindings between private and global addresses are set up dynamically, from a pool of global addresses; this means that the NAT gateway has to manage the state of these bindings.

The other type of NAT is what RFC 3022 refers to as Network Address Port Translation (NAPT; known as overloading or Port Address Translation in the Cisco world, Hide NAT in the Check Point world). This allows multiple hosts on a private network to connect to the Internet using one global address: very attractive in the IPv4 world with the increasing shortage of globally routable addresses. A private network using NAPT will typically use RFC 1918 addresses internally, which are not globally routable.When a host on the private network initiates a connection to the Internet, the NAPT gateway will typically translate the source address of the initial datagram to the global address of the gateway. It then dynamically translates the source TCP or UDP port of the initial datagram to an available port on the gateway itself. TCP and UDP ports are 16-bit numbers, and outbound source ports are generally allocated in the range above 1023, so this will scale up to a a maximum of about 64,000 simultaneous connections. ICMP datagrams have to be modified in an analogous way.

To take an example, say the NAPT gateway has a global address of 192.0.2.1, and there are two hosts with RFC 1918 addresses, 10.0.0.1 and 10.0.0.2, on the private side. Host 10.0.0.1 initiates a TCP connection to port 80 on 198.51.100.1 with a randomly selected source port of 7680. As the first datagram of the connection passes through the NAT gateway, the gateway translates the source address to 192.0.2.1, and the TCP port to a spare port on itself, let’s say 20231. Then host 10.0.0.2 makes a TCP connection to another destination, port 80 on 203.0.113.1, with the source port set to 1818. The gateway will translate port 1818 to another spare port, in this case 10434. The gateway needs to maintain the state of these mappings, so that when a datagram comes in on the global interface with destination of 192.0.2.1 and TCP port 20231, it knows that this needs to be translated to 10.0.0.1 and port 7680 in order to reach its destination.

NAPT gateways have even more work to do than one-to-one NAT gateways. Not only must their checksum recalculations include the modified port numbers, but they must also now maintain the state of every connection that passes through, and clean this up when the connection is closed. If there are multiple NAPT gateways for redundancy, then this state will need to be replicated between them to keep connections up after a gateway failure.

NAPT has the magical property of allowing a private network to be much larger than it appears from the Internet: a bit like Doctor Who’s TARDIS, which is much larger than it appears to be from the outside. It has come to be almost synonymous with NAT, as it’s by far the most prevalent form of NAT today. However it’s important to remember that the different types of NAT have different properties, and different goals. In the following posts I’ll be keeping this in mind as I go through the objections to NAT and assess their validity.