This chapter was meant to be the first part of a three part series on Homenet for the Linux Journal. Very sadly, the journal closed down in August 2019 and so this was never published.
This article, and the following ones, makes many references to RFCs. These are the IETF Request For Comments, and often are the formal specifications of many internet protocols. They are usually pretty heaving reading! They are all at https://www.ietf.org/standards/rfcs/.
Home networking seems to be pretty straightforward right now. You can add almost anything in a plug-n-play mechanism, and mainly, things just work. The home network typically uses IPv4 which has been around forever, it uses DHCP and NAT transparently to manage only having one IPv4 address, you can add wireless extenders, add Zigbee networks through a gateway, and most of the time our precious geek skills aren't needed any more. What could change?
Bandwidth requirements are obviously increasing, with 4k TVs becoming common and 8k on the horizon. A 2017 report by the Australian NBN Co estimates that the typical Australian home will have 30 connected devices by 2020, while forums such as the LIFX forum have many posts on the failure of many wireless routers to cope with more than 30 devices. Of course, not all the home devices are on WiFi. Some will be on Zigbee, Z-Wave or 6LoWPAN networks, bridging through to the home IP network. Complexity is steadily increasing. In the not too distant future many of us will have multiple ISPs, with access via 5G wireless as well as landline into the home, using hubs such as the HTC 5G Hub.
With this increasing complexity, the IETF (Internet Engineering Task Force), responsible for the multitude of internet technologies such as TCP/IP, has devised an architecture which it believes is suitable for home networks of the future: Homenet. It is based on IPv6 rather than IPv4, does away with NAT, can use multiple subnets each for their own purpose, manages addresses from several ISP connections and exploits the IPv6 addressing system to full advantage.
In these articles, we look at what is involved in setting up a Homenet. While in the future this process is hoped to be transparent or at least friendly for the home user, at present much of it is geek territory. It is hoped that engineers will take this nerd-level knowledge and build user-friendly systems. The aim is for Homenet to be even easier to use than current IPv4 systems, but based on a more solid architectural base.
This series looks at Homenet, and how to get there from here. We start from the assumption of "simple" home networking using IPv4, and build up to the current state of Homenet. That can all be done using current tools and distros. We divide this into several parts:
Most home systems are currently IPv4, apparently, but maybe not actually, on a single subnet. NAT (network address translation) is in heavy use both to overcome the shortage of IPv4 addresses (good) and to act as firewall and filtering mechanism (bad). The good side of NAT is that it allows a single IPv4 address to act for a whole subnet of hosts, with hosts able to access external global addresses via a mapping mechanism of IP packets.
NAT however suffers from a number of issues which have been well documented. It doesn't easily scale up to complex systems with double- or even triple-NAT with corresponding fragility. Services running within the network which need to be accessible from outside use techniques such as port forwarding either manually configured or using UPnP IGD (Internet Gateway Device protocol), or (unreliable) hole punching. Double NAT (NAT router within NAT network) will often break services which rely on hole punching, such as many VoIP services amd multi-player games.
With IPv6, NAT goes away. Services on different hosts have their own IPv6 address so NAT workarounds like UPnP IGD are not needed. Port forwarding is replaced by routing which simplifies security. DHCP is still there, but there is also SLAAC (stateless autoconfiguration) for better autoconfiguration of IP addresses. In all, there are good technical reasons to move to IPv6, and for the ordinary user, it is a pretty seamless transition.
My ISP is the Australian company Lightning Broadband. By default, I only got a single IPv4 address from them, and used NAT and DHCP to deal with the hosts in my network. But all I did was ask, and they provisioned me with IPv6. Hopefully your ISP can do the same.
My router is a Linksys EA6900.
Under the Connectivity menu entry is a flag to turn
IPv6 on.
While it is a satisfactory home router, it is woefully
lacking when it comes to telling me what is going on.
There are no logs to tell me what is happening,
and the first indication I had that IPv6 was working is
that using ifconfig
, IPv6 addresses suddenly
started showing up on my PCs and laptops.
This part of the series is about what you can expect to see and do with IPv6 on your network with a consumer home router. Note: home routers vary widely in their IPv6 support. A rock-bottom router such as the Edimax N300 has no IPv6 support. Up a level in cost, the TP-Link Archer C60 claims to support IPv6, and does get external IPv6 addresses but requires manual configuration on the LAN side. The mid-range Linksys EA6900 is better still, but not ideal.
"IPv6 addresses suddenly started showing up..." How was that?
What did they look like?
This section is a primer on IPv6 address - skip if you already know.
IPv6 addresses are 128 bits, usually expressed in hexadecimal (4 bit) nibbles,
2 per byte. Each address thus uses 32 nibbles and a typical example could be
2400:3740:200:d900:39d4:560b:ef93:e50
.
There are shortcuts which use special rules, with the simplest case being
::1
for the loopback address for localhost. Apart from
that address, IPv6 addresses are singularly unmemorable and usually
require a DNS server to map names to addresses.
This will turn into one of the Homenet requirements: appropriate zeroconf DNS servers within the home.
Traditionally one used ifconfig
to find out network information.
This is being replaced by ip
. To find the addresses assigned to the
interfaces on a host, use
ip addr
or for a particular interface, say
ip addr eth0
Before delving into the addresses, please note a change of notation
from using netmasks to CIDR (classless inter-domain routing, if you can figure out
what that means!).
IPv4 addresses were traditionally listed by the IP address itself, and the
32 bit netmask
for that network. So for example, ifconfig
would report
inet 192.168.1.4 netmask 255.255.255.0 ...
For IPv6, we don't want a 128 bit netmask - 32 hexadecimal digits are too cumbersome!
What is used is the prefix
length, standing for the number of bits used to distinguish this network
from any other. Ths is known as CIDR format.
So the above netmask of 255.255.255.0
corresponds to a prefix length of
24: 24 binary ones followed by 8 zeroes. The IPv6 address below comes from a 64 bit
prefix, or a /64 prefix:
inet6 2400:3740:200:d900:39d4:560b:ef93:e50 prefixlen 64
That is, a 64-bit (16 nibbles) network address of 2400:3740:200:d900
and a 64-bit (16 nibbles) node address in that
network of 39d4:560b:ef93:e50.
Here is one of the little secrets of IPv6. Much is said about an address space of size 2128. In practice, 64 bits is the maximum prefix size allowed for the network address, and the remaining 64 bits are for the node addresses within that network. So there can be 264 networks, with each one containing 264 nodes. (Again, simplified from reality, but you get the idea, I hope).
A prefix might be, say, /56. This means that you have one network of a 56 bit prefix, with 28 possible subnets each with upto 264 hosts. This will be another component of Homenet: it wants to support subnets in the home, so your ISP will hopefully be giving you a /48 prefix or at worst a /56. If they only give you a /64, then you can't do any proper IPv6 subnetting and need to change your ISP.
Running ip addr
on a host will often produce an output
such as
inet 192.168.1.1/24 brd 192.168.1.255 scope global eth0 ...
inet6 2400:3740:200:d900:f49f:eb3b:2b04:64a5/64 scope global temporary dynamic ...
inet6 2400:3740:200:d900:461e:a1ff:fe3b:7531/64 scope global dynamic ...
inet6 fe80::461e:a1ff:fe3b:7531/64 scope link ...
Apart from the first entry of the IPv4 address, the rest are IPv6 addresses,
here of 3 kinds. They are
These addresses are non-routable and correspond to the IPv4 private addresses. They have the prefix fe80::/10, such as the above fe80::461e:a1ff:fe3b:7531. They are typically self-assigned (often based on the MAC address), and are unique on any network segment. They can be replicated on different segments though by other independent hosts: that is, two hosts on different networks can have the same link local address. So they cannot be used as globally unique addresses.
This possible duplication on different network segments causes
ambiguity to certain programs.
For example, ping
doesn't know which interface to try if there are multiple interfaces.
The command
ping fe80::c474:4605:44af:462c
throws up the uninformative error
connect: Invalid argument
What it means is that the interface hasn't been specified. The command
for interface wlp2s0
should be
ping -I wlp2s0 fe80::c474:4605:44af:462c
(you can use ping
or ping6
- they are the same executable)
or you can put the interface after a '%' sign in the address:
ping fe80::c474:4605:44af:462c%wlp2s0
A GUA (Globally Unique Address) is just that: routable and unique on the internet. It is formed from the prefix and usually the MAC address (but see the next section). An example in the above is
inet6 2400:3740:200:d900:461e:a1ff:fe3b:7531/64 scope global dynamic
'global' is the keyword here.
These addresses are also GUAs, globally unique and routable. However, they are temporary addresses created for example by a browser for a session. They are typically randomly generated from the prefix, and are relatively short lived. They hide the 'real' identity of the originating host for privacy reasons. See IPv6 temporary addresses and privacy extensions for further details. (and RFC4941). An example, in the above is
inet6 2400:3740:200:d900:61dc:bd3c:bfe7:c2e1/64 scope global temporary deprecated dynamic
'global temporary' are the keywords here.
These addresses don't last long and are just to obfuscate the 'real' GUA from the
rest of the world that doesn't need it.
In addition you will later come across
A ULA (unique local address) is in the range fc00::/7. You can choose any addresses in that range. Their purpose is to provide unique addresses within a network of possibly many subnets, and is routable across all those subnets - but not externally. They may be generated as SLAAC or DHCPv6 addresses.
The 'scope' for those subnets is deliberately not specified, but for home networks is most likely to be all those internal subnets reachable from your ISP gateway, and the gateway itself forms the 'boundary' of the network. These addresses are intended to allow access to any host throughout a household network. All nodes on the network should have a ULA, so that each node can address any other node. For example, the home file server and the home web server will have ULAs so every host on the home network can access them.
Multicast addresses are in the ff00::/8 block. I will use some later, and there will be more detail in the next section and in later parts of this series.
An interface wil typically have at least three IPv6 addresses: a link-local address (LL), a unique local address (ULA) and a globally unique address (GUA). It may have many more though, such as temporary GUAs. This is different to IPv4 where an interface usually only has one address.
We won't actually need this information, but it is worth asking how link local addresses and permanent global addresses are generated. Everywhere you will read that they are generated from the 48 bit MAC address: stretch the MAC address a bit, pad the middle with some extra bytes, flip some bits and there you have it - an EUI64 address (extended unique identifier, 64 bits).
Of course, it is more complex than that. This section isn't required, but may help in understanding the addresses you will see on your own system. The address assignment types include
You can hard-code the address.
System administrators might like to do this for e.g. servers,
to ensure they can remember their address. The assignment might be
based on the IPv4 address, such as 2400:3740:200:d900::192.168.1.1
corresponding to an IPv4 address of 192.168.1.1
A node queries the router for an address prefix. It then creates its own GUA typically by appending the EUI64 part to the prefix. The router will not typically know this address - and neither will anyone else! This could cause issues if you need to find the address of the node - see later for zeroconf DNS. See http://computer-outlines.over-blog.com/article-dynamic-ipv6-networking-part-4-slaac-118827328.html for more details. SLAAC addressing is used according to bits set in the router prefix information.
This is most like DHCPv4, where the router is asked to determine an IPv4 address from an ethernet address. DHCPv4 may give an IPv4 address by looking up an administrator supplied table of MAC/addresses or by generating one from a certain range.
The IPv6 variation is that instead of an ethernet or wifi MAC address, it supplies a DUID (DHCP Unique Identifier). Currently recognised formats (RFC8415) include
Stateful addresses assigned by the DHCPv6 server can be used for DNS lookups directly from that server.
There is a further hiccup in this, to do with SLAAC EUI64 addressing. Wherever you are, EUI64 will generate the same address component. If you are a mobile device, that will give you the same address component on each network you visit. Potentially this could allow your device to be tracked, reducing privacy.
This is addressed by RFC7217 with the cumbersome title "A Method for Generating Semantically Opaque Interface Identifiers with IPv6 Stateless Address Autoconfiguration (SLAAC)". What it does is to ensure that on each network it has a stable GUA, but on different networks it has a different GUA with a different node component. This has recently been adopted by the Linux NetworkManager, so on recent Linux systems you may see GUAs that are not related to the MAC address. This is a different mechanism to the temporary addresses of RFC4941, to address a different use case.
The web site
Test your IPv6 connectivity
will perform a set of tests on your browser to check
whether you are now on the internet using IPv6.
It gives good instructions, and hopefully you will get
to see an image as in Figure 1.
You can also install an extension/addon
IPvFoo for Chromium
or
IPvFoo for Firefox
which
for any web page gives an
indication as to whether it has connected via IPv4 or IPv6 (a '4' or '6' in the extensions bar)
Fnding out what hosts are on your IPv4 network is easy. Say it is a 192.168.1.0/24 network, then this command will list them
nmap -sP 192.168.1.0/24
That is quick because nmap
only has to scan 28 (256) addresses.
But it won't work for IPv6 when you have to scan 264 possible addresses - a simple
coffee break won't be long enough to scan 18,446,744,073,709,551,616 addresses!
Instead, the best way is to send out a multicast request that hosts should understand and respond to. Packets sent to the multicast address ff02::1 are received by all nodes on the local network segment. Depending on the message, they may respond. The ICMP6 (ping6) messages can ask for various things (as described in RFC4861) and I will look at some of those messages types (router discovery for example) in the next part of this series.
For now, one type is Neighbour Solicitation, which asks for the link layer addresses of neighbours. They respond with Neighbour Advertisements. In other words, ping to all neighbours.
Ping produces many responses, each having a sequence number, timestamp, etc. Throw the 'noise' away and collect just the link local addresses found on interface wlp2s0 by
ping6 -I wlp2s0 -c 10 ff02::1 | awk '{print $4}' | sort | uniq
(replace wlp2s0 by your interface). You will get output such as
fe80::224:21ff:fe43:4aed%wlp2s0:
fe80::3a4b:72ff:fef0:26c3%wlp2s0:
...
Another way of discovering local nodes is to use the network discovery cache. This replaces ARP (address resolution protocol) and is based on the node advertisements on ff02::1. It can be seen by
ip -6 neigh
It can produce output of a set of link local and GUA addresses like
2400:3740:200:d900::1 dev wlp2s0 lladdr 38:4b:72:f0:26:c3 router STALE
fe80::c8a3:2491:1c9c:adf9 dev wlp2s0 lladdr 44:1e:a1:3b:75:31 STALE
...
There is also an option to nmap
:
sudo nmap -6 --script=targets-ipv6-multicast-echo.nse
This also will take results from a cache as in
Starting Nmap 7.60 ( https://nmap.org ) at 2019-03-09 12:41 AEDT
WARNING: No targets were specified, so 0 hosts scanned.
Pre-scan script results:
| targets-ipv6-multicast-echo:
| IP: fe80::c8a3:2491:1c9c:adf9 MAC: 44:1e:a1:3b:75:31 IFACE: wlp2s0
| IP: 2400:3740:200:d900::1 MAC: 38:4b:72:f0:26:c3 IFACE: wlp2s0
...
Finally, I will mention
v6disc.sh
which combines many of these methods. In normal use it returns the GUAs of the
nodes on the network:
$bash v6disc.sh
-- Searching for interface(s)
-- Found interface(s): wlp2s0
-- Detecting hosts on wlp2s0 link
-- Discovered hosts for prefix: 2400:3740:200:d900 on wlp2s0
2400:3740:200:d900::1 38:4b:72:f0:26:c3
2400:3740:200:d900:a56f:9aa2:63e1:6602 d0:7e:35:6b:fd:9b IntelCor
-- Displaying avahi discovered hosts
2400:3740:200:d900:6079:65fd:7e90:d4bf netbook-3.local
while v6disc.sh -L
shows the link local addresses:
$bash v6disc.sh -L
-- Searching for interface(s)
-- Found interface(s): wlp2s0
-- Detecting hosts on wlp2s0 link
-- Discovered hosts for prefix: fe80: on wlp2s0
fe80::224:21ff:fe43:4aed%wlp2s0 d0:7e:35:6b:fd:9b IntelCor
fe80::3a4b:72ff:fef0:26c3%wlp2s0 d0:7e:35:6b:fd:9b IntelCor
although it doesn't get the MAC address or manaufacturer correct.
vdisc.sh
uses additional techniques such as malformed messages to get Windows computers
to respond, using the techniques described in RFC7707.
One oddity that you might notice is that there may be missing GUAs: you may be seeing one of the privacy preserving addresses in the cache and not the permanent address.
I run my own web server as well as ssh and UPnP servers. The web server is exposed to the internet by NAT'ing the IPv4 address out through my router's IPv4 address. Many of us have been doing this for years, both manually and by using programs that do it for us.
NAT is gone in IPv6. Well, it's still there in one form, but you aren't supposed to be using that.
So what do we have in its place? That's easy: IPv6 global addresses. As a result of the ISP enabling IPv6 to my router and handing it an IPv6 prefix, my router is able to give prefix information to the nodes in my network, using router advertisements. The individual nodes then assign themselves one (or more) global IPv6 addresses, which gives them unique addresses in the internet. So my web server has a GUA, my ssh server has a GUA, but also my laptops, PCs, phones, tablets and everything else now have IPv6 GUA's.
Does that mean anyone can now access all of the nodes in my network? No: you have to distinguish between addressability and accessibility. The nodes are all addressable, but if your router is any good it will have set up a firewall, blocking accessibility.
The equivalent to setting up a NAT mechanism is done by
opening up the firewall to an interface address on a port.
On my Linksys router this is done under the Security tab,
see Figure 2.
There is one significant difference in appearance of my services on the internet: under IPv4 the address of a service was the single IPv4 address of my router. Under IPv6 the address of a service is its global IPv6 address, and each separate host in my network will have a separate IPv6 address.
It also means my router has its own internal and external GUAs.
When I'm running an HTTP server on a different host using NAT,
I can't access the HTTP
server on my router externally via IPv4, as it goes through to my
NAT'ed server. Now I can using IPv6, because they have different GUAs.
I'm not sure if I want to access it that way,
but it definitely means I can't leave
the default router login as admin/admin
- DUH!
I use an external DNS provider Zoneedit for my domain jan.newmarch.name. Adding IPv6 also has implications for any external DNS lookups: a single DNS entry for the IPv4 router allows access to multiple IPv4 servers, but each IPv6 host would require its own DNS entry. That isn't a bad idea anyway, with separate DNS entries for www.jan.newmarch.name, ssh.jan.newmarch.name (this one doesn't actually exist :-) and so on. So I had to update the DNS entries to include the right IPv6 as well as IPv4 entries: router address for NAT IPv4 and web server GUA for IPv6.
This article has discussed adding IPv6 addressing to an existing home router, what the addresses look like, how to find IPv6 addresses of nodes on the network and how to make IPv6 addresses externally visible. The next part of this series will be on how to build your own router for both IPv4 and IPv6 using OpenWrt so that you get more control and visiblity over what your network is doing.