Fuck You

Once uppon a time

I used to be called a geek. A nerd. A no-life. Whatever. It used to be associated with people who didn’t want to socialize the way high school and society asked them to do.

It used to be people who were refusing what we told them what a boy or a girl should be, should act. It used to be people who were extremely interested by scientific topics, weird mathematics, role playing games, video games, computer science.

It used to be nice people who were chatting online, exchanging data, helping each other – or anyone who gets in and asked for help.

I wasn’t really proud of it, but at least it was something that was usefull for me at some point, I knew what I was. I wasn’t only an outcast.

Things change

But now, people grew old. Those geeks became adult, got in charge of things, and being a geek became something cool. It was rapidly identified to a man with tech gadget (like iPhones, and other useless shiny stuff) who are adept of a specific sub-culture (implying mainly commercial things).

And new people came in. And are still called geek because they spend time online, because they play video games, etc. Those people developped a false feeling of persecution. Prefering staying in their so-called community, they started to chose who was good enough to be a geek.

They are bullying, assaulting, stalking, chasing online and offline people who are saying them they’re doing someting wrong.

Basically, they act like 4 years old to whom someone asked to stop playing games and go eat with the family. Except 4 years old do not send SWAT team to rivals, do not harass women who are part of the industry – industry whoch provide the games they plays to – to the point they have to leave their house or their jobs, they do not hunt celebrities online for years to find nude cpictures of them and asks ransom for it before publishing them, they do not insult those victim once the picture shave been published while masturbating themselves on those pictures, once again to have them leave what they think is their.

They think the internet is their own things. They are destroying the community that once was inclusive (ok, and weird, and not that easy to understand) by turning it into a … I don’t know … mutually masturbating circle of elitists jerk?

Fuck You!

So fuck you. I refuse to be assimilated to you, a geek. You stripped that of me, you forced me to reject what used to be part of me, part of my culture. You can choke on your masculinist ego.

As long as you prefer hating people I love. As long as you think LGBTIQ people, women, or other are inferiro and can’t be part of your group or can’t access your culture, by using extremely violent means, including harassment, threats and other things like that, I can’t be called like you.

You do not deserve it, but you took that from me.

I may have changed recently, I may have discovered my bisexuality recently. But I’m still fond of RPG, Comic books, video games. But I cannot be called a geek. Not anymore.

So fuck you. You, your hate of what’s not like you, your syndrom of persecution, your conservatism, your etricked mind. I’m not like you. I do not want to be considered like you.

You’re destroying the privacy and the life of other people. I try to give them tools to help have privacy and a safe online life.

I’m not a geek. Not anymore. I can’t be.

About learning and teaching

About learning and teaching

And maybe doing it right

So, I happens to have accidentally bootstrapped a sort of collective to “organize” cryptoparties in Paris (See Here). It’s quite cool because then, you know, I can skip some of them to actually get some rest when I’m on holiday.

Things works more or less smooth, but I have some issues with the way it looks like now. It’s not something easy to say, because it’s probably my fault – at least I do have some responsibilities – but we have some attitude issues among some of the co organizers. I hope it’s nothing that can’t be fixed and we will try to talk about it and see how it evolves.

However, the more I think about it, the more I think we didn’t talked enough about what teaching or do training actually is. And what are some responsibilities you have to endorse and accept when going in front of a group of people and try to have then learn new things, be it chemistry, astrophysics, politics or – in this case – cryptography and privacy.

So, as usual, I’m gonna brain dump here. Not sure if it will make sense or if I’m right, but I think people who wanna do some training might think about what it implies for them and for the people they’ll train.

Desorganised and non-planned

This how we kept cryptoparties organised around here. Everyone of good will is welcome to helps, there’s no skill prerequisite, no resume checking. We all do that on our free time and we try to remain between friends, so it implies a lot of parties (the Telecomix way of doing things) and sometime some harsh talk on a mailing list. But it’s how I like it.

I started those workshops at le Loop, because I wanted to explore technology I did not understand completely at that time, and I prefer doing that in group. The fact that it became a sort of institution is an accident and was never planned.

So, when we throw up a new cryptoparty, we follow the Chaos workshop Howto and we mostly tries to know who will be there and who can train on what topic, then ask the question to the people who have gathered here “What do you wanna explore?

And it was far from perfect, but at least it worked for a while. But now, we have some issues. Those issues are basically because we never talked between us of what knowledge transmission implies.

Cognitive biases ans Argument of authorities

First thing to acknowledge is that, when you put yourself in a trainer position, you have an immense power. You are the expert, the authority, the person who knows, and what you will say will be accepted like The Truth (with capital letters) by your audience.

It means that you need to be extra cautious regarding this power, because – has Peter Parker states it – with great power there is also great responsibility. Not to be exhaustive, or to be flawless, but to be as much flawless as you can toward the knowledge you’re trying to transmit.

Especially in the case where you train activists. Those people basically will use this knowledge in life or death situations and you must do everything you can to avoid them having wrong ideas about what they’re doing.

This is YOUR responsibility. You must know what you know and what you do not, you must accept that you can’t know everything and says when you can’t find an answer to a question (and note it and then look later for the answer). You can’t be good enough or approximative. You must be excellent. If you can’t, you should not do this training.

And yes you have internet to help you. When you don’t know, do not hesitate to fire up a web browser and search for the answer. That way, the people you’re training will learn how they can get better at understanding things. In the crypoparty context that’s also why I like doing them in pair. One can correct the other or helps when difficulties arises, and everyone is getting better at doing it.

That’s also why when I want to explore a new tool, I say upfront that I do not now how it works, but I want to find out how it works. And we dig deeper and deeper, while exploring.

That’s also why I do not teach the math behind cryptography, because I do not understand them fully (and that’s also why I’m not writing crypto code), so it’s hard for me to explain how they works besides rough generalities.

But – and that’s the important part – few people will question you. After all, you’re the person who have the knowledge, and they crave for it, they want it. So, it’s YOUR job to make sure that you won’t teach them errors.

Inclusiveness and accessibility

This part is more directed toward cryptoparties. It’s already a hard place for people to come to a cryptoparty, the name is scary – and that’s why we brand them Café Vie Privée or Privacy Café here – so we need to be the more polite, accessible and inclusive as possible.

It means that you should avoid to patronize people and accept their questions, and weirdness. It also means that when you have to pick up examples, analogies, and things like that, you really should avoid stereotypes because it only creates more stereotypes.

That’s also why you shouldn’t do level oriented groups. Or use terms like n00bs. It’s exclusive, it confront people to their lack of knowledge in a specific area (while they can probably teach you a lot of things from their experience).

The fact that our cryptoparties here are mostly ran by white cis-male is already a big issue. If you use sexist example or assume that people – because they’re female – are the ones who do not know a thing about crypto, you will have an issue.

And it’s not even because you’re an asshole. It’s still because you have the authority, and it have some powerful side-effects. If you tell to people that they’re fantastic and that they’re making progress, that it doesn’t matter if they fail now, etc., then they’ll be amazing. On the other end, if you think of them as n00bs and lamers who sucks at understanding basic tech because you knew it all before, then they’ll stay that way.

So always think of inclusion of everyone. Including the weirdest people you’ll see. Or the one you’re not comfortable with. You don’t have a choice, if you want to share your knowledge, you should share it with the biggest number possible of entities, and then you shouldn’t assume anything about their lives.

Stay humble

And that leads to our last part. Stay humble. You might know a lot of things about the topic you’re about to talk, or you wouldn’t or shouldn’t do it. But all the other people around you – including the co organisers – are also more or less expert on some topics, sometime even the topic you’re going to teach.

And you’ll always be in a de-facto authority, so do not brag about all the things you did. You do not need to justify yourself, if people came they already trust you to be good at what you’re going to train them. You do not need to confront them to their lack of knowledge.

And if you’re doing it with a collective – which is best, parties are better when there’s more than one person partying – you need to work with the collectives. Different people have different views on the same topic, that’s why it’s interesting to work with them. They will also helps you when’ you’re in difficulty, or helps you getting things together when your world will inevitably fall apart.

And it’s important in such a collective to not have to big of an ego, to accept to step back. Yes, you can promote your own projects because they’re cool, they can help people and the like. But you have to accept that, sometimes, someone else want to speak, or try to do things a different way, because we’re all learning how to transmit knowledge, and sometimes we need to experiment.

So yeah, you should listen at your co-organisers. But you must also listen at your trainees. They have questions and problematics you can’t anticipate. And since you’re not doing a lecture, you need to interact, to accept their view, to try to get in their shoes, because there’s a reason for that question you judge stupid.

Also, you need to transmit all the keys you may have to knowledge. It means that you, for instance, when you’re demonstrating a new crypto-tool you like, you should explain what each available options are and what are the differences, but also why you recommend using this specific set of options. You have a reason for doing so, so explain it.

And be patient. I mean, I’m doing help desk for a living (or well, part of my job is doing help desk) I can assure you that most of the people who will voluntarily come to one training are willing to learn. But they need to understand things, and sometimes you will need to answer the same questions many times. It means you need to rephrase until the trainee understand. And yes it’s exhausting. But it’s nothing like help desk, so be patient.


So yes, if you want to train people, you have responsibility toward them. You must think about that, you’re basically messing with their lives. It’s easy to scare them, and have them run away, but that’s not your job. Your job is to give them enough keys and support for them to walk then run then do a back-flip.

And it needs some prerequisite. Be humble. Know where your knowledge stop. Be inclusive. If you’re not, and if it happens when I’m around, I will probably rush into you and slaps you around with a big trout.

Training is a serious matter. It can be done in fun ways, but it must be done in a way that will manage trainees to be trained (and, one day, they’ll became trainers too, which is an excellent things and helps you stepping back


Welcome to searx

You might have noticed some change on my seeks node since it’s not a seeks node anymore, but instead it’s a searx node.

Searx is a project started by asciimoo after Taziden gave a talk at Camp zer0 about going forward with seeks and opening it up to a wider base of developper.

The idea is that seeks ‑ currently written in hardcore C++ ‑ is a prototype and an exploratory project about search and decentralization of search, and that we can now build almost from scratch a search engine which will implement the concept behind seeks but in a more developper friendly way, for instance in python.

We already had a lot of discussion with people hanging on #seeks@irc.freenode.net about this and, technically, there’s two tool to develop. An easily extensible metasearch engine which will feed a DHT of result shared with different nodes.

And then asciimoo wrote searx, a meta search engine, easily extensible. Now, we "just" have to connect it to a DHT. But I’ll save that for later.

So, how did I installed it? I’ve fought a little bit with uwsgi and nginx, but now it works. Here’s how:


Getting the code, the dependencies and everything else

Create a searx user for it’s a good practice (don’t run things as root) and do some git cloning and virtualise you’re environment. Oh, before I forgot, I’m running a debian stable and I try to keep the distribution clean (so no pip install outside of virtualenv)

cd /usr/local git clone https://github.com/asciimoo/searx.git chown searx:searx -R /usr/local/searx cd /usr/local/searx virtualenv searx-ve . searx-ve/bin/activate/

Now, you have a running virtual environnement in ”/usr/local/searx/searx-ve” and the code in the parent directory. You need to install some dependencies, so launch that command and go get a cup of coffee.

pip install -r requirements.txt

Now, the code is alive. You can test it by running the flask instance:

python searx/webapp.py

And you can proxy requests to ”http://localhost:8888” from your favorite webserver. It works.


Since it’s not daemonized, and you’ve got only one worker, I wanted to have something more maintainable. So I needed something like uwsgi (or gunicorn, or whatever) to run the apps right from nginx.

Since debian splitted uwsgi config in a lot of modules, don’t forget to install python module (I was stuck with that a lot). So, let’s install uwsgi and required dependencies.

apt-get install uwsgi uwsgi-plugin-python

Next step is to create an app. In debian, uwsgi has the same apps-{available,enabled} file structure than on nginx or apache. Here’ my config file for searx:

vim /etc/uwsgi/apps-available/searx.ini  [uwsgi] # Who will run the code uid = searx gid = searx  # Number of workers workers = 4  # The right granted on the created socket chmod-socket = 666  # Plugin to use and interpretor config single-interpreter = true master = true plugin = python  # Application base folder base = /usr/local/searx  # Module to import module = searx.webapp  # Virtualenv and python path virtualenv = /usr/local/searx/searx-ve/ pythonpath = /usr/local/searx/ chdir = /usr/local/searx/searx/  # The variable holding flask application callable = app

Once that’s done, symlink this file in apps-enabled and start uwsgi.

cd /etc/uwsgi/apps-enabled ln -s ../apps-available/searx.ini /etc/init.d/uwsgi start

By default, the socket used by uwsgi will be in ”/run/uwsgi/ap/searx/socket”. This is where nginx will chat with uwsgi.


Hard part is done, if you already have nginx installed, just use yet another vhost.

vim /etc/nginx/sites-available/searx  server {     listen 80;     server_name searx.example.com;     root /usr/local/searx      location / {             include uwsgi_params;             uwsgi_pass unix:/run/uwsgi/app/searx/socket;     } }

Then activate the newly created sites and restart nginx.

ln -s /etc/nginx/sites-{enabled,available}/searx /etc/init.d/nginx restart

And go visit searx.example.com or whatever your FQDN is) on port 80, it would works.

I suggest you to install some SSL? but it’s beyond the scope of this tutorial.

TBS – Distributing Transcoding

The issue at hand

Recently I’ve worked a lot on adding content to the TBS by parsing the intertubes auto magically. Fr instance, I have a tumblr and a twitter parser who allows me to gather data (especially in Egypt for instance). Even if those parsers are stupid, they works.

Another one I wante dto add, is the bambuser one. It’s a streaming services used a lot by people in Middle East to broadcast covergae of protests. The Bambuer team is great, they already provided us an API key for the first versions of the TBS, but they mainly use flv format for videos.

And I want the TBS to be without flash, so it means HTML5 formats, and there’s three of them: OGG (.ogv), WebM (.webm) and MP4 (.mp4). FLV is neither of those one.

I usually used to transcode them as a celery tasks, righ on the TBS, but the bambuser parsers gaves me 223 videos to transcode, and given my current configuration, and the CPU power needed to transcode from flv to ogv – it actually can take more than 4 days per video – I was stuck.

Also, since I don’t have a lot of CPU cores, I had only one celery worker, so the broadcast wasn’t updating itself, which was a shame.

Distribute work

So, the solution is to not transcode those videos myself. And that’s were you can help. I’ve wrote a little webservice, using tastypie RESTFull API.

The principle is simple, you ask for a job, download the flv vids from my server, transcode it in one of the three HTML5 video format, md5sum it, put it somewhere I can retrieve it (a publicly accessible http/https server will be good) and then PUT me an update.

See? Simple.

SO, let’s get into the dirty details.

First, you ask for a job to do by hitting this link: https://broadcast.telecomix.org/tsc/v1/jobs/todo/?format=json

It will answers you with a job to do:

{   "objects": [     {       "id": 399,       "md5sum": "dce2d12c90cfef2c78b6c5bde98b4c2c",       "resource_uri": "/tsc/v1/jobs/399/",       "start_time": "2013-09-18T16:16:32.587953",       "state": "p",       "token": "u5d98hOslRQbMJRVtCl6ocLzX5xeCFbneij75Y8j",       "uri": "https://broadcast.telecomix.org//media//8695.flv"     }   ] }

id: is the id of the job. md5sum: is the checksum of the file you need to transcode _resourceuri: the URI you can use to check the details of the job (appends it behind https://boradcast.telecomix.org) . It’s also where you’re going to need to put stuff into, after you’ve done the job. _starttime: is the time at which the jobs has been created. usuallay, you should have the oldest one to do. state: give you the current state of the job. It’s p in this case, because the job is in Progress (since you’re going to do it) token: it’s the token associated to this job ID, and it’s how I’ll fight spam. If you do’nt have the job ID and the token, then you can’t PUT anything. uri: is the absolute URI of the file I need you to transcode. Just GET this file.

And that’s all. You can now transcode the file. For the sake of giving an example, I’m generally using ffmpeg and I invoke it like that:

ffmpeg -i input_file.flv output_file.ogv

It’s enough, but if you’re a ffmpeg Guru, you can probably find better ways. I try to stay as close as possible from the original format (in size especially), but a 320×240 size shoudl be enough if you really need a size.

I tend to prefer ogv over webm and mp4, for it’s the most free codecs of the three, but do what you think is best I can manage the 3 of them.

Once you’re done, send me a PUT on the resource_uri using only three args.

Technically, add the ‘Content-type: application/json‘ header to your query. And the body needs to be a JSON formatted content, with only those three fields:

{     'md5sum': "The md5 hexdigest hash of your transcoded file",     'token': "The token associated to the job",     'uri': "the URL whee I can get the file you transcoded" }

Every other field, will leed to an error.

Once I got the PULL request, I’m going to GET your file. It would be nice to give me the ‘Content-type‘ header associated to the file. In fact, if it’s not one of ‘video/ogg’, ‘video/webm’, ‘video/mp4’ then, I’ll drop the file and will reinitialise the job for someone else to do it. So, please, set-up your webserver accordingly.

And once it’s done, you can get back to /todo and start another job.

If no more jobs are available, you’ll get a 404. Then wait for some time (days or hours) for new jobs to transcode.

And a wild client appears

I was working with CapsLock at night to bootsrap a client to automagically do all the stuff.

You’ll need ffmpeg − and, it seems you need to have a more recent than the one in Debian − and some basic python tools to run it.

Then just:

git clone https://git.legeox.net/capslock/tbs-client.git

And then run it using python in a classical fashion.

Neat, isn’t it? Now, you have no excuse for not helping to transcode the datalove.

If you have any questions, just ping me.

Thank for your help, your cores and your bandwidth. Datalove uppon you.

— UPDATE [2013/09/21]: One of teh field needed for the PUT (namely hash was wrong) UPDATE2 [2013/09/21]: Add the git repo for the client

Building OpenWRT to have PirateBox working on TL-WR703N v1.7

It started with a workshop

With some friends, we decided to have a workshop around the [Piratebox][], so we ordered a lot of TP-link WR703n and started to flash them.

They are labelled as 1.6 revision, but we discovered it the hard way they’re not (worse, some of them actually are, and we were lucky on the first one we tried). So, basically we created some bricks and people were going home without their PirateBox, which is sad.

The trunk was building fine, but the snapshots on OpenWRT.org were built without USB modules, and they are mandatory for the PirateBox to works. I had a host with the full openwrt toolchains, so I started playing around with it and, finally, built a workable firmware for this hardware revision.

Work in progress

How canI use it

It works almost like on the original tutorial except that the firmware you need to download is this one and, that on the steps Install Piratebox you need to change the command issued on step 2 like this:

cd /tmp opkg update && opkg install http://piratebox.aod-rpg.de/piratebox_0.6.3_all.ipk --force-depends

Note the force-depends added at the end of line. It is mandatroy, because I build the binary ‘losetup’ inside busybox, not as a package, so opkg won’t find it.

You will have some error message written, speaking about missing dependencies, but you can ignore them.

Reboot your routeur, and now, everything should works.

Want to build your own?

So, in caseyou wantto have fun with the openwrt toolchains, I’ve pushed my openwrt env in gitorious

Yubikey required at boot

Update (02/11/2012) I added the ‘ask a passphrase’ functionnality in the hook.


As you might already know, I have a yubikey I use as an authentication token. Without it, I cannot log on my computer as a normal user.

But I wanted to do more than that. Like, blocking the boot if the key is not present, unmounting encrypted drive by removing the key, etc.

In this post, I’ll show you how I’ve tweaked my initrd system to stop booting if I haven’t plugged in the key. I’m using the basic kernel from arch linux, and the mkinitcpio system that is shipped in this distribution.

However, the scripts mught be easy to port to a different one.

Writing hooks

I needed a new hook for that. This hook will be responsible of embedding the necessary binaries and modules, and to run them at boot.

The Arch wiki has a page about writing some custom hooks. It just need two non-executable scripts. The neat thing is that those script will embedd all required dependencies when creating the image.

So, use your editor of choice and create the first file /usr/lib/initcpio/hooks/yubikey and paste this content in it:

\#!/bin/bash  \# Use y2kchalresp to test if the yubikey is present run\_hook() {     local CHAL YCHAL PASS TRIES OK     msg ":: Loading necessary modules for yubikey..."     /sbin/modprobe hid\_generic      sleep 2

First, we need to load the required modules. dmesg tolds me that this is the module hid_generic (quite expectable since the key actually is a usb keyboard). I need to sleep a little bit, to give time to the USB bus to detect the key. In case your system doesn’t detect the key, you might need to increase it.

    TRIES=0     OK="KO"     CHAL="thechallengeresult"     while [ $TRIES -lt 3 ]     do         read -p "Enter your yubikey passphrase: " -s PASS         YCHAL=$(ykchalresp -2 "$PASS")

This is the crypto part of it. CHAL contains the expected result challenge (that is the result of the command runned in YCHAL), the PASS is the challenge submitted to the key and YCHAL is the command sent to the key to have an answer from it.

We also start a loop to grants you the ability to mistype your password. The call to read with the -s flag is used to define a passphrase and to not display what you’re typing.

        if [ "$CHAL" != "$YCHAL" ]         then             err "Challenge Response with yubikey failed"             ((TRIES += 1))         else             msg "Challenge Response with yubikey correct"             OK="OK"             break         fi     if [ "$OK" != "OK ]     then         exit 1     fi }

If everything is ok, CHAL and YCHAL are equals, and you can process to the end of the boot. Else, you increment TRIEs, and you loop. If tries is greater or equal to 3, then you end the loop.

At the end of the loop, if OK doesn’t contain OK, then exit, else continue the normal boot process.

The second needed file require by mkinitcpio, in the /usr/lib/initcpio/install/yubikey script.

#!/bin/bash  build() {     add_module hid_generic     add_binary /usr/bin/ykchalresp     add_runscript }

The build function is called to pack everything in the initrd. We need a module and a binary, so we add them here. And then the add_runscript function tells mkinitcpio that there is a script in hooks/yubikey to be included.

help() { cat <<HELPEOF     This hook tries to lock the computer at boot if no yubikey is inserted HELPEOF }

The help function just display a message when you want to know what this hook is about.

Then, just add the yubikey hook in your HOOKS array, edit /etc/mkinitcpio.conf and add it after the usbinput things.

And rebuild the initrd.

mkinitcpio -p linux

And now, on boot, you will need your yubikey plugged in.

VPN in a pocket

About the so-called Pirate Box

Everything started when I found not less than three pirate boxes running at the PSES 2012 conferences and all of them were unaware of the two other. Worse, you could connect to one piratebox or to the internet, but not both, because pirate box runs off-line.

And this is the main problem of this thing. I mean, if I want to download and share, I use the bittorent system, you shouldn’t be afraid of the legal consequences of the act of sharing things you like.

But still, those wireless router are damn small (they literally fit in a hand), they need not much power to run and they have some interesting routing capabilities (multiple SSID, bridging, meshing, you name it) and I was thinking that, deploying this kind of hardware cold be a way to cover areas with poor connectivity and works collaboratively to route packets. This is pretty much how the internet works.

So, I was thinking about a meshed network of sharing content boxes that could access to the Intertubes and share this access. But accessing the clearternet is not interesting. With some Telecomix folks we think and works a lot around darknet and weird protocols, because they are fun. And right now, we are working with cjdns – which is not about DNS. Also, a box already configured offering to everyone an access through a VPN can remove the pain of configuring it for non tech-savvy users, and so to have more people using darknets and vpn.

And I have a TP-Link WR703N dedicated to this experimentation.


Before everything, we need to flash a firmware onto the small router (there’s only 4MB of disk to store everything, it’s quite tight). I used the sysupgrade for Attitude adjustment image (and found my way through the Chinese menu). Nothing specific here,the device works perfectly fine

Routed AP

Then I wanted that my box connect to a LAN (connected to the clearternet), to set up an Access-Point and to route everything that come from the AP to get through the LAN and then to the darknet (configured to work over the clearternet as a darknet usually do)

Quite easy, since there’s a recipe for it in the openwrt wiki. However, I did changed some things, so let’s review the different files one after the other.


config wifi-device radio0 option type mac80211 option channel 11 option macaddr ec:17:2f:e0:44:52 option hwmode 11ng option htmode HT20 list ht_capab SHORT-GI-20 list ht_capab SHORT-GI-40 list ht_capab RX-STBC1 list ht_capab DSSS_CCK-40

Nothing specific here, the default are good and I don’t need more.

config wifi-iface option device radio0 option network wifi option mode ap option ssid ChaosBox option encryption none

First interface, configured as an open AP in a dedicated network and without a key. I want everyone to be able to use my VPN without having to found a key.

config wifi-iface option device radio0 option network babel option mode adhoc option ssid ChaosBabel option encryption none

And since I can do multiple SSID on the box, I will use this later for meshing the ChaosBoxes together (and using babel, because it works out of the box). It works, but I haven’t tested it, so it will be the subject of a different post.


config interface ‘loopback’ option ifname ‘lo’ option proto ‘static’ option ipaddr ‘’ option netmask ‘’

Loop back interface.

config interface ‘lan’ option ifname ‘eth0’ option type ‘bridge’ option proto ‘dhcp’

I move the default configuration (static) to a dynamic one. I will then benefit of what the LAN I’m connected onto will offer, notably a gateway to the internet. And probably some DNS cache.

config interface ‘wifi’ option proto ‘static’ option ipaddr ‘’ option netmask ‘’

This is my wireless network, the interface corresponding to the wireless device configured in AP mode. I will use the network, mostly because the 192.168 ones are over-common and I do not want to have a problem with that.

config interface ‘tcxnet’ option proto ‘none’ option ifname ‘tun0’

This one is mainly here to define things that I’ll later use in the firewall.


config defaults
option syn_flood 1
option input ACCEPT
option output ACCEPT
option forward REJECT

So, defaults. They are good and protect a little bit your box.

config zone
option name wifi
option network ‘wifi’ option input ACCEPT option output ACCEPT
option forward REJECT

The zone for all the traffic coming from the wifi network.

config zone
option name lan
option network ‘lan’
option input ACCEPT
option output ACCEPT
option forward REJECT
option masq 1
option mtu_fix 1

The zone for all the traffic coming from the lan. Well, nothing will really come from it but you see what I meant. However we want to masquerade (after all, you can probably found things like a mpd or a nfs share on the lan).

config zone
option name tcxnet
option network ‘tcxnet’
option input ACCEPT option output ACCEPT option forward REJECT
option masq 1
option mtu_fix 1

This zone is for everything going through the tcxnet interface (that will be our cjdns). As for the lan, and since we want to use services inside the darknet, we will masquerade.

config forwarding
option src wifi
option dest lan

config forwarding
option src wifi
option dest tcxnet

And now, let’s forward the traffic through both the lan and the tcxnet zone.


[…] config dhcp wifi option interface wifi option start 100 option limit 150 option leasetime 12h

This is the only dhcp pool I have. I want to address the wireless part. 50 address should be enough.

More info

For more info about those configurations, you should read the openwrt wiki

The fun parts


Now, the real fun begin. First, let’s install CJDNS. Quite easy thanks to the build made by fremont:

opkg update && opkg install http://v4.seanode.meshwith.me/openwrt/ar71xx/packages/cjdns_0.4-SNAPSHOT_ar71xx.ipk –force-depen ds

I use the force-depends flag, for nacl and kernel version on attitude adjustment because they will raise some unneeded conflicts.

And then, following the instructions available in the cryptoanarchy wiki, generate a configuration, add peers and start cjdns:

cjdroute –genconf > /etc/cjdroute.conf

cjdroute < /etc/cjdroute.conf > /dev/null &

No logs, sorry, I haven’t the room for that. Plus I do not likes it.


I’ve tried a lot of things, and it appears that the way to have it working is to simply use a SOCKS proxy and to connect through it.

I’ve installed srelay because it appears to works simply. And to fit in the 4 MB space I have.

opkg install srelay

We need to configure it to get it working, edit the /etc/srelay.conf file delete everything and have it looking like that:

allow local subnet to access socks proxy any

Then just start srelay using the automagick init.d script:

/etc/init.d/srelay enable /etc/init.d/srelay start

It will start on the 1080 port on your openWRT box.


Now, start a computer, activate wifi, connect to the ‘ChaosBox’ ESSID and ask for an IP via dhcp.

Start a browser and configures it to use a SOCKS 5 proxy and use the parameters used to start srelay. The proxy address is and the port is 1080.

You have to disable the option to forward the DNS queries through the proxy for srelay can’t understand them yet. Also, you have to check that your DNS resolver has been set-up by dhcp and is ‘’. If it’s not,edit your /etc/resolv.conf file and add this line on top:


Now, you have two tests to run. First the plainternet, test to load the http://telecomix.org page. If it works, go on the second test.

Try to use the darknet. If you’re connected to the Hyperboria darknet, you can test going on Nodeinfo.hype: http://[fc5d:baa5:61fc:6ffd:9554:67f0:e290:7535]/.

If it works, congratulations 🙂


Why don’t you NAT?

Well, I tried. CJDNS address are in ipv6. So, I’ve choosed an ipv6 prefix, anounced it to be served in the wifi interface and tried to route through cjdns. However, the source IP mismatched.

And ipv6 NAT are out of the table for openWRT. So, I was unable to do it that way.

Why didn’t use Tor?

Simple, openwrt + Tor (in fact the libcrypto) are overweighted and go beyong 4 MB. So, I’ll had to use an external storage connected on the USB port. But then, the power consumption will go high. Also, I need an external devices connected, that can be separated from the router.

You spoke about mesh before?

And you didn’t see it. Yep, I need to do that. But tunneling through cjdns was such a pain. But babel works quite easily.

EDITED 08/17/2012 I changed a little bit about the srelay configuration, did not work as expected at first.

EDITED 09/13/2012 I updated the client configuration part since srelay can’t forward DNS queries. Also, we did some tests at Le Loop yesterday evening and meshing is quite advanced now, I’ll do a post to that at a later time.

EDITED 26/11/2012 The URL for the ipk has changed

How did I streamed the last JHack conference


So, yesterday, the regular Jhack crew set-up an event with Richard Stallman to talk and exchange around the issues involving Free Software and Human rights.

And, as we want to build and keep history (also, it was a week day, so some people can’t come physically to the nice place we’ve had for the occasion), we wanted to stream.

When it come to streaming something, it usually sum-ups to having a cam, connected to a laptop of a sort and which then send it over a more or less closed source application. Everything ending on the web in a flash player (website like Bambuser or Ustream are doing a great job to broadcast video from revolutions, but I cannot see the video there for I have no flash, please people, think HTML5 now, also this is why [TBS][] uses HTML5 and not a flash player).

And I do not wanted that. There might be a way to do it, without using the horrible command line tool gstreamer (I cried tears of blood last time I wanted to use it).

Also, I was surrounded by apple products (Journalists, changes your habits! I cannot works like that anymore), none of them being able to be used as I wanted to (meaning, just do something without Apple software). The last thing I add was a laptop with a small cam and an internal mic.

Tools of the trade

Since we were looking for a streaming solution in #opSyria, a part of the preliminary research had been made, so here are the tools that was needed to stream:

  • A laptop running GNU/Linux (Ubuntu, not my favorite favor, but let’s deal with it) and with included microphone and webcam.
  • VLC, because when you need to do some video/sound it is a good tool
  • Network connexion. Ethernet over RJ45 with a steady bandwidth is generally a good idea.
  • A server to stream to, with a good availability. My choice is Giss.tv, free streaming tool. It is based on icecast and can stream .ogg (free container)

 Assembly everything

Once you’ve find all of the above, the worst oart is done. If you have a powerful laptop, you can even record the stream locally, wasn’t needed here since we’ve got a camera crew working on it.

  1. Plug your computer into the network, start it and launch VLC.
  2. Visit Giss.tv and create a channel for your need. They will send you all the needed informtion for you to stream.
  3. In VLC go in File > Stream, choose your physical device (nowadays, most probably a video4linux2, the cam is ususally in /dev/video* and the sound is your ALSA card (probably :hw0.0). Click on stream
  4. Check the display locally check box, extremely useful to monitor and check everything is ok. Stream to a shoutcast server, feel in the details Giss.tv has send to you.
  5. You want to transcode to a set of codecs of choice (free one, my choice is Theora / Vorbis)
  6. Click on Go. The streaming will start. Go on your interface page on Giss.tv and say ohai to the camera, you’re on the TV \o/


I had some pain to manage the network over there (not mine, they’re not used to weird people doing strange things with network) and with the CPU power needed to transcode. My good old netbook wasn’t powerful enough.

The quality was awful, due to the fact I have nothing best than internal devices. For the next time I need even a cheap jack microphone and a webcam that I could use to zoom on the subject and have better than 2.3 Mpixels.

Also, I need to plug the power cord into a power plug that is actually connected to the electrical network. I have to set this in a bit of a rush and that totally slipped of my mind.

I also need to find a way to do it from the command line. But it works. It’s dead simple and it’s free. So now, you have no excuse.

If you want a shiny design around these, just put some CSS and HTML around, and it would be enough. But get rid of Flash.

Yubico, PAM, and Challenge/response Authentication

Introducing the yubikey

The yubikey is a small device that act as a token generator for authentication system. Yubico build them and, as they’re seen as a Universal Keyboard, they can be easily interfaced with any kind of system.

From generating OATH token, to One Time Password systems, going by Radius and OpenVPN server authentication, they can be used for a lot of funny things and, among other thing, it’s free software (not free hardware, alas). The token is at $25 and you can order them by huge quantities.

Simply put, it’s a good token for it’s price and, given my threat model (my computer being stolen) it is enough.

So, some disclaimers.

  • I have no interest in the yubico company or any of their software.
  • You can end permanently locked out of your stuff if you lose your key and if it’s the only way you have to login. But, it’s what I’m looking to achieve.
  • I am not a security expert. I haven’t notice any obvious security flaw, that does not mean there is not. However, the yubikey seems to do the job.
  • I use Archlinux, and the AUR. You’ll have to adapt things for your distro, but you’re a grown up now, it should not be a problem.
  • The challenge-response mode described here, is only available on Yubikey 2.2 and later.

What are we going to do

The first thing I wanted, was to lock my computer when the key is away. The simple thing is to launch a xlock on running X servers. It’s far from perfect, but if I can do this, I can do more.

The second thing I wanted was to be able to forbid login to people who lack either the key or my user password, a classic Two-factor authentication. But I wanted to do that offline, and without using the static key configuration of the yubikey.

But first, I need some packages, so let’s do some yaourt.

[okhin@tara.sunnydale]$ yaourt -Sy libyubikey pam_yubico ykclient ykpers

The first and second packages, are needed for pam, the last ones are needed for using your key. It seems that some tweaking may be necessary in the PKGBUILD file of pam_yubico. I have change the –with-pam-dir options of the configure invocation to be /usr/lib/security and I added _CFLAGS=-DHAVE_LIBYKPERS1 to the make invocations.

 Configuring udev

So, first thing to do for xlocking everything when removing the YubiKey is to add some udev rules. On my Arch system, they’re located into /usr/lib/udev/rules.d and it’s recommended to use a low priority one, so let’s edit the 99-yubi.rules file in this dir. I just need to rules:

ATTRS{idVendor}=="1050",ATTRS{idProduct}=="0010",GROUP=yubi,MODE="0660" SUBSYSTEM=="usb",ACTION=="remove",ENV{ID_VENDOR}=="Yubico",RUN+="/usr/local/sbin/xlock-yubi"

The first one is a classic Udev rule, and you’ll need to create a group named yubi and to add users who’ll configure the key in this group.

The second one is a bit tricky. The yubikey is detected by the system as 3 devices (on usb, one input and one hidraw), and, if you do not add the SUBSYSTEM part, you’ll have to go through 3 xlock screens before unlocking your device. It’s not that good.

The other weird part is that, when configuring or dealing with your yubikey, the tools scan for the key, and so remove the input/hidraw part of it in udev before adding them back. The subsystem that get disconnected only when you remove the key of your computer, is the usb SUBSYSTEM.

And, for the script, well, do whatever you want in it. It’s not the topic of this post, maybe later.

So, now, when you’re going to get your key out of a USB slot, it will call the script. At least, once you’ve reloaded the udev daemon:

[root@tara.sunnydale] # udevadm control --reload

There’s also a udevadm monitor command that is quite handy when debugging udev rules.

Set up the key

Ok, now, when you unplug any Yubico branded devices, you’re going to lock your screen. We’re going to move into the fun stuff now.

There’s a command for customizing your yubikey. You have to know that this key can handle two different configuration. I’ll use the second one, keeping the first one for other purposes yet to find.

So, let’s burn a new configuration for activating challenge-response:

[okhin@tara.sunnydale] $ ykpersonalize -2 -ochal-resp -ochal-hmac

It will ask you for a AES passphrase, I used one generated by the yubikey (by pushing the button), but feel free to use what you want. You won’t have to use it again, since the AES key will be stored on the yubikey and that no one will be able to read it anymore.

Next options, is to generate the pam configuration for the challenge, and we need a ~/.yubico dir for that. Protect the files inside this directory, for they contain the challenge.

[okhin@tara.sunnydale] $ mkdir ~/.yubico

And then, run this utility to configure the challenges that will be used by pam.

[okhin@tara.sunnydale] $ ykpamcfg -2 -A add_hmac_chalresp

You’ll have a file named challenge-KEYID in your ~/.yubico directory. It contains the file you need.

If, like me, you have an encrypted /home that is mounted using pam_mount at login, you cannot use this configuration. So, creates a world read-writable directory where you’ll store your challenges.

[root@tara.sunnydale] # mkdir /etc/yubico/challenges -p

And then, move your file in it, keeping a 0600 mask and the ownership correctly set-up (that is, only the user that will use this key should be able to read it). Replace the challenge part of the name by the username:

[okhin@tara.sunnydale] $ mv {~/.yubico/challenge,/etc/yubico/challenges/okhin}_KEYID

And now, we just have to play with pam.

I wanted to force users on my graphical login manager to have a key. And to enter their Unix passphrase (I use it to mount my encrypted /home) at prompt. Both conditions being required to get a login.

So, in my /etc/pam.d/slim file I’ve added this line just above the pam_unix module:

[...] auth    required    pam_yubico.so mode=challenge-response chalresp_path=/etc/yubico/challenges auth    required    pam_unix.so nullok [...]

If you want to consider that having the yubikey is the only necessary thing, then change the required by sufficient. You have to know that no password will be asked for. As soon as the yubikey is plugged into your computer, knowing your login name is enough to get access to a session, and it is a security risk.

Relaunch your session-manager and window-manager, plug your key inside your computer, and login. It will asks for your username and password, as usual. However, if you haven’t got your key plugged into your system, then you’ll be unable to login.

Congratulations, you’re done. Try to keep a way to still log into your system, in case you lose your key.

You can also have different key for one user (just add new challenges file). And you can probably have one key for different user (didn’t test that).

What’s next?

I need to change my xlock script to log me out of the box, when the key is unplugged. I need to figure a way to use the yubikey challenge-response mode with system like luks or GPG.

Also, I’d like to use to remotely connect on VPN or SSH, but I need to look into those HowTos. If some of you wanna give it a shot, you know how to reach me.

How to install a Pirate Bay proxy?

How to set-up a The Pirate Bay proxy?

Assuming you have a webserver somewhere in a (cyber|cypher)space and you want to set-up an access to the infamous website thepiratebay.(com|se|org). You need different things:

  • A webserver, in this case apache2 but can probably be nginx or any other webserver you want to use
  • An up-to-date libssl along with the Perl::SSLeay library
  • A dedicated domain name (in this case yar.okhin.fr, can be anything else as long as you own it)
  • The patched tpbCgiProxy provided by the pirate bay.
  • A little bit of time.

 First some cgi

Since it’s based on CGI Proxy you need to have the NPH support of the cgi scripts in your webserver. It’s included into Apache since the 1.3, but just check that first.

Also, check that .cgi files are interpreted as cgi-scripts not as text. Check in your mime.conf file (in debian it’s in /etc/apache2/mods-enabled/mime.conf) that the following line is uncommented:

AddHandler cgi-script .cgi

Put the nph-tpb.cgi file into your cgi-bin script directory (we will define it later in apache), just be sure that the user who runs the webserver can also exec the file. A good place to put your cgi-scripts is usually /usr/lib/cgi-bin/

It seems the tpb admins have forget one URL in their allowed ones. So, just do it now, using the editor of your choice (at line 528), you need to add thepiratebay.se to the ALLOWED_SERVERS

@ALLOWED_SERVERS= ('thepiratebay\.se$', 'thepiratebay\.org$', 'bayimg\.com$', 'suprbay\.com$', 'bayfiles\.com$') ;

Next, let’s move to apache

So, we will need a nifty file for this virtual host. I’ll paste and comment mine here

<VirtualHost *:80>         ServerAdmin webmaster@localhost         ServerName yar.okhin.fr          RewriteEngine on         RewriteCond %{HTTPS} off         RewriteRule (.*) https://yar.okhin.fr%{REQUEST_URI} </VirtualHost>

The above is just to enforce SSL connexion. In case the user is not using HTTPS everywhere. If you do not want to have virtual host on all your address, you can specify one instead of the ‘*’

<VirtualHost *:443>         ServerAdmin webmaster@localhost         ServerName yar.okhin.fr

The name of the server is important in case of a multiple virtual host. You can add server alias too, if you’d like to access the proxy with different names.

        ErrorLog ${APACHE_LOG_DIR}/error.log

I do not like logs. But error logs are, in my mind, necessary to keep the things working. You’re warned, if you crash my server, I’ll know it.

        DocumentRoot /usr/lib/cgi-bin/nph-tpb.cgi/

This is the root of your proxy. This should be the complete and absolute path to the cgi-scripts you’ve installed above.

        <Directory /usr/lib/cgi-bin/>                 AllowOverride None                 Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch                 Order allow,deny                 Allow from all         </Directory>

Add some default for permissions. As we are in the cgi-bin directory, we do not want anyone to list the content of it.

        # Possible values include: debug, info, notice, warn, error, crit,         # alert, emerg.         LogLevel crit          CustomLog /dev/null combined

You do not want to log anything related to your visitors, or it will defeat the purposes of anonymity.

        SSLEngine on         SSLCertificateFIle /etc/ssl/certs/tpb.pem         SSLCertificateKeyFIle /etc/ssl/private/tpb.key

And this is for SSL. Just be sure that the key is only readable (mode 0600) by the user who runs the server.


Why would I do that?

Well, for once, TPB is now censored in the UK. I personally think it should not happens, and if you like your freedom of speech and have access to a server, you should do it also.

Second, it’s fun to do this kind of stuff. You’ll then be able to use the cgi proxy for different purposes if needed. And, well, you really need another reason?

Legal issues

Well, as for all non-logging anonymous proxies, this will raise a lot of issue. Even if your server do not actually host any of the magnets links of the pirate bay, you could be in trouble.

Do what you want keeping this in a place of your head. Do not do it on a company owned server, or not without the former approval of your bosses.

Besides that… Have fun, proxy the planet, mirror the world, copy the tubes.