Mikrotik OpenVPN Server

The purpose of this post is to describe, step by step, my attempt to set up an OpenVPN server on a Mikrotik RouterBOARD 750 and create a working tunnel from an outside machine (AWS EC2 Windows Server 2008 R2) to this OpenVPN server so that an SMB server on the local network can be accessed from said outside machine. The following diagram gives an overview of the setup:

I am going to decribe how to:

  • generate certificates to be used with OpenVPN
  • set up OpenVPN server on Mikrotik router
  • set up a tunnel with OpenVPN client on Windows
I am not going to describe the following:
  • setting up and connecting to an EC2 Windows instance
  • setting up a Samba Server
A few things worth mentioning about Mikrotik OpenVPN server implementation (that will likely bite if not known in advance):
  • only supports TCP mode, UDP is not supported
  • username/password pair is also required even though certificates are being used for authentication

Generate certificates to be used with OpenVPN

root@inhouse-debian:~# apt-get install openvpn
root@inhouse-debian:~# mkdir ovpn-cert
root@inhouse-debian:~# cd ovpn-cert/
root@inhouse-debian:~/ovpn-cert# cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0/* .
root@inhouse-debian:~/ovpn-cert# emacs vars
In the file vars I set the following values:
export KEY_COUNTRY="FI"
export KEY_PROVINCE="Etela-Suomi"
export KEY_CITY="Kotka"
export KEY_ORG="Async.fi"
export KEY_EMAIL="joni.kahara@async.fi"
export KEY_CN="kahara.dyndns.org"
export KEY_NAME="kahara.dyndns.org"
export KEY_OU="kahara.dyndns.org"
If I have understood correctly, of these only CN (Common Name) is obligatory. I may be wrong. Anyway, continuing:
root@inhouse-debian:~/ovpn-cert# source vars
root@inhouse-debian:~/ovpn-cert# ./clean-all
root@inhouse-debian:~/ovpn-cert# ./build-ca
root@inhouse-debian:~/ovpn-cert# ./build-key-server kahara.dyndns.org
root@inhouse-debian:~/ovpn-cert# openssl rsa -in keys/kahara.dyndns.org.key -out keys/kahara.dyndns.org.pem
root@inhouse-debian:~/ovpn-cert# ./build-key ec2 
root@inhouse-debian:~/ovpn-cert# apt-get install ncftp
root@inhouse-debian:~/ovpn-cert# ncftpput -u admin 192.168.1.1 / keys/kahara.dyndns.org.crt keys/kahara.dyndns.org.pem keys/ca.crt

Set up OpenVPN server on Mikrotik router

All the stuff here can also be made through Mikrotik's admin interface; textual form without screen shots is used just to keep thing terse.
root@inhouse-debian:~/ovpn-cert# ssh admin@192.168.1.1
[admin@MikroTik] > /certificate
[admin@MikroTik] /certificate> import file=kahara.dyndns.org.crt
[admin@MikroTik] /certificate> import file=kahara.dyndns.org.pem
[admin@MikroTik] /certificate> import file=ca.crt
[admin@MikroTik] /certificate> decrypt
[admin@MikroTik] /certificate> ..
[admin@MikroTik] > /interface bridge add name=ovpn-bridge
[admin@MikroTik] > /interface bridge port add interface=ether2-master-local bridge=ovpn-bridge
[admin@MikroTik] > /ip address add address=192.168.1.64/24 interface=ovpn-bridge 
[admin@MikroTik] > /ip pool add name=ovpn-pool ranges=192.168.1.65-192.168.1.99
[admin@MikroTik] > /ppp profile add bridge=ovpn-bridge name=ovpn-profile remote-address=ovpn-pool
[admin@MikroTik] > /ppp secret add service=ovpn local-address=192.168.1.64 name=user1 password=pass1 profile=ovpn-profile
[admin@MikroTik] > /interface ovpn-server server set auth=sha1,md5 certificate=cert1 cipher=blowfish128,aes128,aes192,aes256 default-profile=ovpn-profile enabled=yes keepalive-timeout=disabled max-mtu=1500 mode=ethernet netmask=24 port=1194 require-client-certificate=yes
[admin@MikroTik] > /ip firewall filter add action=accept chain=input disabled=no protocol=tcp dst-port=1194
[admin@MikroTik] > /ip firewall filter move 5 destination=1
That last step moves the new rule to the front of the chain; numbers ("5", "1") will likely be something else on your configuration. Firewall rule listing can be printed with the following command:
[admin@MikroTik] > /ip firewall filter print

Setup up a tunnel with OpenVPN client on Windows

After installing OpenVPN, create a config file for it. Here it's called "kahara.dyndns.org.ovpn":
client
dev tap
proto tcp
remote kahara.dyndns.org 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
cert ec2.crt
key ec2.key
verb 3
pull
auth-user-pass userpass.txt
Also, create a file called "userpass.txt" and put the following to it:
user1
pass1
Of course in an IRL situation one should use a real password. Make sure you copied the .crt and .key files over to the Windows machine, after which you can run OpenVPN client with:
PS C:\Users\Administrator\Desktop> openvpn.exe .\kahara.dyndns.org.ovpn
And here we have an EC2 client connected to a local SMB resource over the tunnel:

Tagged with:

Categorised as:


Windows Server 2008 R2 on Amazon EC2

Plan to use an in-house box to run a XenServer to host XP instances (I need multiple Windows desktops for "testing" purposes if anyone asks) had to be scrapped because the box was simply too loud and I couldn't get the wireless bridge to work – not that the latter would have helped anyway because like I said the box really is loud and relocating it anywhere inside our flat just wouldn't lower the noise level enough for it to not disturb sleep. Which brings us here: launching a Windows Server 2008 R2 instance on Amazon EC2 and setting up Remote Desktop Services to enable multiple simultaneous client sessions. Below we can see Alice, Bob, Charlie and Dave each happily running their own Remote Desktop session at the same time:   The whole thing runs "tolerably" smoothly even on the severely memory-limited Micro Instace: At $0.035 per hour this can be considered cheap. And, the server can be shut down when it's not needed in which case the only charge will be for the admittedly humonguos (35 gigabytes) Windows root partition. And of course those clients would need Client Access Licenses which adds a one time cost of roughly $100 per client. Now, to directly compare this kind of setup with having an actual physical server would indicate poor judgement as both have their strong and weak points but costs can be compared. So here we have an estimate of what the total cost of running a server like this for a three-year period would be, sans CALs:
On-Demand EC2 Reserved EC2 (1-year Contract) Reserved EC2 (3-year Contract)
One-time costs $0.00 $54.00 $82.00
Compute $922.32 $421.56 $421.56
Storage (35 GB) $138.60 $138.60 $138.60
I/O (10 IOPS) $103.00 $103.00 $103.00
Transfer In (1 GB/m) $3.60 $3.60 $3.60
Transfer Out (10 GB/m) $48.60 $48.60 $48.60
Total Cost (Euros) 849.69 € 613.00 € 557.11 €
Per Month (Euros) 23.60 € 17.03 € 15.48 €
Source: http://calculator.s3.amazonaws.com/calc5.html Then again, that 600 € would get you two HP Proliant MicroServers. Yet, then again, that price does not include Windows licenses and they would need a physical location, electricity, an Internet connection – an so on.

Tagged with:

Categorised as:


Building a WDS Bridge with Consumer Grade WLAN APs

Small AP is small – and has a built-in antenna, too. I got two of these (for 19,90€ per piece – not A-link list price…) and set up a bridge so I could relocate my noisy Xen box from living room to kitchen to keep the box running 24/7 and sleep. (Turns out that in the end even this didn't help because the box remained loud enough to disturb sleep no matter what settings were selected in BIOS thermal management.) Initially it looked like the bridge worked just fine, except my testing revealed that the transmission speed was nowhere near the advertised "IEEE 802.11n (draft 2.0) / 150Mb":
XenCenter.iso              100%   44MB   1.5MB/s   00:29
After trying different cryptos from WPA2 to plain text and fiddling with various other settings I came to the conclusion that the slow speed was a feature of the device. Anyway, this was not really any kind of concern as I was more interested in latency, which was low enough (a few milliseconds). Put all this together and my opinion is that it's good enough for an access point that is about the size of a deck of cards and costs twenty euros. What did turn out to be a problem is that at times the AP's would somehow manage get a broadcast storm going on, which of course took the wired network down with it very quickly. I wasn't really able to get to the root of this but from what I observed I can tell that the broadcast storm would happen even when one AP was connected to the primary wired segment and the AP at the other end was just "floating" there, with nothing connected to its' Ethernet ports. Also, while after enabling STP in the devices I could, using tcpdump, observe the STP config packets doing their thing and reconfiguring after for example dropping and then reconnecting either end of the bridge, this (STP) did nothing to prevent the broadcast storm from happening. I should also note for the record that I was using the "WDS", not "AP+WDS" mode. Verdict: the devices just aren't suitable for this application, i.e. they are buggy and do not fully work as advertised but given their relatively compact size and ability to function as clients on a WLAN, I'll keep these.

Tagged with:

Categorised as:


H264 HTTP Test Stream Generator

As I haven't got an H264-capable camera to use as a test source (yet) I'm using the following GStreamer pipeline, adapted from videotestsrc documentation to generate an endless, mildly hypnotic low bitrate zone plate pattern wrapped in an MPEG transport stream. A clock is also shown so that when the stream is transcoded and/or segmented, it's easy to see how bad the lag is. Audio is not included but for example audiotestsrc could be plugged in the pipeline if necessary (although I won't be using audio in my app). VLC is used in the end of the command line to serve the stream over HTTP.
gst-launch-0.10 -v mpegtsmux name="mux" ! fdsink fd=1 »
videotestsrc pattern=zone-plate kx2=20 ky2=20 kt=1 ! »
video/x-raw-yuv,width=320,height=240 ! »
clockoverlay valign=bottom halign=left font-desc="Sans 23" ! »
ffmpegcolorspace ! videorate ! video/x-raw-yuv,framerate=15/1 ! »
x264enc bitrate=100000 cabac=false pass=qual quantizer=27 »
subme=4 threads=0 bframes=0 dct8x8=false ! mux. | »
vlc -I "dummy" file/ts:///dev/stdin »
:sout='#std{access=http{mime=video/mp4},mux=ts,dst=192.168.1.35:8000}'

Update: Here's how to save the encoded video to an MPEG-4 file:

gst-launch-0.10 -v videotestsrc num-buffers=900000 pattern=zone-plate kx2=20 ky2=20 kt=1 ! video/x-raw-yuv,width=1920,height=1080,framerate=25/1 ! x264enc bitrate=16000 cabac=false pass=qual quantizer=27 subme=4 threads=0 bframes=0 dct8x8=false ! queue ! muxer. ffmux_mp4 name=muxer ! filesink location=zone-plate-900000-frames-1920x1080-25fps.m4v

Tagged with:

Categorised as:


HTTP Live Streaming with VLC

Well, it took "a while" but I finally got HTTP Live Streaming working with VLC. Downloading and compiling the latest from Videolan's Git repo was required ("1.2.0-git Twoflower" here). I might add that even though on the box that I did this I've compiled a lot of different programs (an Ubuntu installation that has gone through multiple dist-upgrades so it's a few years old and has a lot of packages (2344 atm) installed), quite a few external -dev packages relating to audio and video had to be apt-get'ed to make things work. Below is the command to make VLC read a DVD and generate a segmented stream of H264 video and AAC audio to directory /var/www/html-video-stream/x/ on our local web server. In an IRL situation we would perhaps run the transcoder and segmenter instances on separate machines, or if we already had a suitable H264 stream source (like a camera) we could skip the transcoding step altogether.
vlc -v -I "dummy" dvdsimple:///dev/scd0 »
:sout="#transcode{vcodec=h264,vb=100, »
venc=x264{aud,profile=baseline,level=30,keyint=30,ref=1}, »
aenc=ffmpeg{aac-profile=low},acodec=mp4a,ab=32,channels=1,samplerate=8000} »
:std{access=livehttp{seglen=10,delsegs=true,numsegs=5, »
index=/var/www/html-video-stream/x/stream.m3u8, »
index-url=http://192.168.1.33/html-video-stream/x/stream-########.ts}, »
mux=ts{use-key-frames}, »
dst=/var/www/html-video-stream/x/stream-########.ts}"
  QuickTime X (fanboys have had this since Snow Leopard) supports HTTP Live Streaming, so in order to show the above stream on a web page in Safari using the <video> tag, we can do the following:
<video autoplay loop controls>
  <source src="http://192.168.1.33/html-video-stream/x/stream.m3u8" »
   type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'/>
  <!-- additional sources here -->
</video>
  Although I'm not sure if this will work in a situation where we attempt to feed H264 to clients that don't support HTTP Live Streaming, that is, we have an additional <source> element that points to a "regular" H264 HTTP stream. However, adding Ogg/Theora and WebM/VP8 support should not cause problems – I just haven't been able to make VLC output those (properly) yet. HTML5 video tag streaming support in different browsers is also one big question mark.

Tagged with:

Categorised as: