Monthly Archives: November 2015

OpenWrt, easy-rsa, openvpn and stunnel

Certificates are confusing. I have wanted to generate self signed certificates on OpenWrt using easy-rsa, and use them for openvpn and stunnel. Below are the relevant commands and configurations.

easy-rsa
The vpn guide for OpenWrt is quite good. A summary:

# cd /etc/easy-rsa
# vim vars                   -- edit as you like
# source ./vars
# build-ca                   -- generates ca.crt
# build-dh                   -- generates dh2048.pem
# build-key-server myserver  -- generates myserver.[crt+key+csr]
# build-key myclient         -- generates myclient.[crt+key+csr]

For stunnel purposes, you need to copy/rename your .crt file to .pem. The content is the same.

The .csr files are not needed. The clients need the ca.crt plus their .crt (or .pem) and .key files.

openvpn server

option ca '/etc/openvpn/ca.crt'
option cert '/etc/openvpn/myserver.crt'
option key '/etc/openvpn/myserver.key'
option dh '/etc/openvpn/dh2048.pem'

openvpn client

option ca '/etc/openvpn/ca.crt'
option cert '/etc/openvpn/myclient.crt'
option key '/etc/openvpn/myclient.key'

stunnel server

cert = /etc/stunnel/myserver.pem
key = /etc/stunnel/myserver.key
CAfile = /etc/stunnel/ca.crt
verify = 2

stunnel client

cert = /etc/stunnel/myclient.pem
key = /etc/stunnel/mysclient.key
CAfile = /etc/stunnel/ca.crt
verify = 2

It looks very simple now, but without a working configuration it is not so easy to find the error.

Comfast CF-2410P Review

I needed decent directed antennas for my TP Link WDR3600. I decided to try the Comfast CF-2410P, despite its cheap price.

I can not find that it has any advantages to the standard antennas that came with the router. I would rather say it is crap.

Playing with smart.js and V7

I have been playing quite much with Node.js lately, and I have put some effort into trying to build it for typical OpenWRT hardware. It turns out that Node.js/V8 is not, and will never be, suitable for hardware without an FPU and at least 128MB RAM.

My curiousity led me to smart.js which is based on the V7 javascript engine. Among the positive details were posix compability, ECMA script 5.1 support, HTTP support (not very different from Node.js, just much less of it), and supposed to be the fastest non-compiled JavaScript engine.

smart.js
smart.js seems to be the IoT-platform, while v7 is just the JavaScript engine. smart.js had some peculiar properties:

  • The source zip I downloaded from github failed to compiled becuase of a missing .git-directory. Using git clone solved this.
  • The binary always reads and executes smart.js from the same folder. If you give more command line arguments, it executes those after smart.js.
  • I found no way to pass command line arguments.

It comes with a little set of IoT-example files, and I found this a little confusing.

v7
I found out it was possible to use v7 standalone. It is a very nice v7.c file that is simply compiled:

$ gcc -O3 -DV7_EXE -o v7 v7.c -lm

This is very promising – a lot easier than building node.

I found that neither console.log or process.argv exist and found ways to work around this. My plan was to build a little benchmark suite and test different things. I did not get so far: the below program just creates 100 random objects (TestBit) 10 times and stores in arrays.

if ( 'undefined' === typeof process ) {
  process = {
    exit : exit,
    argv : [ 'v7', 'v7bench.c' ]  // faking command line arguments
  };
}

if ( 'undefined' === typeof console ) {
  console = {
    log : print
  }
}

var TestBit = function() {
  this.n  = Math.random();
  this.s  = '' + this.n;
  this.s1 = this.s.substr(2,1);
  this.s2 = this.s.substr(3,2);
  this.s3 = this.s.substr(5,3);
  this.b  = this.s > 0.5;
};

var generateTestBits = function(n) {
  var i;
  var r = new Array(n);
  for ( i=0 ; i<n ; i++ ) {
    r[i] = new TestBit();
  }
  return r;
}

var Timer = function() {
  this.start = Date.now();
  this.last  = this.start;

  this.split = function() {
    var r;
    var n = Date.now();
    r = n - this.last;
    this.last = n;
    return r;
  }
}

var timer = new Timer();

var i = 0;
var tests = [];
var tmp;

console.log('Start');

while(i<10) {
  tests.push(generateTestBits(100));
  i++;
  console.log('' + ( i*100) + ':' + timer.split());
}

This simple program unfortunately proved that performance is much worse than I could expect. Below are timings for generating the 1000 objects, in steps of 100 at a time. Benchmarks on a RPi2 900MHz ARMv7 CPU.

There is a flag (-vo) described as “object arena size” that I decided to play with (values 1, 10, 100 gave very similar results as 1000)

       default    -vo 1000    -vo 5000    -vo 10000
 100      0.2s       0.12s        6.8s          28s                         
 200      0.4s       0.16s        8.6s
 300      1.3s       0.23s       12  s
 400      7.4s       0.24s        2.6s
 500     13  s       0.37s       15  s
 600     35  s       0.93s       32  s
 700     47  s       2.9 s       48  s
 800     79  s       4.6 s       45  s
 900    160  s       5.9 s       36  s
1000    160  s       8.0 s       37  s

Well, generating 100 random objects on a RPi2 using a simple interpreter could take 0.2 seconds (the top left value): quite reasonable I guess. As the number of generated objects grows the performance is completey ruined. With default parameter, a full 1.6 seconds is spent to generate one single “TestBit”. Memory usage of the v7 process is insignificant.

I dont know what the “object arena size” setting does, but it obviously changes something. The 400-value for the vo=5000 series is actually reproducable.

Even for an IoT-platform I find this performance (and the lack of predictability) unacceptable. V7 officially aims to be the fastest interpreted JavaScript engine out there: it must be cabable of handling what is actually small arrays (10×100 elements) of small objects.