Skip to content

Instantly share code, notes, and snippets.

Created January 25, 2012 18:56
What would you like to do?
Getting started with Meshnet

Getting started with Meshnet

This document is for people who want to help but have no technical knowledge. It assumes you won't be getting involved in squabbles over which relay technology to use, etc.

Step 1: Set up CJDNS

One of the few things widely agreed upon at the time of this writing is the use of CJDNS. Currently Windows is not supported, but if you have Linux or can run Linux in a virtual machine, you can follow the step-by-step instructions lower on that page to install and start up an instance of CJDNS on your system. If you're using Ubuntu 11.10 (latest version), you can follow these simplified instructions.

One thing you should know is cjdns currently isn't a wireless meshnet. A physical meshnet consisting of nodes geographically close to each other is a long way off. Instead, cjdns offers a "mixnet"-like system. cjdns is routable over the current Internet, so this means right now its like a giant VPN (virtual private network). In the future, with enough nodes that are actually physically close to each other, wireless links can be established and data transmitted that way instead of tunneled over the Internet. So worrying about antennae and line of sight isn't really on the table yet, unless you're planning on setting up your own physical link(s) with local friends. Furthermore, your current router will work just fine most likely.

~ jvnk, of /r/darknetplan

Step 2: Find local buddies to network with

Inevitably, different local nets will use different hardware and techniques to create links, and many are directional as well, which makes grouping together with the meshnetty people in your local area vitally important. I recommend finding hot darknet singles in your location at's Mesh Planning Forum, and if your city doesn't have a thread, make one. Eventually, people will join it.

Step 3: Listen to smart people

Like I said in Step 2, the physical layer tech you need to set up is going to depend on what the other people in your area are doing. You don't want to set up with an optical link when everyone uses directional wifi, or vice versa. Some people in your group are just gonna stand out as technically experienced leaders, know what they're doing, and will be able to help coordinate the rest of you in terms of what to buy, how to put it together, where to aim it, etc.

Step 4: Save up for long-distance links

While this project is really young, there won't be much of a demand for inter-mesh links, which connect one local mesh to another with high bandwidth. These can be expensive and aren't really worth it for small local meshes. But those meshes grow, and eventually you will want to link up with far-away meshes, and then you'll need money for link towers. If you start saving up now, and the other people in your mesh do the same, the individual financial burden will be almost nil when the time comes.

from gevent import monkey; monkey.patch_all()
from bottle import run, route, response, request
import bottle
import urllib2
cow = """ ____________________________________
< Thanks for using the CJDNS proxy\! >
\ ^__^
\ (oo)\_______
(__)\ )\/\\
||----w |
|| ||
rootoutput = cow + "\n\n Usage: http://localhost:8080/[some ip or domain name]/forum"
def home():
response.content_type = 'text/plain'
return [rootoutput]
def proxy(site):
site = "http:/" + request.fullpath
if request.query_string:
site += "?" + request.query_string
source = urllib2.urlopen(site)
return source
except urllib2.URLError as e:
bottle.abort(404, "Could not find that website: " +str(e.reason))
run(host='', port=38080, server='gevent')

Setting up CJDNS on a freshly-installed Ubuntu 11.10 machine

Ubuntu is known for its user friendliness and support, among other things. Here, I'll take you step by step installing CJDNS on a fresh, vanilla install of the latest version. If you're using a virtual machine, this is basically just a continuation of those steps.

Step 1: Log in

Log into your account, which was created during the setup process. If you're following from the VM instructions, this is based on the information you put in in Step 3.4.

Step 2: Update all the packages

Because of the fast-paced world we live in, the ISO you downloaded is out of date. No maybe about it. It's out of date, and I'd prefer that we update our existing packages before installing new ones. Somewhere in the bar on the left-hand side, where all the icons are, there will be one for your package updater. Hover your mouse over the icons until you find the one that says something like "314 packages out of date", and click on it. When the update manager pops up, click "Install Packages". It will ask you for your password, which is the same as you used to log in in Step 1. After that it will take a long time and then need to restart. Be sure to restart before going to Step 3.

Step 3: Start Terminal

From here on out, a lot of stuff we do, will be by terminal. That's not to say that parts couldn't be done graphically, it would just be awkward. Plus, if terminals are scary to you, it's time to break your fears. I'll tell you each command so you can copy and paste it exactly, there's absolutely no need to worry.

To open a terminal, click the icon at the top left, the "Dash Home". This brings up a thing you can search from. Go ahead and just start typing "terminal". It shouldn't take too many keystrokes to filter it down to the three default provided terminals: Terminal, UXTerm, and XTerm. We're going with the one that has a fancy icon, Terminal. Click on that.

If you're in a VM or on a slow machine (or in my case, in a VM that's running on a slow machine), it may take awhile to load. You're ready to go when you see something like "philip@ubuntu:~$". Except it'll have your name, not mine, and possibly a custom hostname instead of "ubuntu". Anyways.

Step 4: Install git

Type or copy/paste this exactly into your terminal: sudo apt-get install git , then press enter to run the command. This will prompt you for your password, which is the same password as Step 1. This tells the system that you want to install git. It'll spit out a bunch of package information, and then ask if you want to continue. Type "y" on your keyboard and then press enter. The installation should go pretty much automatically from there.

Pro tip: on the terminal, CTRL-SHIFT-C copies, and CTRL-SHIFT-V pastes. CTRL-C and CTRL-V do completely different things, which is why the copy/paste commands are funny. If these are habit to you... my condolences. I have been there, my friend. You do eventually get used to it, but you never stop occasionally using the wrong one.

Step 5: Install cmake

Basically the same as Step 4. The command this time is sudo apt-get install cmake. As long as you didn't take too long a break in between Step 4 and Step 5, you'll still be authenticated and it won't even ask your password!

Step 6: Download CJDNS with git.

We're just going to pull the CJDNS code repository down into a subdirectory of the home folder. If you don't understand that, don't worry, there's absolutely no reason you have to. However, there is another terminal command for you to input:

git clone git://

Don't forget to hit enter to run the command! It should go pretty fast since CJDNS is a young project, with not a lot of repo history. If you get errors, check the URL for typos, which are easy to make if you're manually typing it out.

Step 7: Get libevent2

Yes, Ubuntu comes with libevent2. Unfortunately, it's just a teeny bit too old for CJDNS to use. So we have to rip out the installed version and install the proper version. In case there's any confusion... only enter the parts in special formatting, okay? The numbering is just for show. That's probably obvious, but ya never know what people will do.

  1. sudo apt-get remove libevent-2.0.5
  2. wget
  3. tar -xzf libevent-2.0.16-stable.tar.gz
  4. cd libevent-2.0.16-stable
  5. ./configure && make && sudo make install && cd ..

That last bit will do three commands in a chain, and that may take awhile to do, especially on a VM. However, if my experience was any indication, you shouldn't get any error messages. Your sudo authentication might expire and ask you your password again, but other than that, this can run unsupervised while you do other, more worthwhile things with your life. Or you could just watch it while you wait, compiler outputs are pretty so I'm not judging.

Step 8: Actually compile and install CJDNS

Now we compile and install CJDNS. This is gonna just be another list of commands, but I'd be lying if I didn't say this was the exciting part.

  1. cd cjdns
  2. mkdir build && cd build
  3. export Log_LEVEL=DEBUG
  4. cmake .. && make

Once again, I've squeezed the big time-murdering commands into one line with the last one, so that you can start it and go do something else while you wait. Compilation can take a pretty long time, depending on your system. So now would be another good chance to make some coffee, catch up on Breaking Bad, drunkenly phone your ex-girlfriend... actually no, don't do that last one. Really.

Step 9: Test run!

Test that your stuff built properly by running the command ./cjdroute . If it spits up usage information, that's a terrific thing. If bash can't find a file by that name, stuff in the compilation went bad, and you'll have to try to figure out what from the error messages of the compilation process. But in theory this should just work.

Assuming that things are working up to this point, the usage output of ./cjdroute is a series of steps necessary to run the program properly. But we'll take it step by step in more detail now.

Step 10: Configuring cjdroute

Now, we're following the steps outlined by cjdroute. This part can get a bit hairy, as it requires a bit more thoughtpower on the part of the user instead of blind obedience, but it's not at all impossible.

  1. ./cjdroute --genconf > cjdroute.conf
  2. sudo useradd cjdns
  3. sudo /sbin/ip tuntap add mode tun user cjdns
  4. /sbin/ip tuntap list | grep `id -u cjdns` | sed -E 's/^([^:]*):.*/\1/'

The output of the last command is important. Write it down, labeled as "tun device".

Now, here's the hairy part. In order to link up with the meshnet, you have to set up in your configuration which node you want to link up with. There's no automatic peer discovery, although wouldn't that ever be nice! In order to find peers, you'll want to go and ask on IRC, or more conveniently, the same channel as a webchat. Supposedly there's eventually going to be a registry, but until then, you have to talk to actual people. Sorry. Ask for a public key, password, and host. They'll give you the stuff.

Now that you have a key, password, and host, it's time to put them in your config. For the purposes of this tutorial, I will use the real information I got in IRC, but it will probably not work forever, and you can't count on it doing so. IRC user jerco gave me his node information: the key is "3cwqg8zrlcfhchv0mz9pjtclh01pqrg2rd6d3yzk3u02lnt9v490.k", the password is "null", and the host is "".

  1. nano *.conf

This opens up the editing program called nano, where you'll adjust the configuration file to use the information you've collected in the previous steps. Scroll down to the lines with "interfaces" and "UDPInterface". There will be a section called "connectTo", and that's where we're going to lay our fertile eggs with our ovipositor of knowledge.

Every node we want to connect to is listed in the format of "<host>":{"password":"<password>", "publicKey":"<key>", "authType":1, "trust":9001}, where you fill in the brackets with the appropriate information. Those of you in the audience who are familiar with JSON should be well at home with the syntax, those who aren't... well, that's okay too. Here's my version of this section of the conf:

        // Nodes to connect to.
            // Add connection credentials here to join the network
            // Ask somebody who is already connected.


I made mine look nice for formatting, but all-one-line works just as well. Note also that the order of the properties doesn't matter.

Now, scroll down to the "router" section, with the "interface" and "tunDevice" things. By default, tunDevice is set to "tun0". Now, look at that post-it or whatever where you wrote down the tun device earlier. It'll probably be tun0 too. But if they don't match up, you need to change the config to match.

Now save and quit by hitting CTRL-O (that's O the letter, not zero), Enter, and then CTRL-X. Congratulations, thou art configured!

Step 11: Run that sucker

There's a little last-second config we need to do, but it's just one command and we don't need no stinkin' editors.

./cjdroute --getcmds < cjdroute.conf | sudo sh

Then, finally, to start your CJDNS node:

sudo -u cjdns ./cjdroute < cjdroute.conf

There you go! Your terminal is now taken over by the cjdroute daemon, which maintains your IPv6 tunnel. Find some live meshnet addresses on the IRC channel and ping6 them (ping6 fcee:a1f3:68df:ccd1:450b:3fe7:30fe:7134, for example). You may need to open a new terminal tab to do this and other testing (File > Open Tab, or CTRL-SHIFT-T). As long as you don't reboot, you can keep running this node indefinitely!

Caveats: we haven't set it up to start back up automatically at boot time yet, and if your Linux box is a VM, the host operating system (Windows or OS X) won't have access to the tunnel.

Step 12: Tunnels are Forever

Solving the problem of getting mesh access on the host OS is gonna be pretty dang difficult, so let's focus on the easy stuff first. Let's make Linux start up cjdns every time it reboots. This will require a bit more file editing, but who doesn't love that? The following code assumes you're still in the build directory.

  1. echo "cd `pwd`" >> startup
  2. echo "/sbin/ip tuntap add mode tun user cjdns" >> startup
  3. echo "./cjdroute --getcmds < cjdroute.conf | sh" >> startup
  4. echo "sudo -u cjdns ./cjdroute < cjdroute.conf &" >> startup
  5. chmod +x startup
  6. sudo su
  7. echo "@reboot `pwd`/startup"

This last line, you will need to copy. Highlight it, and use the right-click menu or CTRL-SHIFT-C (Not CTRL-C! Those habits will bug the crap out of you when trying to use the terminal) to copy the text.

  1. crontab -e

If it asks you which editor, just hit enter to use nano. By now it should be at least a tiny bit familiar. Scroll down to the bottom and hit enter a few times as necessary to give yourself some space after the comments. Then, paste what you copied earlier, using the right-click menu or CTRL-SHIFT-V. Save and quit (CTRL-O as in Oprah, Enter, CTRL-X).

  1. exit

It's bad to stick around as root longer than you need to.

Now, let's test this out by restarting. Click the Gear icon in the top-right of the screen, and select "Shut Down". When the dialog pops up, click "Restart". When it comes back on, we want to do a little test that it worked, so here's two. Remember, you'll have to start Terminal again, through the Dash Home icon at the top left.

  1. pgrep cjd

If that comes up with a number, you have an instance of the cjdroute daemon running! But does it work?

  1. ifconfig -a

Sections for eth0 and wlan0 are likely to come up, lo is pretty much guaranteed to be there. But if tun0 is there? That's how you know it worked! Also, your IPv6 address is in there, under the heading inet6 addr in the tun0 section. Congratulations, you win at life.

Step 13: Proxy for your Host OS

If you're running Linux outright this step is not relevant to your interests. However, a lot of you are probably running Ubuntu in a VMware Player instance according to the other instructions in this document. Yay for you! I'll show you how to set up a proxy server running in your Linux guest so that you can access Hyperboria and other cjdns networks from the comfort of your host (Windows).

  1. cd ~/cjdns/build
  2. sudo apt-get install python-gevent python-bottle
  3. wget
  4. echo "python &" >> startup
  5. python

This proxy server is extremely simplistic and should probably replaced with a better one, but with a few bugfixes it'll do okay for now. To update it, download the latest version of again by doing Steps 13.1 and 13.3 again.

When you're done with that stuff, you want to adjust your VMware settings so that your host OS can connect to your guest. Open the Virtual Machine settings (if the machine is running, then this will be in the "Virtual Machine" menu in the toolbar"). On the left is a list of hardware devices, find and click "Network Adapter". Now the network settings are on the right hand side, change the Network Connection to the "Bridged" option.

Find your Linux machine's IP address by using the command sudo ifconfig eth0 | grep -o 'inet addr:[0-9.]* and write it down (for example, Now, switch back to Windows and go to but replace it with the IP of your Linux box (keep the :38080 though, that's the port of the proxy). You should see a cow. Now try, it should pull up a barebones version of Google. Real moment of truth: stick an IPv6 address in there that's meshnet exclusive, and see if it pulls up a meshnet website. I suspect it will ;)

Setting up a virtual Linux environment on Windows

So, you're on Windows and want to run CJDNS. Unfortunately the Windows port is sorta nonexistent. If you're willing to take a bit of a dive into virtualization, you can still do it, though. VMware Player is a no-cost and fairly user-friendly way to set up a virtual machine.

Step 1: Download and Install VMware Player

Other virtualizers work too, but for these instructions we're going to use VMware. You can download it from this page, but be ready to have to do a free registration first.

You can do the install simultaneously with Step 2 if you want to save some time, but don't restart when it asks unless your ISO download is already done, or downloading through BitTorrent (where you don't lose your spot if you stop). Those are big downloads and you don't want to break them halfway through.

Step 2: Download a Linux ISO

I recommend Debian or Ubuntu. If you already have a torrent application installed, I recommend using it, since it will go faster, put less stress on the main servers, and check download integrity automatically.

Step 3: Create a virtual machine in VMware Player

  1. Start up VMware Player and click "Create a New Virtual Machine".
  2. Select "Installer disc image file (iso):" (Second option, default if your machine doesn't have a CD drive), and put the path to your downloaded Linux ISO file in the box. The most simple way to do that is with the Browse button, of course.
  3. Click "Next" if you haven't already out of habit.
  4. Enter your information in these four textboxes. Player will automatically create a user account for you on the virtual machine using your input here. When you're done, click Next.
  5. Now, you're prompted for the computer name and where to store the virtual hard drive. The first one is not the hostname, it's the name that shows up in your list of virtual machines, underneath "Home". It's pretty arbitrary, but I'd go with "CJDNS Box". Click next when you're happy with your settings.
  6. The hard disk settings are probably going to be fine as the defaults, but you may want to adjust them if you're short on HDD space in Windows. Note that this is a maximum size, and the hard drive files will probably never actually get that big unless you're torrenting movies on your Linux machine or something. Next.
  7. Unless you're particular about something specific, you can go ahead and click Finish to start up your Linux VM for the first time. You probably won't have much to do until the install finishes if Easy Install is going.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment