Simple Ipv6 Config in Azure

Using IPv6 in Azure VNETs

Posted by     "Ward van Besien" on Tuesday, 24 December 2019
Last Modified on Friday, 10 January 2020

Azure IPv6 support is now out of preview and available for use.

This is no doubt good news, but Microsoft hasn’t gone the full hog and implementation has a couple of annoying limitation:

  • even with IPv6 on your resources, public ingress traffic is still being nat-d.
  • Microsoft will not supply an IPv6 prefix you can use within your network. You can get a tiny prefix for public IP addresses, but not to assign to your VMs.
  • at the moment, you cannot create an IP configuration on a NIC using the GUI. You can view it however.

That is unfortunate. One of the benefits of IPv6 is that if you use public IP addresses even for internal resources, you don’t really have to worry about IP address conflicts. Given that I often get involved in projects where multiple networks are being merged, this is actually a potential massive benefit we are losing out on.

Yes, I am suggesting the use of public IP addresses on your servers, and before you start screaming and shouting about security… NAT isn’t security, it wasn’t designed for security and shouldn’t be relied on. In fact, if using public IP addresses forces you to rethink how you secure your servers and data, it’s actually a good thing.

True, you can use your own public address space, but that requires those address to be assigned to your ASN (possibly in your country) which means that all traffic for those address will route through your own network first. This is hardly efficient.

I know this may annoy some people at Microsoft, but AWS does provide public address space. Now, you don’t get to choose, but that really shouldn’t matter, as long as the addresses are unique and don’t change.

Isn’t IPv6 complicated?

Really not has complicated as generally assumed. Yup IP addresses are longer, but the use of router advertisements or DHCP is strongly encouraged. So, you shouldn’t be entering them that often. It’s newer than IPv4, and thus a bit improved in some areas. Longer address may also be harder to summarise, although again, it isn’t as hard as you may think (see below). If you actually use public IP addresses throughout, your firewall configuration doesn’t require any NAT, so you won’t need any of that config, and firewall rules are surprisingly straightforward. Hosts all go in a /64 subnet, so you don’t have to spend too much time thinking about the size of a subnet, because it’s really one-size-fits-all.

To get started

Because Microsoft won’t supply addresses, you’ll have to bring your own. The samples on Microsoft’s website are not overly helpful if you are not very experienced with IPv6.

Just like with IPv4, for IPv6 we also have private addresses. As usual, the range is quite large, but to make things simple, start with ‘fd00’.

In fact, the only thing fixed is the fd, however you must include trailing 00 in a hextet, so fd00 is where to start. fd01, fd02 are all valid.

A couple of things to be aware of:

  • IPv6 subnet with hosts are always /64. This is an enormous address space. This is the current convention and doing anything else may get you errors.
  • It’s normal that your VM will have multiple addresses. They serve different purposes. Addresses starting with fe are link local, there are not the same as private addresses. They do not route.
  • the convention is to use 48 bits for the prefix, 16bits for the subnet and 64 bits for the hosts. With all prefixes starting with fd, you effective have 40 for for prefixes.
  • subnetting and NSG is the same as with IPv4.

While this /64 may seem large, keep in mind that some of the traditional reasons to create smaller subnets (/24 for example) do not apply. There’s no broadcast domain or collision domain. Hence, having a large subnet doesn’t come with the same traditional drawbacks. You can safely create very large subnets if you want.

dissecting an address

What’s this hextet thing? Where an octet refers to 8 bits written in some form you can understand, a hextet refers to 16bits.

However, let’s just look at an IPv6 address to put this in context:

fd00:8003:c02f:4e01:8ab:8d6c:307f:4b85

The last 4 hextets, are the host portion. This is automatically generated based on the mac address of the host so this is unique. If you want to use a static address, it would look something like: 0000:0000:0000:0001, which Azure won’t let you enter, so it’ll be shortened to ::1. Typically, you only bother for your DNS servers…

The first 4 hextet make up the prefix portion and the subnets portion. Typically, if you were to request a public block of address space, you’d be allocated a /48. Although, for smaller usecases (like home users) you may only get a /56. A /48 is simple: it’s the first 3 hextets. for example 2001:8003:c01f::/48 is a public prefix. This one belongs to Telstra in Australia (one of the many used on the ISP side). So, if this is the prefix you get from the registry, ALL your IP address will start with the same 3 hextets. After you’ve entered this manually a couple of times, you’ll remember them well.

So, that leaves 16bits, to carve up, and 16bits, gives you 65556 possible subnets. That’s quite a lot of address space.

creating your own address space

The following is just a suggestion, but if starting out with IPv6, it’s a safe place to start.

So, while IPv6 addresses are 128 bit, we already use 64bit for the host portion. This may be wasteful, but because there is such a large address space, we’re not likely to run out, and later could potentially be changed.

IPv6 addresses are divided into 8 hextets of 16bits. So, if I use the first for my ‘fd00’, and the last 4 are the address bit, leaves me with 48 bit of address space to allocate. This is larger than the whole internet, so you should be able to handle this.

So keep things simple: start with fd00

then use two hextets to specify a location. fd00:xxxx:xxxx

and the next hextet to subnet within a location. A location in this context is a datacentre, subscription etc.

So, use hextet 2 and 3 to set the address space for your VNET, and the following for the subnets. You can create a nice repeatable scheme if you want.

I have at times used the second hextet to specify the country, and the next to specify the different network in that country.

That gives you 65K vnets, with 65K subnets in each country. Should be enough.

With IPv6, in each hextet you can remove leading zeros (not trailing) and you can skip all the hextets that are zeros (but only once). Thus, fd00:61:00:00:00:00:00:00/48 is the same as fd00:61::/48. Azure will require you to enter the shortest form.

Working with hextets

Creating route summaries for routing and firewall rules isn’t as hard it it first seems, as long as you know what the structure of a hextet is and how it translates to the underlying binary.

Effective, with IPv4, an octet is 8 bits converted to a decimal number between 0-255. For example: 00111011 translates to: 59.

To convert that, you need to know the value of each bit which in the above example goes like this:

bit value bit in example value
1 128 0 0
2 64 0 0
3 32 1 32
4 16 1 16
5 8 1 8
6 4 0 0
7 2 1 2
8 1 1 1
total 59

Add those numbers up and you get 59.

The reverse isn’t that hard either. Start from bit 1 (with value 128), does 128 fit in 59 (no), so bit is 0. For bit 3, does 32 bit in 59, answer is yes, so, bit 3 will be 1, does bit 4 (16), find in the remainder (which is 59-32 = 27), again yes, so bit 4 is also 1. And so on.

IPv6 works similarly, but because a hextet is 16 bits, they actually simplified things (yeah), as long as you can count to 16. IPv6 address are written in hexadecimal, which uses 0 1 2 3 4 5 6 7 8 9 A B C D E F to write things. If you take fd00 for example, you do not need to convert to 16 bits, you’d convert to 4x4 bits. Thus: fd00 translates to 1111 1101 0000 0000.

With 4 bits, we have a value of 0 to 15, written in hex that is 0 to F.

Hexadecimal writes numbers on a scale of 0 to 15, with numbers 1 to 9 having the same values as in decimal, but 10 is written as A, 11 as B, 12 as C, 13 as D, 14 as E and 15 as F. That way, it’s still a single character.

So with values as follows:

bit value bit in example value
1 8 0 0
2 4 0 0
3 2 1 2
4 1 1 1
total 3

This example shows 0011 equal 3 in hex.

The good news is that within that hextet of fd00, each character is one 4 bit block, rather than this being one big number.

indeed, because a private network uses fd::/8, the bits from 8 to 16 can be used. so, fd09::/16 is a valid private prefix. Next one btw isn’t fd10::/16. Remember we must increment each character separately, so the next one is fd0a::/16.

Summaries, and divisions with IPv6

So, if I have a hextet of 0000 and want to divide it in two? Well, for the first block that digit should translate to 0000 and for the second to 1000. In translated to hex, that becomes 0000, and 8000. Remember 8 is half of 16, so the middle between 0 and f.

Want to carve that up further? You can change the second digit: 8000 and 8800. It’s actually a nice hierarchical system, and you only need to be able to count to 16…

with IPv6, the same rule applies as with IPv4, move the prefix length left and you double the space, move it right and you have it. Thus /56 is twice as large as /57.

Setting this up in Azure

IPv6 addressES can be allocated at creation time. It’s important to understand the the IPv6 address is completely separate from the IPv4 address space. This is a dual stack, while they share the VNET and subnet resources, ultimately, connectivity, routing is completely separate.

create VNET with with IPv6

This this example, I use fd00:61::/48 as my address space for the VNET. Essentially, that’s the same as fd00:0061:0000:0000:0000:0000:0000:0000/48.

I just used 61 for my network in Australia as 61 is the country code. I could similarly use 81 for Japan.

The second network I’d create would actually be fd00:0061:0001:0000:0000:0000:0000:0000/48, which is shortened: fd00:61:1::/48, it’s the next after fd00:61::/48 although it has the same size, the way it’s written looks longer.

You also need to specify a subnet which has to be /64 in length. The one in this example is fd00:0061:0000:0001:0000:0000:0000:0000/64 or fd00:61:0:1::/64.


comments powered by Disqus