My home network on IPV6

by davy hollevoet


0. Introduction

0.1. Overview

0. Introduction
  0.1. Overview
  0.2. What
  0.3. Why
  0.4. Version overview
1. Getting started
  1.1. Requirements
  1.2. Optional
  1.3. Superfluous
2. From the beginning
  2.1. What we've got
  2.2. But we need more
    2.2.1 What can we get?
    2.2.2 What does it mean?
3. Multiple segments
  3.1. Dive into setup.sh
  3.2. Coffee break
4. Clients
  4.1. Address
  4.2. Route
5. Why it doesn't work

0.2. What

Since a while I'm using the Freenet6 tunneling service so I can connect to IPv6 IRC servers and show my buddies how 3l33t I am. Freenet6 is so kind to give us a /64 (or a /48) prefix, which means we have a (huge) range of IPs we can assign to our internal network, so no more NAT and stuff, but transparent and clearily visible hosts.

0.3. Why

Freenet6 provides some scripts to config your system to broadcast routing advertisement using radvd (rtadvd(8) on *BSD), but...
So what I did, was configurating my network manually, which gave me nice segments and clean, independant IPs. And that's I'll try to help you with.

0.4. Version overview

1. Getting started

1.1. Requirements

You will need:

1.2. Optional

This might be handy:

1.3. Superfluous

This you can throw away, because it won't be handy:

2. From the beginning

2.1. What we've got

We start with a working tunnel: We can ping www.kame.net and they can DoS us for doing so. Everything OK.
We have an IP on our tunnel device, eg.
dead:beef:f00d:39::2/128
That's one IP we have got to work with...

2.2. But we need more

First we must notice Freenet6 that we want more, because we want a nice range we can assign to our toasters and teddybears.

2.2.1 What can we get?

Now if we follow the Freenet6 directions to set up our internal network, we must add this to our tspc.conf:
host_type=router
if_prefix=YOUR_NETWORK_INTERFACE
Since we don't need a /48, we are not going to add it to our config. But if you absolutely need it, go ahead, just keep in mind that all prefixlens are going to be different for you.
Now the router option is set, and the script will perform some additional things, like configurating the internal NIC you specified, and that's what we need. So restart your tunnel and let's have a look at what we have now.

Type
 ifconfig *yourinterndev* 
(my case eth7) and examine the output. It could be something like this:
eth7      Link encap:Ethernet  HWaddr 00:25:38:52:6B:A6  
          inet addr:192.168.0.1  Bcast:192.168.0.255  Mask:255.255.255.0
          inet6 addr: feed:deaf:babe:1::1/64 Scope:Global
          inet6 addr: fe80::225:38ff:fe52:6ba6/10 Scope:Link
...
The only thing we need here is the line where is says "inet6 addr...", but NOT the one with the address starting with "fe80::". But this one:
          inet6 addr: feed:deaf:babe:1::1/64 Scope:Global 
It teaches us that we received a /64 prefix from Freenet6 and that prefix is "feed:deaf:babe:1". If you requested a /48, you prefix will be "feed:deaf:babe" and it wil say "/48".

2.2.2 But what does it mean?

It means that your internal device (eth7 here), now has received an IPv6 address (feed:deaf:babe:1::1) and is directly connectable from the the rest of the world. You can check that by asking someone to ping the address, or doing it yourself on a box you rooted. If it doesn't work, there is something wrong with your configuration.

And what about the "/64" (or "/48") you ask? It's a netmask like we have on v4. Every packet with destination address "feed:deaf:babe:1:X:X:X:X" (or "feed:deaf:babe:X:X:X:X:X" with a /48) will be forwarded to eth7. Now you can connect a _huge_ amount of clients to that single NIC and give them all a unique IP. Nice isn't it? But what about my second network segment you ask?

If you have only one segment, skip the next paragraph.
If you have two or more, proceed to the next section.

3. Multible segments

3.1. Dive into setup.sh

Freenet6 is so kind to give us a nice script, so why wouldn't we use it? It's not perfect for us, but it's a good base to start from. We just have to alter setup.sh a bit.
If we take a look at the default tunnel script, we see this at the end:
# Router configuration if required
if [ X"${TSP_HOST_TYPE}" = X"ROUTER" ]; then
   Display 1 "Router configuration"
   Display 1 "Kernel setup"
   #Better way on linux to avoid loop with the remaining /48?
   $route -A inet6 add $TSP_PREFIX::/$TSP_PREFIXLEN dev $TSP_HOME_INTERFACE 2>/dev/null
   Exec $route -A inet6 add 2000::/3 dev $TSP_TUNNEL_INTERFACE # default route for forwarding
   Exec $sysctl -w net.ipv6.conf.all.forwarding=1 >/dev/null   # ipv6_forwarding enabled
   Display 1 "Adding prefix to $TSP_HOME_INTERFACE"
   OLDADDR=`$ifconfig $TSP_HOME_INTERFACE | grep "inet6.* $PREF" | sed -e "s/^.*inet6 addr: //" -e "s/ Scope.*\$//"`
   if [ ! -z $OLDADDR ]; then
      Display 1 "Removing old IPv6 address $OLDADDR"
      Exec $ifconfig $TSP_HOME_INTERFACE inet6 del $OLDADDR
   fi
   Exec $ifconfig $TSP_HOME_INTERFACE add $TSP_PREFIX:1::1/64
   # Router advertisement configuration
#   Display 1 "Create new $rtadvdconfigfile"
#   echo "##### rtadvd.conf made by TSP ####" > "$rtadvdconfigfile"
#   echo "interface $TSP_HOME_INTERFACE" >> "$rtadvdconfigfile"
#   echo "{" >> "$rtadvdconfigfile"
#   echo " AdvSendAdvert on;" >> "$rtadvdconfigfile"
#   echo " prefix $TSP_PREFIX:0001::/64" >> "$rtadvdconfigfile"
#   echo " {" >> "$rtadvdconfigfile"
#   echo " AdvOnLink on;" >> "$rtadvdconfigfile"
#   echo " AdvAutonomous on;" >> "$rtadvdconfigfile"
#   echo " };" >> "$rtadvdconfigfile"
#   echo "};" >> "$rtadvdconfigfile"
#   echo "" >> "$rtadvdconfigfile"
#   /etc/init.d/radvd stop
#   if [ -f $rtadvdconfigfile ]; then
#      KillProcess $rtadvdconfigfilename
#      Exec $rtadvd -u radvd -C $rtadvdconfigfile
#      Display 1 "Starting radvd: $rtadvd -u radvd -C $rtadvdconfigfile"
#   else
#      echo "Error : file $rtadvdconfigfile not found"
#      exit 1
#   fi
fi

Display 1 "--- End of configuration script. ---"

exit 0
The first thing we notice, it that the radvd part is commented out, so we don't have to worry about that anymore. The second thing we see, is that the part which is mentioned on this page, is only executed when you have set that you are a router in the configuration file. So this is where we'll have to alter things a bit.
There are two lines concerning the configuration of our internal NICs, and that's
   $route -A inet6 add $TSP_PREFIX::/$TSP_PREFIXLEN dev $TSP_HOME_INTERFACE 2>/dev/null
to setting our route table and
   Exec $ifconfig $TSP_HOME_INTERFACE add $TSP_PREFIX:1::1/64
to assign an address to our device.

I think we don't even need that first line to set our route table, so put a '#' at the beginning to the line to disable it. (in case you know why we DO need this line, please let me know.)

That leaves us with that single line which, for now, assigns our precious range entirely to one greedy device. Let's play divide and conquer and split up our range.
Thanks to the concept of (sub)netmasking we can split our /64 range up into, let's say, a few /80 parts. (If you have a /48, you could divide it into /64 parts.) Now if we assign a /80 to each of our segments, we have a huge amount of clients we can spread over two or more NICs.

In my example, I could give "feed:deaf:babe:1:1::/80" to my eth7 (feed:deaf:babe:1 being my prefix), "feed:deaf:babe:1:2::/80" to sl2, "feed:deaf:babe:1:7::/80" to dummy4, and so on. Doing that, the IP of eth7 becomes "feed:deaf:babe:1:1:0:0:0", and the clients connected to that NIC will have an address like "feed:deaf:babe:1:1:X:X:Y", with Y!=0 because that address is taken.

So what do we change in our setup.sh? First of all, put a '#' in front of the this line
   #Exec $ifconfig $TSP_HOME_INTERFACE add $TSP_PREFIX:1::1/64
to disable it. Just above that line, we see some instructions to remove our old addresses from the devices. Since adding (on Linux, not BSD) the same address to a device which already carries it, simply duplicates the address on the device, we'll have to repeat the instructions for every device. So copy/paste a bit and insert the device names where needed.
If you did well, when the script hits the line we commented out a while ago, all our devices should have no IPv6 address part of our prefix (range). Now we can start adding! Insert this for every device:
   Exec $ifconfig *devicename* add $TSP_PREFIX:1:X::/80
with X a number you choose. When dividing a /48, you should put this:
   Exec $ifconfig *devicename* add $TSP_PREFIX:X::/64
with X a number you choose for that segment. For my example, the last part my config becomes (I left out the radvd part)
# Router configuration if required
if [ X"${TSP_HOST_TYPE}" = X"ROUTER" ]; then
   Display 1 "Router configuration"
   Display 1 "Kernel setup"
   #Better way on linux to avoid loop with the remaining /48?
   #do we need this? $route -A inet6 add $TSP_PREFIX::/$TSP_PREFIXLEN dev $TSP_HOME_INTERFACE 2>/dev/null
   Exec $route -A inet6 add 2000::/3 dev $TSP_TUNNEL_INTERFACE # default route for forwarding
   Exec $sysctl -w net.ipv6.conf.all.forwarding=1 >/dev/null   # ipv6_forwarding enabled
   Display 1 "Adding prefix to $TSP_HOME_INTERFACE"
   #removing old addy from eth7
   OLDADDR=`$ifconfig eth7 | grep "inet6.* $PREF" | sed -e "s/^.*inet6 addr: //" -e "s/ Scope.*\$//"`
   if [ ! -z $OLDADDR ]; then
      Display 1 "Removing old IPv6 address $OLDADDR"
      Exec $ifconfig eth7 inet6 del $OLDADDR
   fi
   #removing old addy from sl2
   OLDADDR=`$ifconfig sl2 | grep "inet6.* $PREF" | sed -e "s/^.*inet6 addr: //" -e "s/ Scope.*\$//"`
   if [ ! -z $OLDADDR ]; then
      Display 1 "Removing old IPv6 address $OLDADDR"
      Exec $ifconfig sl2 inet6 del $OLDADDR
   fi
   #removing old addy from dummy4
   OLDADDR=`$ifconfig dummy4 | grep "inet6.* $PREF" | sed -e "s/^.*inet6 addr: //" -e "s/ Scope.*\$//"`
   if [ ! -z $OLDADDR ]; then
      Display 1 "Removing old IPv6 address $OLDADDR"
      Exec $ifconfig dummy4 inet6 del $OLDADDR
   fi
   Exec $ifconfig eth7 add $TSP_PREFIX:1:1::/64
   Exec $ifconfig sl2 add $TSP_PREFIX:1:2::/64
   Exec $ifconfig dummy4 add $TSP_PREFIX:1:7::/64
   # Router advertisement configuration 
...
fi

Display 1 "--- End of configuration script. ---"

exit 0
Now reset that tunnel and find out where you made that typo!

3.2. Coffee break

Remember that carré confitureke?

4. Clients

4.1. Address

Now we can start distributing IPs among our cybersoldier! The only thing you should keep in mind is that an address you assign to a computer must have the same prefix and prefixlen as the NIC in your router has. To make it clear, here it is, applied on my example:

A node connected to my eth7 can have this as address:
feed:deaf:babe:1:1:*0-ffff*:*0-ffff*:*1-ffff*
and should have prefixlen /80.
For dummy4 (you never know):
feed:deaf:babe:1:7:*0-ffff*:*0-ffff*:*1-ffff*
also prefixlen /80.
Here's how we do that on a box connected to eth7:
root@netbsdbox# ifconfig *mydev* inet6 feed:deaf:babe:1:1:1:2:3 prefixlen 80
or
root@openbsdbox# ifconfig *mydev* inet6 alias feed:deaf:babe:1:3:3:7 prefixlen 80
(if you don't want to keep getting that error) or
root@linuxbox# ifconfig *mydev* add feed:deaf:babe:1:1:6:6:6/80
Now your ready to kick some ass with your cyberarmy! Or aren't you? Because you still can't ping www.kame.net!

4.2. Route

The only thing we have to do, is tell our OS what he should do with its packets. Just like we had to set a default gateway in the days of our NAT, we now have to set a default v6 gateway. And that is going to be the NIC in our router we are connected to. This is how we do that:
root@bsdbox# route add -inet6 default feed:deaf:babe:1:2::
or
root@linuxbox# route -A inet6 add 2000::/3 gw feed:deaf:babe:1:2:: dev eth0
for a node connected to my sl2.

5. Why it doesn't work

This is a short one, I don't know. You made a mistake, or I did. But buy me lunch (or a carré confitureke) and I'll try to help you. Don't expect an answer to dumb questions.

You can find me at irc.krey.net on #lugwv. My e-mail is davyhollevoet at hotmail dot com.

Also, if you should have found unpardonnable errors in my parlé, please let me know so I can cover them up and pretend it never happened.