Building Your Own Networks

by Casandro

As developments like data retention and censorship become prevalent, it might be wise to build new networks, networks that belong to the users.

Back in the BBS days, people operated their own networks like FidoNet over the easily available but unfree telephone network.  Today, the Internet is the new unfree network, plagued by companies who want to extort more and more money out of the users.  So, it might be a good idea to build your own moderately-sized networks.  Even if this won't solve any important problems in the world, it will still be fun.

In this article, I would like to compress all the information needed to do so.  This article is a bit Linux-centric, but the ideas should be easy to convert to just about any operating system.

Well what's the obvious thing you need first?  Connections.

Today we have a lot of possibilities, from IP over carrier pigeon to fast fiber optic connections.  The most practical of these are probably WLAN and VPN-tunnels.  The other thing needed is routing.  So we need a routing protocol which is simple to use and available to anybody.

Let's start with the connections.

Obviously the simplest connection is just an Ethernet cable.  Configure the nodes just as usual, and there you go.  For larger distances, it might be wise to use WLAN devices in ad-hoc mode.  This is probably best explained by an example.

Let's assume our wireless device is named wlan0.  You can find out its name and settings with the iwconfig command.

Setting up the device can be a bit tricky.  You will need the following commands:

# iwconfig wlan0 essid "NetworkName" channel 6 mode ad-hoc commit
# ifconfig wlan0 10.111.4.5 netmask 255.255.255.0

The first line sets the wireless device's channel and network.

The second command assigns the IP address 10.111.4.5 and netmask 255.255.255.0 to the device.

The other wireless devices on the network would have to be in the 10.111.4.X range, with X between 1 and 254.

On some cards you will have to first execute an ifconfig wlan0 up command to turn on the device.

Please choose the IP addresses as randomly as possible to avoid collisions.  If you notice that an IP address or range is already taken, use another address.

VPN tunnels are a bit harder to set up.

There are a number of technologies for this, but we'll focus on OpenVPN because it is available for most platforms and easy to set up, at least in shared key mode.

First you need to create a key:

$ openvpn --genkey secret somefile.key
$ cat somefile.key
#
# 2048 bit OpenVPN static key
#
-----BEGIN OpenVPN Static key V1-----
bcec76bdaa903173fa202fde4299c131
728422f026cfa648a8dac9334c1fbc34
cdac51671f13749201e0e1f60d9dd0fb
947ba343644e04dd4d5e7acadd6b58ac
eef57d27a6b712d7dc5112d4715fb1f8
1b09fd91877812e9ee9269ef40fcc915
195ee08a1c8fc2b5646e3f2b9af32383
75350d9c5365951d8d6f4a4474d29064
c6bbf2d07be46891dad9099ab42e4abf
ce5ea58276e36fa4eb9ec65c86c233fe
8c125a41ee2b0247727000666df6dc6e
3248e3712f2cb9810ddab980ba5b2c0a
80caf5e6e12d524db4c6263b109085d0
061ccb8701f7382f0c41cc801e4aad5d
fb4b141dfd3e45c599ff2375289970f0
346d64d868c50209c85422c506fbc9e9
-----END OpenVPN Static key V1-----

This stores the shared key in the file: somefile.key

Obviously, you could use any file name for this.  This key has to be copied to both ends of the tunnel.  OpenVPN then needs a configuration file which tells it what to do.

Here's an annotated example.  First, the SERVER's configuration file:

# Be sure to have this UDP port open to be accessed from the client
port 1117
dev tun
# Internal server Adr. client address
ifconfig 172.24.13.11 172.24.13.12
# Name of your keyfile  
secret somefile.key
# Periodically send some packets to keep the connection alive though routers
keepalive 10 120
# Compress the data.
comp-lzo

And the CLIENT's:

# This is the IP or domain name of your server
remote nameorip.ofyour.server.org 
# The same as on your server
port 1117
dev tun
# Internal client adr. server address
ifconfig 172.24.13.12 172.24.13.11
# Name of your keyfile
secret somefile.key
# Periodically send some packets to keep the connection alive though routers
keepalive 10 120
# Compress the data.
comp-lzo

As you can see, there are two differences between the SERVER's and the CLIENT's configuration files: the CLIENT's file has an additional remote line, and the ifconfig lines have the IP addresses in reverse order.

Again, please choose the internal addresses randomly, to avoid collisions.  Be sure to always use private addresses.

To start OpenVPN, just type: openvpn --config your_config_file.conf

Start OpenVPN first on your SERVER, then on your CLIENT.  Most distributions already have init files to start OpenVPN automatically on boot-up.  These often only support one tunnel.  If that is enough for you, you can try to use that.

Now, you need to set up the routing.

For this we will use OLSR as provided by olsrd.  This is now probably the most popular daemon for wireless seed networks.  I prefer the 0.5 series as it is considerably more stable than the 0.4 one.

To make it work, you might need to change a few settings in the configuration file olsrd.conf:

UseHysteresis no
LinkQualityLevel 2

In the Interface section of the file you need to uncomment the line:

Ip4Broadcast 255.255.255.255

and adapt the Interface line to include all your network interfaces.  In my case that is:

Interface "tun0" "tun1" "tun2" "tun3" "tun4" "tun5" "tun6" "tun7" "tun8" "eth0"

Now you can simply start olsrd by typing olsrd -d 2 on the console.

After a short while, the links' status messages should appear.  Once you seem to be connected to your peers, you can type route -n to get a list of all the routes.

Typically, you should get a line for every node in the network.

What if you have computers which cannot run olsrd, for example because they are routers or printers?

For those computers, you can use the Host Network Announcement (HNA) feature.  This feature tells the other nodes in the network that your node can reach computers that are not nodes.

In the Hna4 section of olsrd.conf, you will find an example of this.  You will also have to tell the devices that they can reach the OLSR-managed network via your node.  One easy way to do this is to set the devices' default gateway to your computer.

So, what could be accomplished with this?

Of course, you could start by connecting your computer to your friends' computers and even to strangers'.

Additionally, you could set up a wireless interface.  With this, you will be able to offer network access to all members of the network, without having to offer Internet access.

If nearby nodes also have wireless devices, they can also form a connection and build a network.  Wireless networks were the original application for olsrd.

In Berlin, there is such a wireless network consisting of several hundred nodes.

In the dormitory I live in, we have some wireless nodes.  Roaming works rather well.  You can walk throughout the building and keep your IP address despite being in a different point of the network topology.

As described, this network does not include internet access.

If you want to provide it, you have several possibilities.  The simplest and most elegant is to set up NAT on your node and use a HNA entry to "0.0.0.0  0.0.0.0" in your olsrd.conf.

Nodes to which your node is the closest Internet gateway will automatically use your connection.  There can be several internet gateways; however, be aware that if network topology changes cause you to change your gateway, then stateful protocols like TCP might break.

Another way is to use proxies.

For example, I run an anonymity proxy on one of my nodes.  This works fairly well if you only want to do web-browsing, as you must manually select your gateway in your web browser.

A good compromise might be to create another VPN tunnel to the Internet.  This would potentially allow you to have unlimited Internet access.

To further obscure the network topology and therefore the position of SERVERs of the network, it might be desirable to install those SERVERs on virtual machines.  You could then just migrate the SERVER from one location to another.

I already operate a small network consisting of three permanent nodes plus some extra nodes fading in and out.  If you want to connect to it, I am willing to give a tunnel to anyone who is willing to give some tunnels to others.

Automation

In order to save you from having to do a lot of monotonous work, I have written a few scripts.

The script search_ip.sh first gets a random address from the private address range.  If we did not check, there would be a rather high chance of collisions.

This is a traditional birthday paradox.  Keep in mind that, in addition to this high chance, there is also probability of not recognizing that an IP address is already taken.

When an apparently free IP address is found, the script write_configuration_files.sh is executed.

This script creates a SERVER and a CLIENT configuration file as well as the shared key file and neatly packs them into two ZIP files, one for the SERVER and one for the CLIENT.  Please edit the settings at the top of this file to suit them to your needs.

getkeys.cgi is a "key dispenser."

It gives out a different key file for every request.  If you have a very fast computer with a fast connection to the internet, you could use the first script to create a few hundred configuration files and use the CGI script to get them to your peers.

Be sure to not leave your key files world readable.  Not only could they be read by just about anybody on your system, but also OpenVPN will refuse to start.

So, let the fun begin.


search_ip.sh:

#!/bin/bash

# Find an unused IP-address
# It'll be stored in $a.$b.$c.$d
a=172
let "b=$RANDOM % 16 + 16"   # from 16 to 32
let "c=$RANDOM % 255"       # from 0 to 255
let "d=($RANDOM % 127) * 2" # from 0 to 254 only odd adresses Server
let "d2=$d + 1"               # last number of client

# If first address free and second address free  write configuration
ping -n -c 3 $a.$b.$c.$d || ping -n -c 3 $a.$b.$c.$d2 || write_configuration_files.sh $a.$b.$c.$d $a.$b.$c.$d2
echo $a.$b.$c.$d
echo $a.$b.$c.$d2

write_configuration_files.sh:

#!/bin/bash

public_server_ip="xxxxxx.xxx.xxx" # public IP of server
lowest_port_number_file="/tmp/lowest_port_number"

config_client="/tmp/keys"
config_server="/tmp/keys_server"
config_temp="/tmp/config_tmp"

mkdir $config_client
mkdir $config_server
mkdir $config_temp

server_ip=$1 # Private IP of server
client_ip=$2 # Private IP of client

ls $lowest_port_number_file || echo 5000 > $lowest_port_number_file

server_port=`cat $lowest_port_number_file`

let "server_port=$server_port+1"
echo $server_port > $lowest_port_number_file

keyfile="$config_temp/secret.key"
keyfilebn=`basename $keyfile`

openvpn --genkey --secret $keyfile

cat > $config_temp/server.conf   <<HEREDOCUMENT
port $server_port
dev tun
ifconfig $server_ip $client_ip
secret $keyfilebn
keepalive 10 120
comp-lzo
HEREDOCUMENT

cat > $config_temp/client.conf   <<HEREDOCUMENT
remote $public_server_ip
port $server_port
dev tun
ifconfig $client_ip $server_ip
secret $keyfilebn
keepalive 10 120
comp-lzo
HEREDOCUMENT

#rm $config_client/client_config$server_port.zip 
zip -j $config_client/client_config$server_port.zip $keyfile $config_temp/client.conf
#rm $config_server/server_config$server_port.zip
zip -j $config_server/server_config$server_port.zip $keyfile $config_temp/server.conf

rm $keyfile $config_temp/server.conf $config_temp/client.conf

getkeys.cgi:

#!/bin/bash

# The directory where the configuration files lie
keydir="/tmp/keys/*.zip"
# The directory where used configuration files go
useddir="/tmp/used_keys"

# Get the one file
x=`ls -d $keydir | head -n 1`

echo "Content-Type: application/zip"
echo 

cat $x && mv $x $useddir/`basename $x`

Code: search_ip.sh

Code: write_configuration_files.sh

Code: getkeys.cgi

Return to $2600 Index