Luarocks on FreeBSD

As LuaRocks is unfortunately not part of the FreeBSD ports collection, it has to be compiled manually. As I’m going to need to repeat this process in the foreseeable future, I decided to document the required steps here.

The reason why I’m targeting Lua 5.1 specifically is that I’m installing Luarocks to build rocks to be used with the Nginx Lua module, as I plan to migrate the Telize server to FreeBSD.

Installing Lua and some required packages

pkg install lua51 gmake curl

Fetching, unpacking, and configuring using Curl as downloader

curl -O
tar xvfz luarocks-2.2.0.tar.gz
cd luarocks-2.2.0
./configure --with-lua-include=/usr/local/include/lua51 --with-downloader=curl
make build && make install
make bootstrap

Building and installing some Lua modules

luarocks build lua-cjson
luarocks build lua-iconv

Verifying that our modules have been built and installed successfully

ls /usr/local/lib/lua/5.1

FreeBSD CheatSheet

Here are some notes on how to bootstrap a FreeBSD workstation and keep it up-to-date using binary packages and/or the ports collection.

System configuration

Setting the timezone

cp /usr/share/zoneinfo/Europe/Warsaw /etc/localtime

Setting an alternative keymap in console

The keymap directive should be set in rc.conf :


Performing binary updates for the base system

freebsd-update fetch
freebsd-update install

Using pkg

Since FreeBSD 10.0, pkg is now the default tool for installing binary packages. Legacy pkg_* tools are now depreceated.

Installing pkg

To install pkg, simply invoke it and confirm action :

The package management tool is not yet installed on your system.
Do you want to fetch and install it now? [y/N]: y
Bootstrapping pkg from pkg+, please wait...
Verifying signature with trusted certificate done
Installing pkg-1.3.8_2: 100%
Message for pkg-1.3.8_2:
 If you are upgrading from the old package format, first run:

  # pkg2ng
pkg: not enough arguments
Usage: pkg [-v] [-d] [-l] [-N] [-j <jail name or id>|-c <chroot path>] [-C <configuration file>] [-R <repo config dir>] [-o var=value] [-4|-6] <command> [<args>]

For more information on available commands and options see 'pkg help'.

Installing packages

pkg install package

Updating package repository catalogues

pkg update         

Performing upgrade of packages

pkg upgrade    

Using the ports collection

Fetching and extracting the ports collection

portsnap fetch extract

Updating the ports collection

portsnap fetch update

Compiling a port and cleaning working directory and dependencies

make -C /usr/ports/category/name install clean clean-depends

Using the X.Org Server

Installing required packages

pkg install xorg

Required configuration directives

The hald_enable and dbus_enable directives should be set in rc.conf :


Minimal .xinitrc to launch a Window Manager

exec /usr/local/bin/wmaker

Setting an alternative keymap for X

The setxkbmap directive should be set in .xinitrc :

setxkbmap fr

Setting background and font colors for xterm

The following directives should be set in .Xdefaults :

xterm*background: #000
xterm*foreground: #aaa
xterm*pointerColor: #aaa
xterm*cursorColor:  #aaa

Installing Fonts

Installing TrueType core fonts for the Web :

pkg install cabextract 
make -C /usr/ports/x11-fonts/webfonts install clean clean-depends

Then follow instructions displayed after installation :

Make sure that the freetype module is loaded.  If it is not, add the following
line to the "Modules" section of xorg.conf or XF86Config:

	Load "freetype"

Add the following line to the "Files" section of xorg.conf or XF86Config:

	FontPath "/usr/local/lib/X11/fonts/webfonts/"

Allowing Chromium to start

The kern.ipc.shm_allow_removed directive should be set in sysctl.conf :


Testing a JSON API with Curl

I’ve been working a lot on JSON APIs during the past few years, and even more intensively lately. If testing GET requests is straightforward, for POST requests I often had to look at Curl documentation again for exact options names and parameter syntax for sending the desired HTTP headers.

So I decided to post some quick notes on doing unauthenticated POST requests, in order to have a quickly accessible reference.

Here is a list of some relevant Curl options :

-d, --data DATA     HTTP POST data (H)
-X, --request COMMAND  Specify request command to use
-H, --header LINE   Custom header to pass to server (H)

Doing an empty POST request

curl --request POST

Posting JSON data

curl --request POST --data "{ \"ip\": \"\", \"country_code\": \"NL\", \"country_code3\": \"NLD\", \"country\": \"Netherlands\", \"continent_code\": \"EU\", \"latitude\": 52.5, \"longitude\": 5.75, \"dma_code\": \"0\", \"area_code\": \"0\", \"asn\": \"AS196752\", \"isp\": \"Tilaa V.O.F.\", \"timezone\":\"Europe/Amsterdam\" }" --header "Content-Type: application/json"

Posting JSON data from a file

curl --request POST --data @filename --header "Content-Type: application/json"

This is particularly handy when working with large JSON objects.

Lastly, for a fully client-side JSON validator and formatter, check

NetBSD on the Raspberry Pi

Last spring, I finally caved in and ordered a Raspberry Pi. In fact, I had a very precise reason to do so : it makes a nice and affordable little board to run NetBSD natively.

Before starting, I recommend using a Class 10 SDHC Card as it will make the whole process of using pkgsrc faster.

Creating the SD card

As the Rapberry Pi port is still not part of the stable release, we will have to run NetBSD-current. Pre-built images can be downloaded here.

Let’s fetch an image, and create the bootable media :

gunzip rpi.img.gz
dd if=rpi.img of=/dev/da0 bs=4M

I used FreeBSD to create the SD card, so please set the output file accordingly when using other systems.


Switch the Raspberry Pi on and login as root, there is no password by default.

We can run uname -a to get more details about the build :

NetBSD rpi 6.99.40 NetBSD 6.99.40 (RPI) #1: Wed Apr 23 12:06:29 UTC 2014 evbarm

And here is /etc/motd customized with my NetBSD ASCII logo :

NetBSD 6.99.40 (RPI) #1: Wed Apr 23 12:06:29 UTC 2014

                  ________    _____
       _____     /       /   /    /___  _ _
    __|     \  _/    ___/ / /        /     |                 _ __
   /         \       \     /      __/     _|_______       ______/_
  /          /       /___ /      /____  \ \        \     /     / / _____
 /     :     \     _/    /     _/    /   \ \____    \   /     __/ /     |__
/      |      \          \           \  _ _    /    /___\     \__/         \
\      |       \  __      \____       \/      /    /     \       \     .    \
 \___ _|       / __/______/ __/_______/     __\    \      \      /     |     \
  \__  |______/    \_____/    \______/\    |        \    _/     /     __\     \
     |_|_____/                         \___|        /           \    |         \
       |                                \__|_______/______  Cl!  \___|         /
       |     Welcome to NetBSD/evbarm      | _____/ \____/_______/_  | _ _____/
       |                                   |             \______/  |_|______/
       |___ __   _______ _   _ ___ _ __  __|

This system is running a development snapshot of the NetBSD operating system,
also known as NetBSD-current.  It is very possible that it has serious bugs,
regressions, broken features or other problems.  Please bear this in mind
and use the system with care.

You are encouraged to test this version as thoroughly as possible.  Should you
encounter any problem, please report it back to the development team using the
send-pr(1) utility (requires a working MTA).  If yours is not properly set up,
use the web interface at:

Thank you for helping us test and improve NetBSD.

Add a password :


Add a regular user in the wheel group :

useradd -m -G wheel username

Growing the root file-system

As the NetBSD image written to the SD card has a fixed size, we will need to resize the file system to span the whole card.

The NetBSD Wiki has the required steps listed here : NetBSD/evbarm on Raspberry Pi.

Keeping time synchronized

As the Raspberry Pi does not include a hardware clock on board, we will need to use NTP to keep the time synchronized.

Setting time zone :

ln -fs /usr/share/zoneinfo/Europe/Warsaw /etc/localtime

After adding the ntpdate directive in rc.conf :

echo "ntpdate=YES" >> /etc/rc.conf

We can start ntpdate manually :

/etc/rc.d/ntpdate start

Using pkgsrc

To fetch and unpack the pkgsrc current branch, run :

tar xfz pkgsrc.tar.gz -C /usr

We can now start building :

echo "ACCEPTABLE_LICENSES+= vim-license" >> /etc/mk.conf

for package in chat/irssi editors/vim misc/screen misc/tmux net/nload net/mtr net/unbound net/wget shells/zsh sysutils/mc sysutils/pv www/curl www/links www/lynx www/nginx ; do
    cd /usr/pkgsrc/$package
    make install package clean clean-depends

Specifying the package option when invoking make will create a binary package in /usr/pkgsrc/packages/All. As compiling can take a long time on the Pi, this is especially handy when doing reinstalls or using multiple boards.

Here is the list of packages which have been created :

ls -l /usr/pkgsrc/packages/All
total 94284
-rw-r--r--  2 root  wheel    909780 Apr 24 06:18 autoconf-2.69nb4.tgz
-rw-r--r--  2 root  wheel    125681 Apr 25 00:44 bsdtar-2.8.4nb1.tgz
-rw-r--r--  1 root  wheel    760030 Apr 24 15:39 curl-7.36.0.tgz
-rw-r--r--  2 root  wheel   7141904 Apr 24 09:53 glib2-2.38.2.tgz
-rw-r--r--  2 root  wheel    512926 Apr 24 02:04 gmake-4.0.tgz
-rw-r--r--  2 root  wheel     85486 Apr 24 05:56 help2man-1.45.1.tgz
-rw-r--r--  2 root  wheel     43185 Apr 25 00:29 intltool-0.50.2nb2.tgz
-rw-r--r--  1 root  wheel    507486 Apr 24 10:21 irssi-0.8.15nb9.tgz
-rw-r--r--  1 root  wheel    442189 Apr 24 19:30 ldns-1.6.16nb3.tgz
-rw-r--r--  2 root  wheel     93192 Apr 24 06:28 libelf-0.8.13.tgz
-rw-r--r--  2 root  wheel    642068 Apr 24 18:29 libevent-2.0.21nb3.tgz
-rw-r--r--  2 root  wheel     43643 Apr 24 07:12 libffi-3.0.13.tgz
-rw-r--r--  2 root  wheel    257832 Apr 24 11:24 libidn-1.28.tgz
-rw-r--r--  2 root  wheel   1229536 Apr 24 13:41 libslang2-2.2.4nb2.tgz
-rw-r--r--  2 root  wheel    468947 Apr 24 01:11 libtool-base-2.4.2nb6.tgz
-rw-r--r--  1 root  wheel    451896 Apr 24 21:18 links-2.8nb1.tgz
-rw-r--r--  1 root  wheel   2339499 Apr 24 17:54 lynx-
-rw-r--r--  2 root  wheel    215882 Apr 24 06:16 m4-1.4.17.tgz
-rw-r--r--  1 root  wheel   2102060 Apr 24 14:32 mc-
-rw-r--r--  1 root  wheel     43411 Apr 24 20:23 mtr-0.85nb3.tgz
-rw-r--r--  1 root  wheel    288745 Apr 24 21:54 nginx-1.4.7nb5.tgz
-rw-r--r--  1 root  wheel     52094 Apr 24 12:09 nload-0.7.4.tgz
-rw-r--r--  2 root  wheel    200993 Apr 25 00:27 p5-XML-Parser-2.41nb2.tgz
-rw-r--r--  2 root  wheel     15613 Apr 24 05:54 p5-gettext-1.05nb9.tgz
-rw-r--r--  2 root  wheel   1179041 Apr 24 07:06 pcre-8.34.tgz
-rw-r--r--  2 root  wheel  15767929 Apr 24 05:49 perl-5.18.2nb1.tgz
-rw-r--r--  2 root  wheel    207352 Apr 24 01:52 pkg-config-0.28.tgz
-rw-r--r--  1 root  wheel     51044 Apr 24 17:10 pv-0.9.6nb1.tgz
-rw-r--r--  1 root  wheel    188499 Apr 24 22:20 tmux-1.9a.tgz
-rw-r--r--  1 root  wheel    976804 Apr 24 19:06 unbound-1.4.22.tgz
-rw-r--r--  1 root  wheel    913978 Apr 25 00:18 vim-7.4.141.tgz
-rw-r--r--  2 root  wheel   6244854 Apr 24 23:32 vim-share-7.4.141.tgz
-rw-r--r--  1 root  wheel    932868 Apr 24 11:53 wget-1.15nb1.tgz
-rw-r--r--  1 root  wheel   2511673 Apr 24 11:04 zsh-5.0.5.tgz

Final words

So far, running NetBSD on the Raspberry Pi has been a very positive experience and the system is very stable. I would definitely recommend anyone wanting to use BSD on the Pi to give NetBSD a try, it’s well worth it.

I should probably also mention that it’s smaller than a toaster :-)

My Raspberry Pi running NetBSD

Lastly, for some prebuilt images with X.Org included :

Nginx and Server Side Includes

Server Side Includes are an interesting way to embed content dynamically into static files. It can be particularly useful to inject information about the visitor or to add headers, footers or any file containing data changing over time.

Please note, however, that Nginx does not implement the full SSI specification yet. More information about what is currently supported can be found in the ngx_http_ssi_module documentation.

To enable SSI, the following directive must be added in the http, server or location block :

ssi on;

Here is an example HTML snippet with SSI directives, showing how to echo variables and include content from other files :

<h2>Visitor information</h2>

<p>Visitor IP address : <!--#echo var="REMOTE_ADDR" --></p>
<p>Visitor User agent : <!--#echo var="HTTP_USER_AGENT" --></p>

<h2>Server information</h2>

<p>Server local time : <!--#echo var="DATE_LOCAL" --></p>
<p>Server time (GMT) : <!--#echo var="DATE_GMT" --></p>

<p>Server uptime (refreshed every minute) : <!--#include file="uptime.txt" --></p>

<h2>Fortune of the day</h2>

<!--#include file="fortune.txt" -->

In order to populate fortune.txt and uptime.txt, we can use Cron and refresh files content as required. For even more fun, we can also use cowsay together with fortune.

Let’s add the following entries to the Crontab :

* * * * * uptime > /path/to/htdocs/uptime.txt
0 0 * * * /usr/games/fortune | /usr/games/cowsay -f tux > /path/to/htdocs/fortune.txt

Finally, here is the resulting output when accessing the page using Lynx :

Visitor information

   Visitor IP address :

   Visitor User agent : Lynx/2.8.8rel.2 libwww-FM/2.14 SSL-MM/1.4.1 OpenSSL/1.0.1h

Server information

   Server local time : Sunday, 21-Sep-2014 18:55:49 CEST

   Server time (GMT) : Sunday, 21-Sep-2014 16:55:49 GMT

   Server uptime : 18:55:01 up 52 days, 7:50, 3 users, load average: 0.13, 0.19, 0.22

Fortune of the day

/ In most countries selling harmful      \
| things like drugs is punishable. Then  |
| howcome people can sell Microsoft      |
| software and go unpunished?            |
|                                        |
\ -- Hasse Skrifvars,, /
       |o_o |
       |:_/ |
      //   \ \
     (|     | )
    /'\_   _/`\