Menu

Ever wanted VM IPs that didn't conflict?

For a while I found myself on LANs that used different address blocks: 10.x.x.x, 192.168.x.x, etc - necessitating I change all the addresses for my local VMs. What if we could requisition some IPs that should never conflict?

Warning: This is cursed, don't ever do this in production or in a product. This works because of the implementation on Linux, RFCs around IP addressing are quite explicit that this should never happen / be possible.

Loopback is quite a large address space: 127.X.X.X. Despite this, the vast majority of software only ever binds to 127.0.0.1, meaning theres a lot of waste. While in gross violation of the spec, I wanted to see if I could vacuum some of this address space locally for my own purposes, and it turns out you can (on Linux).

[xxx@xxx:~]$ sudo ip addr add 127.0.0.1/16 dev lo
[xxx@xxx:~]$ sudo ip addr del 127.0.0.1/8 dev lo
[xxx@xxx:~]$ ifconfig

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.255.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:400 errors:0 dropped:0 overruns:0 frame:0
          TX packets:400 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:37840  TX bytes:37840

...
    

Great! now i can use 127.1.0.1 and onwards for my local VMs.

So why does this work anyway?

While the spec says that loopback addresses should always be dropped in routing, it turns out that Linux doesn't treat them specially. Instead, a default loopback interface will have the standard 127.0.0.1/8 range mapped to it, but it can be changed.

Any new interfaces (such as an veth or a tun device) can now use the free addresses without conflict, and they will be routed according to the regular semantics for IP networks. However, any attempt to route such traffic outside the local machine will fail, so a local NAT will be needed if those VMs need internet access.

This pattern is widely used within kernel tests as well, so its likely this will never be changed.