30

I know that the ip tool lets you bind multiple addresses to an interface (eg, http://www.linuxplanet.com/linuxplanet/tutorials/6553/1/). Right now, though, I'm trying to build something on top of IPv6, and it would be really useful to have an entire block of addresses (say, a /64) available, so that programs could pick any address from the range and bind to that. Needless to say, attaching every IP from this range to an interface would take a while.

Does Linux support binding a whole block of addresses to an interface?

Khaled
  • 35,688
  • 8
  • 69
  • 98
p-static
  • 403
  • 1
  • 4
  • 5
  • Different distros have different ways of handling this. Pick one. – Ignacio Vazquez-Abrams Dec 05 '10 at 00:34
  • Ubuntu right now, but solutions that work across distros are preferred, of course. – p-static Dec 05 '10 at 01:43
  • This tutorial binds a single address within a block (/24). The /24 just specifies which block it is in. It should work identically for IPv6. – BillThor Dec 05 '10 at 03:18
  • Cross-distro would be to write a script that uses "ip addr add". Red Hat, Ubuntu and SuSE have different networking scripts... – Sean Reifschneider Dec 05 '10 at 03:27
  • Yes, I know it works identically for ipv6. My point in linking that tutorial was to point out something that does *not* apply to what I'm trying to do, but is very similar. Again: linking up one address at a time (e.g., with "ip addr add") is a nonstarter, because I want to attach a *lot* of addresses to one machine efficiently. – p-static Dec 05 '10 at 10:23
  • Hi @p-static are you find solution for this? – Chandra Nakka Jan 13 '16 at 06:39
  • 1
    @ChandraNakka Is [this](http://serverfault.com/q/590038/214507) useful to you? – kasperd Feb 26 '16 at 17:08
  • @kasperd Hi friend, I'm already followed that instructions. Problem solved. Thank you :) – Chandra Nakka Feb 26 '16 at 17:39

5 Answers5

35

Linux 2.6.37 and above supports this via a feature called AnyIP. For instance if I run

ip route add local 2001:db8::/32 dev lo

on an Ubuntu 11.04 machine it will accept connections on any address in the 2001:db8::/32 network.

Gerald Combs
  • 6,331
  • 23
  • 35
  • 1
    Is there any AnyIP solution for ipv4? – Coaku Nov 26 '15 at 13:55
  • Is it work on Ubuntu 14.04 ? – Chandra Nakka Jan 13 '16 at 06:38
  • This does appear to work and I can ping the range of addresses but when I run `ip route list` or `ip -6 route list` the added route is not visible. How would you enumerate an AnyIP address block? – Colton Nov 13 '16 at 11:27
  • This works for the addresses locally but I can't ping or access these IPs from external sources. Any way to fix that? (I tried replacing lo with eth0 but then nothing is reachable) – BrainStone Apr 12 '17 at 09:05
  • @BrainStone you need to install ndppd for that, or get a prefix routed from your provider – Arya Oct 03 '17 at 05:17
  • @Colton you can see the new routes with `ip -6 route list table local`. – ntc2 Aug 19 '20 at 10:08
  • @Gerald I can ping these addresses, but I can't seem to bind them! For example, `nc -lkvn 2001:db8::1 8888` fails with `nc: Cannot assign requested address`. – ntc2 Aug 19 '20 at 10:11
6

Yes, Linux supports binding a block of network addresses to a network interface... but only on the loopback interface. So you can do this:

ip addr add 192.168.5.0/24 dev lo

And then do this:

$ nmap -sP -oG - 192.168.5.0/24

# Nmap 5.21 scan initiated Tue Dec  7 11:38:28 2010 as: nmap -sP -oG - 192.168.5.0/24 
Host: 192.168.5.0 ()    Status: Up
Host: 192.168.5.1 ()    Status: Up
Host: 192.168.5.2 ()    Status: Up
[...]
Host: 192.168.5.254 ()  Status: Up
Host: 192.168.5.255 ()  Status: Up
# Nmap done at Tue Dec  7 11:38:46 2010 -- 256 IP addresses (256 hosts up) scanned in 0.11 seconds

With the appropriate routes in place this will do what you want... for IPv4 addresses. You've asked about IPv6, and I don't have any experience with IPv6, but there's a good chance it will work the same way.

I originally read about this here (towards the bottom of the article). Note that this article also discusses how to explicitly assign multiple addresses to an interface using CentOS/Red Hat features I hadn't previously known about.

Lekensteyn
  • 6,111
  • 6
  • 37
  • 55
larsks
  • 41,276
  • 13
  • 117
  • 170
  • Cool! I tried this with IPv6 on Ubuntu (Lucid & Hardy) without any luck. I think this would be a killer feature for IPv6 — you could map addresses do database objects or use addresses as session IDs. – Gerald Combs Dec 22 '10 at 22:44
  • 2
    No, you should not add an address to lo. Instead, add a route: `ip -6 route add local dev lo`. – Navin Aug 30 '16 at 20:25
2

So I see a few options here:

  1. use a script to bind the addresses all to the interface individually

  2. route the block you want to the single address of your machine, and then have that machine use the pcap interface to intercept all traffic for said block (as if it was a router) and handle it.

  3. You could concievably play tricks with NAT rules to then rewrite a block of Ips that were routed to one machine into a single internal IP on that machine... but you'll still end up with one internal IP per IP you really want to pay attention to, which gets you back to solution 1.

If I were you, I'd just write the small script in option 1. Or use the one from here:

#!/bin/sh
if [ "$#" -ne "4" ]; then
        echo Usage:
        echo " $0 interface ip range netmask"
        echo " examples:"
        echo "  1) Assuming you want to bind the IP range 192.168.0.1..192.168.0.254 to eth0 with netmask 255.255.255.0:"
        echo "  $0 eth0 192.168.0. 1..254 255.255.255.0"
        echo "  2) Assuming you want to bind the IPv6 range 2001:41d0:1:5000::1-2001:41d0:1:5000::254 to eth0 with netmask /56"
        echo "  $0 eth0 2001:41d0:1:5000:: 1..254 56"
else
        echo "Attempting to assign the IP range $2($3) to interface $1 with netmask $4"
        for ip in $(eval echo "{$3}"); do ifconfig -v $1 add $2$ip netmask $4; done
fi
pjz
  • 10,497
  • 1
  • 31
  • 40
2

As others have said, you can use the AnyIP mechanism to route arriving packets for an entire subnet to the localhost interface, but keep in mind that you'll also need to get your upstream router to route all of the desired packets to this machine in the first place. This can be done simply with routing table entries on the router, or via BGP. ARP is not really appropriate given that your machine would have to ARP for each IP individually.

Kyle Rose
  • 21
  • 2
1

The "Anyip" described above didn't work for me on centos 7. I had to create a script to manually create ipv6 addresses at boot. To do so i have added the following to /etc/crontab:

@reboot root /path/to/bashscript

Here is the bash script to create roughly 3000 ipv6 addresses:

#!/bin/bash
INETP="2a00:xxxx:xxxx:xxxx::"
PRE="64"
INTE="eth0"
IP1=/sbin/ip
echo -n "Adding IPv6 addresses..."
for i in {3..3000}
do
$IP1 -6 addr add ${INETP}$(printf '%x\n' $i)/${PRE} dev ${INTE}
done
echo "Done!"
  • This method only works until you reach about 4000 addresses. If you try to configure more addresses than that it won't work. There are scenarios where it is desirable to assign an entire /96 or /64 to a single host, there is no way your method will scale that far. – kasperd Jan 24 '16 at 12:22
  • @kasperd where you able to make the so called anyip mechanism "described" by Gerald Combs above work on Centos 7 or Debian 8? – Nicolas Guérinet Jan 24 '16 at 13:28
  • 1
    Yes, that works. But there are a few more steps than mentioned in that answer. See [my answer](http://serverfault.com/a/591435/214507) to a similar question. – kasperd Jan 24 '16 at 13:52