Skip to content
Nov 3 14

OpenVPN server on FreeBSD with pf firewall

by Finn Espen Gundersen

FreeBSD 10, with the new and improved packet filter/firewall pf, and OpenVPN are all great products. But I had a not so great time making them play together – especially with a Windows 8 client. As with everything, it is easy when you know how.

Most OpenVPN examples seem to be using the tap interface and ethernet bridging. To keep things simple, I wanted to go with the default ip-routed tun interface. Apart from being default, thus requiring less config fiddling, it fits nicely with pf and requires one less kernel module.

After making it all play together, I also wanted the connecting clients to access the internet through the VPN connection, necessitating some routing. The last step is not necessary if all the resources the VPN clients will need are on the server itself. A similar step will be required if the clients should access other servers close to the VPN entry-point.

The steps outlined here should also work on FreeBSD 9.

Preparing certificates

Installing is as easy as

pkg install openvpn

But before we can go ahead and start it, we need keys and certificates. Decide on somewhere to keep the server’s private keys and other crucial files, I opted for

mkdir /root/sslCA
chmod 700 /root/sslCA

This needs to be put in /etc/ssl/openssl.cnf as

dir            = /root/sslCA    # Where everything is kept

OpenSSL also requires some folders and a serial number

cd /root/sslCA
mkdir certs private newcerts
echo 1024 > serial
touch index.txt

Then, let’s generate the 10 year Certificate Authority which will be used to sign the certificates

openssl req -new -x509 -days 3650 -extensions v3_ca -keyout private/cakey.pem -out cacert.pem -config /etc/ssl/openssl.cnf

OK, that authority can now sign the server certificate. This is a two-step process where we first generate a request for a certificate, then the actual certificate. Note that while you can put almost anything in the fields when asked, you will need at least a common name for each, and the organization must be the same for both certificates.

openssl req -new -nodes -out server.req -keyout private/server.key -config /etc/ssl/openssl.cnf
openssl ca -out server.crt -infiles server.req -config /etc/ssl/openssl.cnf

Answer yes [y] where asked.

If you want to use password-based authentication for the clients, these are all the certificates you need. But if you want certificate based authentication, then each client will also need a certificate. Just create another request and certificate in the same manner, but with “server” replaced by “client”. You will need to copy those files (and the CA cert) to the client later.

The last piece of the plumbing puzzle is the random Diffie-Hellman parameters.

openssl dhparam -out dh1024.pem 1024


Configure OpenVPN

We will base our config on the sample file, so copy it first.

cp /usr/local/share/examples/openvpn/sample-config.files/server.conf /usr/local/etc/openvpn/openvpn.conf

Most settings are defaults. In particular we avoid some work with tap and bridges since we are using a tunneled ip routed interface. But we need to tell OpenVPN where we put everything. Look for the lines in openvpn.conf starting with ca, cert, key and dh.

ca   /root/sslCA/cacert.pem
cert /root/sslCA/server.crt
key  /root/sslCA/private/server.key
dh   /root/sslCA/dh1024.pem

If you want the client to use the VPN as the default gateway, i.e. not only to access server resources, but perhaps also to surf the web, you will need to put these two lines either in the server or client config. You will also need some routing, see below.

push "redirect-gateway def1 bypass.dhcp"
push "dhcp-option DNS"

If you want the clients to be able to see each other, uncomment the line


Now, prepare to run by adding to /etc/rc.conf:


And then, ignition:

/usr/local/etc/rc.d/openvpn start



If all you want is for the clients to access the server, no routing is necessary. If you don’t already have pf (or another firewall) enabled, consider yourself done with the server setup. However, if you have a firewall and/or want the clients to access the internet, or other servers in your LAN, you are in for  some pf magic.

The packet filter pf just recently got SMP support in FreeBSD. It perfectly illustrates how the FreeBSD community values performance, now having a faster port than the native OpenBSD version. If only we could port the “match” functionality as well.

Type ifconfig and identify the name of your network interfaces.

create a file /etc/pf.conf containing

# default openvpn settings for the client network
vpnclients = ""
#put your wan interface here (it will almost certainly be different)
wanint = "vtnet0"
# put your tunnel interface here, it is usually tun0
vpnint = "tun0"
# OpenVPN by default runs on udp port 1194
udpopen = "{1194}"
icmptypes = "{echoreq, unreach}"

set skip on lo
# the essential line
nat on $wanint inet from $vpnclients to any -> $wanint

block in
pass in on $wanint proto udp from any to $wanint port $udpopen 
# the following two lines could be made stricter if you don't trust the clients
pass out quick 
pass in on $vpnint from any to any
pass in inet proto icmp all icmp-type $icmptypes

Note that all incoming TCP from the WAN is blocked with this setup, add a line resembling the “pass in for proto udp” one to open specific TCP ports.

Rule 1 of firewall design is “Never blindly copy-paste rules”. While the above has been designed to not expose copy-pasters to too much danger, it is certainly better to extract the essentials and adapt the pass rules to your own needs. If you want IPv6 you have to.

Since pf is included by default, all we need is some rc.conf settings


And then, enable packet forwarding, enable pf as our firewall, and start it

sysctl net.inet.ip.forwarding=1
pfctl -ef /etc/pf.conf

Nevermind any messages about missing ALTQ, we don’t need QoS (yet).


Configuring Clients

Thanks to using the tun interface and keeping to the defaults, the client configuration can be kept close to the defaults. Just search online for tutorials for your operating system. If your client is Windows 8, read on.

The Windows client includes an OpenVPN GUI program. I could not get that to show any GUI. If you can’t either, don’t despair. We will go old school and edit the settings file instead.

After installing the Windows OpenVPN client, copy the client.ovpn file from c:\Program Files\OpenVPN\sample-config to ..\config. It will need the CA certificate, client key and client certificate from the server to accompany it.

Edit the client.ovpn file slightly (it needs to be done as administrator). Look for the following lines and edit accordingly.

remote # put your server IP or name here
# the certificate files from the server (separate client certificate, not server)
ca   ca.crt
cert client.crt
key client.key
# remember to keep this line commented out
;ns-cert-type server

At the end add

#this line sets the VPN as default gateway
redirect-gateway def1
#these lines stroke Windows 8 the right way
route-method exe
route-delay 5
route-metric 550

To start the connection we need to run (again, as administrator)

c:\program files\openvpn\bin\openvpn.exe --config client.ovpn

The default OpenVPN network is with the server at Try pinging it.


Oct 19 14

Unreal Tournament Server on FreeBSD

by Finn Espen Gundersen
Unreal Tournament 99 GOTY

Unreal Tournament from 1999 (Game of the Year – GOTY – Edition) is now 15 years old and still a great multiplayer game, especially at LAN parties. It is free to download so you can share this gem with anyone. If you play it regularly you will want to host a server.

This guide for FreeBSD closely follows the Linux guide, but as always FreeBSD needs a couple of adjustments.

First of all make a new user with adduser. All default settings, I call mine ut99.

You will also need the files as well as the patch from v436 to v451 (to get functioning web admin).

tar xfz ut-server-436.tar.gz
cd ut-server
tar xfj UTPGPatch451LINUX.tar.tar
tar xfz asu-0.6.tar.gz
chmod +x
cd System
ln -s

For some reason (Linux…) the first line of specifies sh, but the script later tests for bash. We need to install bash if you don’t already have it

pkg install bash

then change the first line to


Now run to set some options. First choose I, answer the prompts, then S for more prompts, then X to exit. Default options are ok; just remember to enter the user you added when prompted for it. Whatever you enter here can be changed later in System/UnrealTournament.ini. creates a script ucc.init which we will use to run the server. But before anything will run we need to

chmod +x ucc.init
chmod +x ucc
cd ..
chown -R ut99 ut-server

If you already have Linux compatibility installed, you are good to go. But if not, you will get ELF binary type “3” not known, which means:

kldload linux
pkg install linux_base-f10
echo 'linux_enable="YES"' >> /etc/rc.conf

At last, start the server with

./ucc.init start

If you want to move the server files later, note that ucc.init contains the absolute path two places. These will need to be updated.

Even though the server starts we are not done yet. Some of the maps in the Maps directory are zero-length files. These must be copied from the original game download. Most commonly these are DM-Morbias][.unr, DM-Curse][.unr and DM-Deck16][.unr.

If you want to make the server available from the internet, the ports to be NATed are 7777-7783 (UDP) as well as the web admin port, most commonly 5580 (TCP). The web admin port can be set in UnrealTournament.ini. Make sure to set the web admin username and password there as well.


Aug 24 14

4x4x4 3D RGB Charlie Cube by Stavanger Makerspace

by Finn Espen Gundersen

Over the last two Sundays, Stavanger Makerspace hosted meetups to build 4x4x4 RBG LED Arduino-controlled “charlie cubes”. A charlie cube, originally designed by Asher Glick and Kevin Baker, uses a minimum of components and can be made very cheap by using just an Arduino nano.

Charlie-cube projects abound on the internet, but the amount of soldering points suspended only by thin wires often leads to misaligned results. Our intrepid member Kjetil Eik, known for impressive 3D prints on his sturdy Felix, thought we could do better. He designed and printed tools and jigs to straighten out what would otherwise have been a crooked crowd. He also designed a PCB to avoid the messy breadboard.

Download the 3D print gcode files for the LED and

Download the the PCB layout for Fritzing and have it delivered by dirtypcbs.



The tools are, from top left and clockwise:

  • Hats for the top LEDs, to be used during soldering to perfectly align the top LEDs in a grid, as well as keep them together during transport.
  • Base platform for the PCB and Arduino. The arduino and all solder points are hidden underneath the PCB. It has just one small hole in the side for the USB cable.
  • PCB designed with the program Fritzing.
  • Jig to hold an RGB LED in the center hole while the leads are bent to match the grooves on the star’s arms.
  • Tool to help remove stuck LEDs from the soldering jig
  • Soldering jig to hold 4 LEDs and two wires while soldering. This is used twice for each “tower” to solder wires pairwise. This kind of jig is essential in a charlie cube project.

Apart from 3D printed tools and the PCB, the parts needed are:

  • 64 RGB LEDs
  • 1 Arduino Nano v3 (+ USB cable)
  • 2 Single row angled SMT male header w/spacing 2.54mm (1/10″)
  • 7m Steel wire




LEDs are an essential part of any hobby electronics project. This project has plenty. Full colour!


The star-shaped jig for bending LEDs improves efficiency and alignment. An interesting observation is that the LED can be inserted in any orientation. The only unbendable rule for lead bending is the order: up, left, right, down. By the 64th LED, you have reached an amazing speed.

Next comes wires.


Ordinary fence wire won’t line anyone’s pockets, but works perfectly. It needs a bit of straightening out before it can be trusted with the task we have in mind, though. The process is simple: pull firmly, without yanking, and watch it stretch. Best done in pairs.


Cut to measure. Length is not too important, just keep it over 10cm.


Three people made about 700 of these. We got the hang of it after about 100.

In addition to LED bending and wire stretching, we had USB cables, Arduinos and 3D-printed jigs for 10 people.



4 LEDs and two wires goes into the soldering jig. The topmost LED can be put in at any orientation, but each LED downwards must then be rotated 90 degrees clockwise. Bring out the old soldering iron and link the connections before the heat makes the wire dig itself into the plastic jig (according to our jig maker, this never happens to him).


Then, use the removal tool, turn the LEDs 180 degrees and repeat for the other leads.



It helps to have the PCB rigged with the Arduino and 4 temporary connectors, to confirm the non-presence of dud soldering joints.


When happy, clip the wings.


The 16 towers with a total of 256 soldering joints is a great way to improve soldering skills for novices. For everyone else, it is a great way to test one’s patience.

Before assembly, solder the SMT header to the PCB. This is where the Arduino Nano will go. The reason for using surface mount headers is to avoid visible solder joints on the top.

To assemble, put the PCB in the base and stick all 16 towers in it without soldering. Take care to ensure that all towers are oriented the same way by matching the orientation of the topmost LED. Put the hat on top and turn it all upside down. It is now possible to adjust the height/level of the PCB and make sure it is completely flat. Also make sure that all towers are fully extended into the hats and not suspended in the air.

Then solder the last 64 joints and hope for the best.


As a last step, cut the protruding wires, and.. Voila!

I can’t wait to make som impressive sequences for this, watch this space for the obligatory scroll text program next.

Apr 14 14

American Netflix on any device without VPN or site-wide DNS changes – using pfSsense

by Finn Espen Gundersen
Netflix Mad Men

It seems like everyone is finding ways to watch American Netflix content. While it is easy with one of many plugins on the computer, it gets harder on devices such as iPad or PS3 and even more so on Chromecast with its hard-coded google DNS. Some people will also want a solution for the home router, covering all devices at once.

The most common fix is to get a VPN. Usable from the computer, iPad, Chromecast or a sufficiently advanced router, a VPN routes your traffic through a server in the US. The main drawback is speed. Most VPN providers are over-subscribed and, in general, it will be hard to get Super HD streaming – at least with any stability and on more than one device. You will also want to separate your other browsing traffic from the VPN to avoid the speed loss, and avoid having all websites think you are from the US. All in all, a solution with drawbacks.

Another common fix is to get a custom DNS provider such as or After the extremely easy sign-up you just change your DNS server settings to point to theirs. The custom DNS will return the addresses to their own US-based servers (reverse proxies) for all Netflix-related lookups. All other traffic flows normally.

This avoids the speed loss of a VPN as the actual streaming goes directly from Netflix’s servers to your home. It also does not affect your other web traffic. Usually a cheaper service than a VPN, this seems like the perfect solution. It does, however, have a slight security implication: the DNS provider can see all your lookups and could in theory log or divert some of it.

What we want is to divert only relevant lookups to the proxy provider’s DNS. This is accomplished in pfSense by adding a domain override in the DNS Forwarder. The web gui for the domain override adds wildcards, so an entry for will also cover all subdomains. We accomplish our task by adding the following to Services | DNS Forwarder | Domain Overrides and making sure the box “Query DNS servers sequentially” is checked:

The IP address is for the DNS server of unblock-us. Only the first two lines are necessary for Netflix, the others are for Rhapsody, Pandora and Hulu.

For the unbehaving Chromecast, with its hard-coded Google DNS, we are forced to add a NAT rule to reroute all DNS requests. In Firewall | NAT | Port Forward, add a new rule with these settings:

RDR: Unchecked
Interface: LAN
Protocol: UDP/TCP
Source: IP of your Chromecast
Source port: any
Destination: any
Destination port: DNS (53)
Redirect target IP: the DNS server of unblock-us or similar service
Redirect target port: DNS (53)

Chromecast pfSense NAT

All in all this is a perfect solution. Switching regions can be done either in the DNS provider’s web interface, or by disabling the pfSense settings.

Apr 6 14

Altibox med egen ruter med pfSense

by Finn Espen Gundersen

De fleste som har Altibox fiber-bredbånd og vil bruke egen ruter hjemme setter Altibox-ruteren i bridge-mode. Men det er unødvendig å ha den som et ekstra ledd mellom deg og internett. Du kan like gjerne kople din egen ruter eller server rett på linjen.

Denne trengs ikke

Denne trengs ikke

Om du ikke har vært Altiboxkunde alt for lenge så har du en mediekonverter foran ruteren som leveres av Altibox. Da kopler du deg direkte i mediekonverteren. Har du ikke en mediekonverter er jobben litt mer innfløkt fordi du må direkte på fiberen med f.eks egen mediekonverter.


En PC med to nettverkskort, hvorav kortet som skal være WAN støtter VLAN (det gjør de fleste) er alt som trengs. Jeg bruker en HP Microserver med et ekstra nettverkskort og pfSsense. HP Microserver sitt innebygde nettverkskort støtter VLAN. Boksen har heller ingen problemer med de høye båndbreddene man kan få hos Altibox. Vil du bare teste så fungerer det helt fint å starte pfSense fra USB-pinne uten å installere.

Internett leveres på VLAN 102 og den offentlige IP-adressen kommer med DHCP. TV leveres på VLAN 101. Takk til første poster i denne posten for disse opplysningene. Det er mulig rettskriving ikke er posterens beste side, men han vet hva han snakker om.

Når pfSense starter spør den først etter evt VLAN. Svar ja og oppgi VLAN-tag 102 på WAN-kortet. Om WAN-kortet heter bge0 skal deretter WAN bindes til bge0_vlan102. LAN bindes til det andre kortet.  Videre innstillinger kan gjøres i pfSense webinterface på

pfSense Altibox

pfSense setter som default opp ruting og NAT mellom WAN og LAN og henter adressen på WAN-kortet via DHCP automatisk. Det er overraskende lite jobb å få dette til, jeg hadde satt av godt med tid til frustrasjon, men opplevde ingen. Ingen endringer på Altibox sine selvbetjeningssider er nødvendig. Det er heller ikke nødvendig å sette MAC-adressen på WAN-kortet til samme MAC som Altibox-ruteren. Alt bare virker.

Har du kommet så langt som dette så får du til ruting av TV-signalet selv. Når du først er i gang, så gå for Altibox IPv6 i tillegg.

Altibox burde dokumentere denne fremgangsmåten på egne sider. Det gir ikke mer supportkostnader enn for bridge-mode-brukerne (“eget ansvar, plugg tilbake ruteren vår før vi hjelper deg”), men ville gitt Altibox som brand mye geek-cred. Og det er slike som velger bredbånd for venner og slektninger.