Ever wanted VM IPs that didn't conflict?
For a while I found myself on LANs that used different address blocks:
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
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.