Speaking in Tongues

It turns out it's remarkably simple to use multiple IPs on your linux machine.

Posted on December 12, 2017

Sometimes when you’re testing networked services, it can be handy to run one or more locally, each using a different IP, so that they appear as different machines on our network. For a serious setup, you’re probably going to want to use virtual machines, or a container based setup, like docker-compose or kubernetes.

Today I learned that you don’t necessarily need all that infrastructure: let’s say your primary network device is wlp3s0 (this will likely be different on your machine). Running ip addr show on it will give you a bunch of information, including any existing IP addresses it’s using:

sudo ip addr show wlp3s0

> 3: wlp3s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
>     link/ether ac:b5:7d:6f:d3:b1 brd ff:ff:ff:ff:ff:ff
>     inet 10.0.0.31/24 brd 10.0.0.255 scope global dynamic wlp3s0
>        valid_lft 586742sec preferred_lft 586742sec
>     inet6 2601:643:8400:5548::eb59/128 scope global dynamic
>        valid_lft 586931sec preferred_lft 586931sec
>     inet6 2601:643:8400:5548:4750:7b2b:93ac:8169/64 scope global noprefixroute dynamic
>        valid_lft 310560sec preferred_lft 310560sec
>     inet6 fe80::dba1:e0e6:c717:bc5c/64 scope link
>        valid_lft forever preferred_lft forever

Adding a new IP is as simple as:

sudo ip addr add 192.168.3.1 dev wlp3s0

If you run ip addr show again, you should see your new IP listed. Now we can run a service, and bind to this IP. For example, our trusty python simple server:

python3 -m http.server 8000 --bind 192.168.3.1

NB: regardless of which IP you bind to, you will still need to use different ports, else they will clash. For example, the following will fail:

python3 -m http.server 8000 --bind 0.0.0.0

It is also worth noting that adding addresses this way is not permanent, so it’s great for testing things out.