Nov 152022
 

This is intended as a basic guide to how IP networking works at the basic level; traditionally such guides are for “dummies” but a lack of knowledge doesn’t make someone dumb but ignorant and being ignorant of one small esoteric part of computing is no crime. On the other hand, fixing that ignorance can help solve certain networking issues or at the very least make those domestic router settings make some sort of sense.

What is IP?

Whether we are talking about IPv4 (192.0.2.98/24) or IPv6 (2001:db8:1:1::1/64), these are both at a superficial level both “Internet Protocols”. Networks require some kind of physical networking layer underneath the IP layer – most commonly Ethernet for wired connections and WiFi for wireless connections, but it can run on many other networks – FDDI (historical), Fiber Channel, or InfiniBand. IP works above that level.

What made IP “special” for the time was the word internet; we think of this today as a world-wide network (“The Internet”) but back in the 1970s, the internet part of IP was about connecting multiple networks together with a gateway. Whilst network gateways existed before IP (and indeed after), they translated one network protocol into another and not infrequently were application specific (i.e. perhaps only allowed email through) whereas IP was build from the ground up to allow network traffic to traverse multiple network gateways.

There’s a whole lot of detail we could get into about the “protocol” bit of IP, but an an early stage all we need to know is that the packet of data contains an IP header which amongst other things specifies the source address, destination address, and a hint of what’s inside.

IP Addresses

An IP address (whether a source address or a destination address) is either a 32-bit integer (for IPv4) or a 128-bit integer (for IPv6). Which is the technical way of saying they’re just numbers; although we’re used to seeing (and using) a standardised representation of that number. Some tools will convert the representation of the address or will use the actual number :-

» ping 3221226082   
PING 3221226082 (192.0.2.98) 56(84) bytes of data.

So the usual representation of an IPv4 address is a “dotted quad” – four numbers between 0-255 which when converted to binary and concatenated make up the real network address.

On the other hand, IPv6 is somewhat longer and uses groups of four hexadecimal digits separated with colons (“:”) as in:

2001:0db8:0001:0001:0000:0000:0000:0001

Although it is usual to compress that with two simple rules – firstly a number of sequences of all zeros can be replaced once with “::” :-

2001:0db8:0001:0001::0001

Secondly, leading zeros within each ‘group’ can be dropped :-

2001:db8:1:1::1

Even shortened, IPv6 addresses are somewhat more complex than IPv4 addresses, but that’s why we have the DNS; in fact those used to using IPv4 addresses without the DNS should bear in mind that IPv4 addresses are also too complex for normal people to get right (and are subject to typos).

Netmasks

Whether you are assigned a public IPv6 address (2001:db8:cafe/48) or pick a private address from RFC1918 (10/8) you have a “choice” – you can either use the entire network range for one huge network, or you can sub-divide it into smaller subnets. Most home users will go with the first option but for most organisations of a reasonable size, the later is not just preferred but essential.

Whether you further divide a network into subnets or not, your computer still needs to know whether to send packets directly to the destination or whether to route those packets via a gateway or a router. This is done with a netmask that defines the network part of the address (and the host part of the address). If the network address of the destination matches the network address of the source, then the packets can be sent directly. Otherwise they’re sent via the gateway.

AddressLocal?
Netmask255.255.255.0
Source address192.0.2.98Yes
Destination 1192.0.2.73Yes
Destination 2172.16.1.13No

IPv6 addresses work in the same way except the addresses are longer.

Although netmasks are historically given as dotted quads making them look a bit like IPv4 addresses, it is becoming increasingly common to use a more compact method which is less error prone. The netmask is instead specified as the number of bits that the netmask covers – 192.0.2.98/24 rather than 192.0.2.98/255.255.255.0. As for IPv6, the same applies although “/64” is very often assumed – the default size for an IPv6 network is very much more strongly encouraged than for an IPv4 network (although it isn’t compulsory).

The Gateway Or The Router

Gateway or router? Well both – from the perspective of an ordinary host it’s a gateway to other networks; from the perspective of the gateway itself, it is a router connected to multiple networks (domestically often just two) and forwards packets on behalf of other computers.

In essence there is very little difference between a router and an ordinary machine except that the ordinary machine isn’t configured to forward packets, and it is usually configured with just a default gateway (sometimes called a gateway of last resort). Well and the route for the network it is connected to.

Both contain a routing table (or more than one) in the operating system kernel which basically consists of a set of network addresses and destinations (where to forward the packets to). In the case of your usual domestic router that usually consists of a route to your home network, a route to the ISP’s network, and a default route pointing at the ISP’s router.

When a machine wants to send (or forward) a packet to a destination, it picks the closest match in the routing table, and uses that as a intermediate destination to forward the packet to. Your machine operates this way; as does the core Internet routers (although they have slightly larger routing tables).

Some routers (probably a minority) are rather more complex of course. If you have heard of routing software such as BGP, OSPF, or IS-IS, then you have heard of software that distributes routing information. The larger Internet uses BGP to distribute routing information to add to routing tables around the world.

The description of routing so far has been rather hierarchical – your computer forwards to a default gateway, and it in turn forwards to your ISP’s default gateway. Which is a bit unfortunate as Internet routing doesn’t really work this way – there are alternate routes so if one router goes “bang” traffic can still reach the destination.

Dover Castle Gateway
Jun 052019
 

On previous occasions (yes that does mean more than once) I have messed around with the network configuration of containers to get :-

  1. A consistent behaviour.
  2. A fixed IPv4 address with no DHCP configuration (this one is easy).
  3. A fixed IPv6 address with no autoconfigured global addresses (this one has been tricky)

This turns out to be relatively easy providing that you configure the addresses within the container rather than within the container configuration. At least it looks good to go so far (I’ve been mistaken in the past).

The container configuration is quite simple :-

lxc.net.0.type = veth
lxc.net.0.flags = down
lxc.net.0.link = br0

Note that the bridge interface (br0) may be different. Also note that there is no lxc.net.0.ipv4.address, lxc.net.0.ipv4.gateway, lxc.net.0.ipv6.address, or lxc.net.0.ipv6.gateway.

The configuration within the container is dependent on what userland you are running, but for Debian (and Ubuntu if you’re not using Netplan) :-

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
    address 10.0.0.34/16
    gateway 10.0.0.1

iface eth0 inet6 static
    address 2001:0db8:cafe:dead:0000:0000:0000:3eb/64
    scope global
    gateway 2001:0db8:cafe:dead:0000:0000:0000:0001
    privext 0
    accept_ra 0
    autoconf 0

Not sure quite which options are required but having all of “privext 0”, “accept_ra 0” and “autoconf 0” does mean no additional autoconfigured IPv6 addresses.

(And no the part number of this post isn’t anything more than a joke)

Oct 092018
 

And yes that includes me

For those who don’t know, RFC1918 is the Internet standard that allocates the addresses used for private networks – 10/8, 192.168/16, or 172.16/12. 

And in reference, specifically :-

To minimize the risk it is strongly recommended that an organization using private IP addresses choose randomly from the reserved pool of private addresses

(Apologies for the incorrect spelling above; it’s a quote from an American source)

This was reinforced to me yesterday whilst I was working from home, and I had trouble with a site-to-site VPN joining my network to work’s. As it happens there was no addressing conflict, but I had to install many routes more than should be necessary.

And I keep seeing this sort of thing; joining multiple networks when everybody is using 10/8 is a continual game of chicken – when are we going to find ourselves in conflict? 

Of course there is a “fix” for this – NAT. The real fix of course is to use global IPv6 addresses even for devices and networks that will never be on the global Internet.

The Window
Oct 192016
 

This is a bit of a thought experiment, so it may be not entirely correct (especially the maths – my probability theory is very rusty).

One of the lesser reasons for using the DNS rather than IP4 addresses is that typing mistakes are more easily caught – if you intend to type 192.168.67.52, but accidentally enter 192.168.67.53 instead, you still have a valid IPv4 address. Whereas entering the domain name wombar.example.com instead of wombat.example.com will most likely get you an error instead of sending your secrets off to an unknown location on your network – unless you have a rather silly server naming convention of course!

But how likely are you to make a mistake typing in an IPv4 address? According to a random web site “out there”, the average accuracy of a typist is 92%, or an average of 8 typos per 100 characters. If we convert this into a probability, we get a probability of typing each character correctly as 0.92.

Given that typing IPv4 addresses is something that some of us have a lot of practice at, and in many cases we will notice typos before they become a problem, I’m going to arbitrarily declare that the probability of getting any character within an IPv4 address correct is 0.999. But to type in an IPv4 address correctly we have to get a maximum of 15 characters correct :-

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
1 9 2 . 1 6 8 . 1 2 8 . 1 2 8

So the probability of getting all those characters right is 0.999 (first character) x 0.999 (second character) … Or 0.999^15.

And once you work that out, subtract it from 1 (to get the probability of making a mistake) and convert it into a percentage, there is an 11% chance of making a typo in an IPv4 address.

For an IPv6 address such as 2001:db8:ca2c:dead:44f0:c3e9:28be:c903, which has 38 characters (no I’m not doing that silly table for IPv6) – 100 * (1 – 0.999 ^ 38) – 32%.

Now whilst my calculations may be a bit off, the likelihood of entering an IPv6 address incorrectly is nearly three times higher than the risk of entering an IPv4 address incorrectly.

In other words, with IPv6 you really need a good working DNS solution just to keep the errors to manageable levels.

dam-ip6

Oct 032015
 

A newer post has more information (and more reliable information).

One of the things that has been mildly irritating me about my little collection of Linux containers has been that in addition to the statically defined IPv6 addresses, there is also an automatically defined IPv6 address :-

» lxc-ls --fancy
NAME      STATE    IPV4       IPV6                                                              AUTOSTART  
---------------------------------------------------------------------------------------------------------
apricot   RUNNING  10.0.0.34  2001:db8:ca2c:dead:21e:a0ff:feb6:6a, 2001:db8:ca2c:dead::3eb      YES        
chagers   RUNNING  10.0.0.32  2001:db8:ca2c:dead:804a:bfff:fe83:f98d, 2001:db8:ca2c:dead::5e11  YES        
glanders  RUNNING  10.0.0.31  2001:db8:ca2c:dead:21e:a0ff:feb6:66, 2001:db8:ca2c:dead::ba11     YES        
lyme      RUNNING  10.0.0.30  2001:db8:ca2c:dead:21e:a0ff:feb6:65, 2001:db8:ca2c:dead::cafe     YES        
mango     RUNNING  10.0.0.35  2001:db8:ca2c:dead:6c42:24ff:fe7d:4e9, 2001:db8:ca2c:dead::a      YES        
peach     RUNNING  10.0.0.33  2001:db8:ca2c:dead:21e:a0ff:feb6:68, 2001:db8:ca2c:dead::3a11     YES        
rhubarb   RUNNING  10.0.0.40  2001:db8:ca2c:dead:21e:a0ff:feb6:69, 2001:db8:ca2c:dead::dead     YES

Now this is hardly the end of the world, but it is not tidy and it is the sort of thing that may lead to problems down the road if servers are communicating on an address that is not reverse DNS registered. Or indeed when someone contacts a server on an address such as 2001:db8:ca2c:dead::3eb and the reply comes from 2001:db8:ca2c:dead:21e:a0ff:feb6:6a.

After any number of false starts, the answer is quite simple – use sysctl to turn off autoconfigured address from within the container; which doesn’t make much sense logically – containers don’t have a kernel of their own, so the global kernel should be the one that is tuned. However :-

for container in $(lxc-ls)
do
  echo net.ipv6.conf.eth0.autoconf = 0 >> /var/lib/lxc/$container/rootfs/etc/sysctl.conf
done

Does the trick (after a reboot)  :-

» lxc-ls --fancy
NAME      STATE    IPV4       IPV6                                                              AUTOSTART  
---------------------------------------------------------------------------------------------------------
apricot   RUNNING  10.0.0.34  2001:db8:ca2c:dead:21e:a0ff:feb6:6a, 2001:db8:ca2c:dead::3eb      YES        
chagers   RUNNING  10.0.0.32  2001:db8:ca2c:dead:18d9:99ff:fe28:3591, 2001:db8:ca2c:dead::5e11  YES        
glanders  RUNNING  10.0.0.31  2001:db8:ca2c:dead:21e:a0ff:feb6:66, 2001:db8:ca2c:dead::ba11     YES        
lyme      RUNNING  10.0.0.30  2001:db8:ca2c:dead::cafe                                          YES        
mango     RUNNING  10.0.0.35  2001:db8:ca2c:dead:2411:80ff:feb9:6600, 2001:db8:ca2c:dead::a     YES        
peach     RUNNING  10.0.0.33  2001:db8:ca2c:dead::3a11                                          YES        
rhubarb   RUNNING  10.0.0.40  2001:db8:ca2c:dead::dead                                          YES        

Except for the older containers 🙁

I’ve obviously missed something, but fixing nearly half of the containers is a good start.

After attending to pending upgrades (some of my old containers were still running wheezy), and setting the network configuration to manual, one of the recalictrant containers (glanders) lost it’s autoconfigured address.

Two more containers lost their unwanted extra addresses after “fixing” their configuration. I’m not sure what was wrong with the old configuration, but after copying and modifying a recently created container configuration, they rebooted with just one IPv6 address. The last one was mango, but after an extra reboot, it also was fixed :-

» lxc-ls --fancy
NAME      STATE    IPV4       IPV6                      AUTOSTART  
-----------------------------------------------------------------
apricot   RUNNING  10.0.0.34  2001:db8:ca2c:dead::3eb   YES        
chagers   RUNNING  10.0.0.32  2001:db8:ca2c:dead::5e11  YES        
glanders  RUNNING  10.0.0.31  2001:db8:ca2c:dead::ba11  YES        
lyme      RUNNING  10.0.0.30  2001:db8:ca2c:dead::cafe  YES        
mango     RUNNING  10.0.0.35  2001:db8:ca2c:dead::a     YES        
peach     RUNNING  10.0.0.33  2001:db8:ca2c:dead::3a11  YES        
rhubarb   RUNNING  10.0.0.40  2001:db8:ca2c:dead::dead  YES