21

I tried adding a whole IPv6 (/64) block to an interface using

ip route add local 2001:41d0:2:ad64::/64 dev lo

like described here on my Debian server, but I seem to be missing something.

If I ping for example 2001:41d0:2:ad64::fe locally everything works just fine, but if I try from a remote machine it does not work. I then tried adding the route on eth0:

ip route add local 2001::41d0:2:ad64::/64 dev eth0

Now I couldn't even ping any example address locally!

I'm a bit lost since I seem to be missing something but I can't find the answer here.

For short: I want 2001:41d0:2:ad64::/64 to be bound to eth0 so that every IP this block is containing will be reachable from the internet on my machine.

I hope someone out there can point me the right way. Thanks in advance.

The guide provided by the ISP does require me to add each IPv6 to the interface explictly. I want it to be implict.

Working configuration with explict ip address binding

/etc/network/interfaces:

auto eth0
iface eth0 inet static
        address my.ip.v4
        netmask 255.255.255.0
        network my.network.address.ip
        broadcast my.broadcast.address.ip
        gateway my.gateway.ip

iface eth0 inet6 static
        address 2001:41d0:2:ad64::fe
        netmask 64
        gateway 2001:41d0:2:adff:ff:ff:ff:ff
        up ip addr add 2001:41d0:2:ad64::1/64 dev eth0
        down ip addr del 2001:41d0:2:ad64::1/64 dev eth0
        up ip addr add 2001:41d0:2:ad64::2/64 dev eth0
        down ip addr del 2001:41d0:2:ad64::2/64 dev eth0
        up ip addr add 2001:41d0:2:ad64::3/64 dev eth0
        down ip addr del 2001:41d0:2:ad64::3/64 dev eth0
        up ip addr add 2001:41d0:2:ad64::4/64 dev eth0
        down ip addr del 2001:41d0:2:ad64::4/64 dev eth0
        up ip addr add 2001:41d0:2:ad64::5/64 dev eth0
        down ip addr del 2001:41d0:2:ad64::5/64 dev eth0
        up ip addr add 2001:41d0:2:ad64::6/64 dev eth0
        down ip addr del 2001:41d0:2:ad64::6/64 dev eth0
        up ip addr add 2001:41d0:2:ad64::7/64 dev eth0
        down ip addr del 2001:41d0:2:ad64::7/64 dev eth0
        up ip addr add 2001:41d0:2:ad64::8/64 dev eth0
        down ip addr del 2001:41d0:2:ad64::8/64 dev eth0
        up ip addr add 2001:41d0:2:ad64::9/64 dev eth0
        down ip addr del 2001:41d0:2:ad64::9/64 dev eth0
        up ip addr add 2001:41d0:2:ad64::a/64 dev eth0
        down ip addr del 2001:41d0:2:ad64::a/64 dev eth0

Solution try #1

I tried reenableing the local route as @kasperd suggested.

Content of my /etc/network/interfaces

auto lo
iface lo inet loopback
    post-up ip route add local 2001:41d0:2:ad64::/64 dev lo
    pre-down ip route del local 2001:41d0:2:ad64::/64 dev lo

auto eth0
iface eth0 inet static
        # <snip of ipv4 config>

iface eth0 inet6 static
        address 2001:41d0:2:ad64::fe
        netmask 64
        gateway 2001:41d0:2:adff:ff:ff:ff:ff

Local routing table:

# ip -6 route show table local
local ::1 dev lo  proto none  metric 0
local 2001:41d0:2:ad64::fe dev lo  proto none  metric 0
local 2001:41d0:2:ad64::/64 dev lo  metric 1024
local fe80::225:90ff:fe06:6bbe dev lo  proto none  metric 0
ff00::/8 dev eth0  metric 256

Output of traceroute (my local home PC):

  1    <1 ms    <1 ms    <1 ms  fritz.box [xxx]

  2    20 ms    21 ms    24 ms  2002:c058:6301::1
  3    21 ms    22 ms    24 ms  10gigabitethernet6.switch2.fra1.he.net [2001:470
:0:150::1]
  4    44 ms    31 ms    40 ms  100ge3-1.core1.ams1.he.net [2001:470:0:2d4::1]
  5     *        *        *     Zeitüberschreitung der Anforderung.
  6     *        *       35 ms  ams-5-6k.nl.eu [2001:41d0::8d1]
  7    37 ms    39 ms    36 ms  rbx-g2-a9.fr.eu [2001:41d0::ab1]
  8    37 ms    70 ms    36 ms  chi-3-4m.il.us [2001:41d0::176]
  9  Zielhost nicht erreichbar.

Ablaufverfolgung beendet.

traceroute6 on server:

traceroute to 2001:41d0:2:ad64::23 (2001:41d0:2:ad64::23), 30 hops max, 80 byte packets
 1  2001:41d0:2:ad64::a (2001:41d0:2:ad64::a)  0.028 ms  0.009 ms  0.008 ms

ping6 on server:

PING 2001:41d0:2:ad64::23(2001:41d0:2:ad64::23) 56 data bytes
64 bytes from 2001:41d0:2:ad64::23: icmp_seq=1 ttl=64 time=0.029 ms
64 bytes from 2001:41d0:2:ad64::23: icmp_seq=2 ttl=64 time=0.057 ms
^C
--- 2001:41d0:2:ad64:23 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.029/0.043/0.057/0.014 ms

tcpdump output (while pinging and tracerouting on remote server):

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes

tracert to the gateway:

Routenverfolgung zu vss-3-6k.fr.eu [2001:41d0:2:adff:ff:ff:ff:ff] über maximal 3
0 Abschnitte:

  1    <1 ms    <1 ms    <1 ms  fritz.box [2002:5476:1b4c:0:c225:6ff:fe40:b2b0]

  2    23 ms    22 ms    26 ms  2002:c058:6301::1
  3    24 ms    40 ms    23 ms  10gigabitethernet6.switch2.fra1.he.net [2001:470
:0:150::1]
  4    28 ms    37 ms    39 ms  100ge3-1.core1.ams1.he.net [2001:470:0:2d4::1]
  5     *        *        *     Zeitüberschreitung der Anforderung.
  6    38 ms    33 ms     *     ams-5-6k.nl.eu [2001:41d0::8d1]
  7    36 ms    39 ms    38 ms  rbx-g2-a9.fr.eu [2001:41d0::ab1]
  8    36 ms    35 ms    35 ms  vss-3-6k.fr.eu [2001:41d0:2:adff:ff:ff:ff:ff]

Ablaufverfolgung beendet.

ping to the gateway:

Ping wird ausgeführt für 2001:41d0:2:adff:ff:ff:ff:ff mit 32 Bytes Daten:
Antwort von 2001:41d0:2:adff:ff:ff:ff:ff: Zeit=36ms
Antwort von 2001:41d0:2:adff:ff:ff:ff:ff: Zeit=34ms
Antwort von 2001:41d0:2:adff:ff:ff:ff:ff: Zeit=38ms
Antwort von 2001:41d0:2:adff:ff:ff:ff:ff: Zeit=57ms

Ping-Statistik für 2001:41d0:2:adff:ff:ff:ff:ff:
    Pakete: Gesendet = 4, Empfangen = 4, Verloren = 0
    (0% Verlust),
Ca. Zeitangaben in Millisek.:
    Minimum = 34ms, Maximum = 57ms, Mittelwert = 41ms

So it's still just working locally (server) but not from remote (my pc).

8
  • So have you tried a traceroute from a remote machine? Where does the trace fail?
    – Zoredache
    Apr 19, 2014 at 1:09
  • If all the hosts are in the same network, you shouldn't had any route.
    – Spack
    Apr 19, 2014 at 1:10
  • Your second ip route command has a typo in the IPv6 address. Apr 19, 2014 at 1:30
  • @Spack I want eth0 to listen to a whole ipv6 /64 prefix (incoming traffic), @michael-hampton fixed, it was just while typing this question, @Zoredache It fails at the ISPs Gateway 2001:41d0:2:adff:ff:ff:ff:ff after that it will just timeout. Apr 23, 2014 at 9:36
  • From research I've done in the past, this isn't possible. The reason it works locally is because your routing table knows where to route packets. If you added this prefix as a static route in your edge router then you'd see LAN clients able to connect.
    – Nathan C
    Apr 26, 2014 at 19:59

3 Answers 3

18
+50

I have needed something similar in the past. I found that there are three steps needed to get this working:

  • You need to route a prefix to the host
  • You need a local route on the host
  • Applications need to set the IP_FREEBIND or IP_TRANSPARENT option on sockets

The proper way to get a prefix routed to the host involves contacting your provider, if they do not already provide you one. They may have a DHCPv6 server, which can delegate a prefix to you, if you just send the right DHCPv6 request to it.

If a real routed prefix is for some reason impossible for you to get, but you have access to use as many addresses as you want from a link prefix available on one of your network interfaces, you can turn part of that into a routed prefix by having a daemon respond to neighbor discovery requests for every IPv6 address in that range.

Using such a daemon is not recommended other than as a last resort, since it will needlessly consume memory from all your neighbors. There are a few implementations of such a daemon, one that looks promissing is ndppd. (I have no specific experience with it, since I only learned about it after I had written my own with my link prefix hardcoded.)

It looks like you already got the local route working. As you noticed, it has to be assigned to the lo interface in order to work.

Finally the applications using addresses from this range need an IP option in order to be able to bind to addresses, which are not explicitly assigned to a specific network interface on the host. Here is a code fragment, that can be used:

const int one = 1;
setsockopt(fd, SOL_IP, IP_FREEBIND, &one, sizeof(one));
24
  • I've got a static prefix routed to my server by the ISP (they do not provide DHCP. Neither fo IPv4 nor IPv6). I want all IPv6 in this /64 block to be reachable from the outside (most of my applications bind to :: which should be all available addresses if I'm not mistaken). Now I want all these IPs to be available on eth0 so if I try to connect to any IPv6 in that block any application listening to the specified port will be able to answer (for example each IP should respond to ping correctly). Apr 26, 2014 at 13:23
  • If you bind to :: the IP_TRANSPARENT option is not needed. With a prefix routed to my server and the local route in place, I can bind to :: and receive connections made to arbitrary IPv6 addresses in that range. ping6 works as well. I am testing this on Ubuntu 12.04, but I would expect it to work on any recent kernel on other distributions as well. If it is not working for you, I suggest you take a look on the network traffic using tcpdump -pni eth0 'host 2001:41d0:2:ad65::fe'
    – kasperd
    Apr 26, 2014 at 21:12
  • It's still not working. I provided a few more information on the configuration in my question, maybe this helps. Apr 26, 2014 at 23:42
  • You say that you have a /64 routed to the server. But the examples in the hosting provider's guide only has a link prefix and no routed prefix. And the tcpdump and traceroute6 output looks like the addresses are not routed to the server. Have you managed to get a single IPv6 address working using the documentation from the provider?
    – kasperd
    Apr 27, 2014 at 3:03
  • 1
    @Arya When I needed such a thing I put the command in /etc/rc.local
    – kasperd
    Oct 1, 2017 at 21:09
8

It's 2019 year now. One word: ip_nonlocal_bind (since 4.3 kernel as i may know).

Use ndppd + sysctl net.ipv6.ip_nonlocal_bind = 1, last one allows you to bind to any IPv6 address(no IP_FREEBIND needed in this case).

Guess you did so:

ip add add local 2001::41d0:2:ad64::/64 dev lo
ip route add local 2001::41d0:2:ad64::/64 dev eth0
sysctl  net.ipv6.ip_nonlocal_bind = 1

ndppd.conf will look like:

route-ttl 30000

proxy eth0 {

   router no

   timeout 500
   ttl 30000
   rule 2001::41d0:2:ad64::/64{
       static
   }
}

run ndppd and now you can bind to any address(of added block) and use it as it added itself.

3
  • when trying this ndppd responds with "(error) Unable to create socket." Anyone have any clue why?
    – robert
    Jun 22, 2020 at 22:55
  • what if application listens on [::]? i tried ndppd but it's not working...
    – Lamp
    Jun 18, 2021 at 17:48
  • regardless of that i can't ping any random ipv6 either. But I see the echo request in tcpdump
    – Lamp
    Jun 18, 2021 at 18:06
0

You need to add the subnet to your loop back interface and then add a route between lo and eth0 and also enable non-local binding for ipv6. Just modify your networking configuration (/etc/networking/interfaces) as is in the following and restart your networking daemon:

auto eth0
iface eth0 inet static
        address my.ip.v4
        netmask 255.255.255.0
        network my.network.address.ip
        broadcast my.broadcast.address.ip
        gateway my.gateway.ip

iface eth0 inet6 static
        address 2001:41d0:2:ad64::fe
        netmask 64
        gateway 2001:41d0:2:adff:ff:ff:ff:ff
        up ip addr add 2001:41d0:2:ad64::/64 dev lo
        up ip route add local 2001:41d0:2:ad64::/64 dev eth0
        up sysctl net.ipv6.ip_nonlocal_bind=1
        down ip -6 addr del 2001:41d0:2:ad64::/64 dev lo
        down ip route del local 2001:41d0:2:ad64::/64 dev eth0
        down sysctl net.ipv6.ip_nonlocal_bind=0

I use this approach for setting up ipv6 tunnels on my Ubuntu machines and it works fine. The whole IP range is ping-able from remote machines.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .