Local DNS setup with Dnsmasq, NSD and Unbound

In this article, I want to show you the dns installation I made in my local network, in hope it will be useful to somebody. It’s also a way for me to check the setup, be sure everything works as supposed.

Here is the base of the config and what I want :

  1. Openbsd server on a lan, setup as DMZ, so it listens directly to internet AND the lan.
  2. Ipv6 enabled.
  3. I host my own domain name server, with dnssec.
  4. I intend to do dnssec validation as well.
  5. I want to be able to resolve all my hosts address, so that a new host can enter the network without problem. He will have ip + ipv6 address and hostname.

As you can see, it may be a bit complicated !


I see two solutions :

  1. The venerable Bind and its cousin Dhcp which update the local zone. You use the Bind view function to answer authoritative  for your own domain. Problem : Bind has its critics. It is considered heavy and bogus. Depending on your dhcp server, you may have problems with dhcpv6 and dns updating (maybe). And you have to launch a r(t)advd[1] for people not using dhcpv6.
  2. You use Dnsmasq as a local dns + dhcp +dhcpv6 +r(t)advd daemon. At the same time, you  use unbound as a deep resolver, and you answer autoritative side (your domain) with nsd.

In the second solution, the resolver and the authoritative server can be other softwares of course. Yet, NSD and Unbound are in the base of OpenBSD, so I won’t argue.

Compare the two solutions :

Bind + dhcpv4 + dhcpv6 +r(t)advd

You need ddns to be able to add hosts in the lan without thinking of it. And you need to setup Bind to answer dns queries depending on the origin of the requests (it’s the view function). So you have a lot of work to setup Bind correctly. Both Dhcp and Bind have to share some common settings (the ddns key).


Dnsmasq works almost out of the box for local matters. But you need to setup a proper resolver for dnssec validation and recursion. And you have to take care all this daemons won’t collapse each others, as they are suppose to use the same port and address !

As said above, it will be complicated !

I will use the Dnsmasq solution. At first, I though Dnsmasq was not a good thing. Its configuration looks like a mess, or a draft, as you want. But I really like the fact that it is possible to run completely a lan on its behalf ! If you don’t want to browse the web, nor need to host an authoritative domain server, it’s perfect ! It completely replace three softwares at once (local and caching dns server, dhcp 4 and 6, both coordinated, and r(t)advd).


Actually, as you have noted, we will have three (!) dns servers running on the same machine. That may lead to huge problems ! So I am going to launch all this servers on different ports, and use pf to forward queries coming from the lan to Dnsmasq, which will ask Unbound to resolve the deep internet with dnssec.

I could use one address per server (after all, we are in a lan, we can use ten addresses with not much problem, and ipv6 allows so much addresses) but Dnsmasq doesn’t like to be restricted in address listening. So I prefer forward ports.

I will use mainly ipv6 local address when needed. When ipv4 will be out of order (in years) you should have switched every service to ipv6 at each configuration upgrade, and, voila… you can now shutdown the ipv4 stack (if you want so).

Everybody understand  and ready ? Let’s go !



Let’s start with the autoritative dns server. He will listen to the internet, on the standard port, unaware of the two other daemon.

I followed this tutorial to setup NSD properly. It serves well this domain, signed with dnssec.

Remember to add nsd to rc.conf.local :



Dnsmasq is available in Openbsd packages or ports. Bad news is that it’s buggy at present. I will use the git version.

cd /usr/src/
git clone git://thekelleys.org.uk/dnsmasq.git
cd dnsmasq
make install

I will make dnsmasq listen on the port 5353 for its dns part. All the rest will remain default or almost. You should have a look at dnsmasq doc ! Here is my config :

# Configuration file for dnsmasq.
# Format is one option per line, legal options are the same
# as the long options legal on the command line. See
# "/usr/local/sbin/dnsmasq --help" or "man 8 dnsmasq" for details.
# Listen on this specific port instead of the standard DNS port
# (53). Setting this to zero completely disables DNS function,
# leaving only DHCP and/or TFTP. I set 5353 here and pf will forward local
# dns queries to this port.
# Never forward plain names (without a dot or domain part)
# Never forward addresses in the non-routed address spaces.
# Add local-only domains here, queries in these domains are answered
# from /etc/hosts or DHCP only.
# talk with unbound on port 5354
# Set this (and domain: see below) if you want to have a domain
# automatically added to simple names in a hosts-file.
# Set the domain for dnsmasq. this is optional, but if it is set, it
# does the following things.
# 1) Allows DHCP hosts to have fully qualified domain names, as long
# as the domain part matches this setting.
# 2) Sets the "domain" DHCP option thereby potentially setting the
# domain of all systems configured by DHCP
# 3) Provides the domain part for "expand-hosts"
# Specify a subnet which can't be used for dynamic address allocation,
# is available for hosts with matching --dhcp-host lines. Note that
# dhcp-host declarations will be ignored unless there is a dhcp-range
# of some type for the subnet in question.
# In this case the netmask is implied (it comes from the network
# configuration on the machine running dnsmasq) it is possible to give
# an explicit netmask instead.
# Do DHCP and Router Advertisements for this subnet. Set the A bit in # the RA so that clients can use SLAAC addresses as well as DHCP ones.
# dhcpv6 range, default netmask is 64
dhcp-range=2001:DB8::100, 2001:DB8::8000, ra-names
# Send options to hosts which ask for a DHCP lease.
# See RFC 2132 for details of available options.
# Common options can be given to dnsmasq by name:
# run "dnsmasq --help dhcp" to get a list.
# Note that all the common settings, such as netmask and
# broadcast address, DNS server and default route, are given
# sane defaults by dnsmasq. You very likely will not need
# any dhcp-options. If you use Windows clients and Samba, there
# are some options which are recommended, they are detailed at the
# end of this section.
# my ipv4 router is not the machine running dnsmasq !
# means you say a dhcp option with the dnsmasq address.
# Here the ntp server
# I use the dns-server running on the server (dnsmasq itself !)
# plus opendns server
# domain to pass to the dhcp client (same as the one in domain=...).
# same options as ipv4, with ipv6 notion.
# [::] means dnsmasq address.
# Set the cachesize here.

You obviously have to adapt your settings : domain name, ip address range and ipv6 address range. In the configuration above, I use opendns servers and the ipv6 router is the same machine as the one running dnsmasq. But the ipv4 router is different.

You have to have a rc script. Here is mine :

daemon="/usr/local/sbin/dnsmasq --proxy-dnssec"
. /etc/rc.d/rc.subr
rc_cmd $1

Dnsmasq will forward recursive dns to unbound, with a dnssec proxy.
And add dnsmasq to pkg_script in /etc/rc.conf.local


Unbound is installed by default in OpenBSD base. It’s a good idea to have a look at its documentation. In order to resolv dnssec, you need to install root keys before it starts. So run this command :


Then goes the configuration of the daemon. You don’t have much to change. Just take care of the port, and the anchors (I installed the root anchor with the previous command and the dlv anchor) :

# The server clause sets the main parameters.
# verbosity number, 0 is least verbose. 1 is default.
verbosity: 1
# port to discuss with dnsmasq
port: 5354
# Enable IPv4, IPv6, Udp,Tcp,"yes" or "no".
do-ip4: yes
do-ip6: yes
do-udp: yes
do-tcp: yes
access-control: refuse
access-control: allow
access-control: allow
access-control: ::0/0 refuse
access-control: ::1 allow
access-control: fe80::/64 allow
access-control: 2001:DB8::/64 allow
chroot: "/var/unbound"
log-queries: yes
root-hints: "named.cache"
module-config: "validator iterator"
auto-trust-anchor-file: "root.key"
dlv-anchor-file: "dlv.isc.org.key"

Remember to make unbound start on boot. You should have this in /etc/rc.conf.local, here both dnsmasq and unbound. Now, your rc.conf.local should have this :

pkg_scripts="... dnsmasq unbound ..."


Here is the great trick : you have to redirect every dns query arriving on the server to dnsmasq ! Overwise, it will be NSD which receive the request, which it has no damn knowledge of !

In my pf.conf, I have a localnet table (replace the « by < and reverse), very useful. Then I allow the server to talk friendly with the neighbourhood (general rule no purpose with this article), but I don't use quick ! Then I forward local dns queries to dnsmasq port (5353). And finally, I let casual dns queries pass to Nsd.

table «localnet» {, 2001:DB8::/64, fe80::/64,, ::1 }
# let’s talk with the neighbours
pass in from «localnet» to any
pass out from any to «localnet»
# dns redirection sur dnsmasq
pass in log quick inet proto { udp,tcp } from «localnet» to any port domain rdr-to port 5353
pass in log quick inet6 proto { udp,tcp } from «localnet» to any port domain rdr-to ::1 port 5353
# final dns port
pass in log quick proto { tcp, udp }    from any to any port domain

Take care of the rules interaction ! You may have a look on the pf.conf manual and search for the tutorials on internet... The orders the rules apply is really important !


In order for the server itself to resolv its network and companions (via dnsmasq), and the internet outside (via unbound), we have to change the content of the /etc/resolv.conf file on the server.

We request the two dns daemons. To use the non standard port, you must use brackets [ ], with or without ipv6. Finally, I indicate also opendns, in order to prevent failure from unbound which will arrive, one day or an other !

search example.com
domain exemple.com
lookup file bind
nameserver [::1]:5354
nameserver [::1]:5353
nameserver 2620:0:ccc::2

In use...

I have this config running quite correctly, with dnssec validation and local hosts resolving. Remember to ask your network client to work with dhcp (v4 and v6). This works perfect on debian and windows. I have only troubles because my isp forces the dns resolution on its dns servers. There seems to be a debian bug on that.

Dnsmasq act also as r(t)advd and furnish dns info as well as route, it's useful for temporary hosts. But when I began setting this up, it worked better with dhcpv6 - at least for hosts resolution.

You can install a dnssec validator in firefox. I have now quite often a green key in my address bar. That's fine.

[1] Under OpenBSD, the router advertisement daemon is called rtadvd. Under debian it's called radvd. So I use the r(t)advd word instead.

Piwigo : Ldap login v1.1

I have recently released my piwigo plugin. Unfortunately, there was a small mistake, which made the plugin unusable. Thus, I just reviewed the code and published a new release.

This release correct this bug and use (for the first time) the install function of Piwigo. That allows you to reset the plugin config. I hope to have done it in a correct manner.


The plugin is available for download on piwigo extensions website. You can also get it there, signed with my gpg key.

You just have to download the zip and unzip it in your piwigo instance plugins directory. Don’t forget to give the correct rights, as the plugin need to write its config in its folder.

You may also find the plugin in your extensions manager.

You can discuss about the plugin and / or receive help in the comments below, through my mail (stephane AT 22decembre DOT eu). The french piwigo forum has a topic about the plugin (which I launched and follow regularly), but the english forum not, it seems.

If you launch a topic there, please mail me so that I can follow and help you.


If you want to help, you can download the sources from the svn :


Contact me by mail or jabber : stephane AT 22decembre POINT eu.By discussing, we can improve the thing. I don’t really like that someone write me with a piece of code without discussing the point, proving it’s a good idea or not.


This plugin is provided as open-source and free software. Read it, comment… Everything is good.

But I think some of you would feel good to give back a bit. Feel free to give a piece of money, any amount you want on my bitcoin address :


Piwigo : Ldap login v1.0

Piwigo has recently released 2.6. This was a good time for me to release also a new version of my plugin ldap_login.
I added a function some people have requested for : ability to add new users to piwigo database when they are successful along the ldap. So, no boring work to synchronize the two sides : ldap and piwigo. The plugin works for you !

I think this new release will please the great domains admins, typically university or big firms / department with hundreds or thousands of users. At least two persons with this kind of function have contacted me for that. I am happy to help them in their task.


This release is working with the piwigo 2.6 release. It is compatible with the previous one only if you don’t use the new function : create new users when ldap is successful.

To my mind, this release is not yet to be considered stable, as it miss your comments or bugs reports. There is really little chance you face big crash in installing or testing.

The plugin is available for download on piwigo extensions website. You can also get it there, signed with my gpg key.

Edit : as I have published the minor release 1.1, I get the text of this article there.

Softwares projects

Apart from running all the city in search of a job, going to 5 danish courses 4 days a week and to the archery club, I am also working a bit on few software projects I have.

First, I am the writer of the piwigo ldap_login plugin, and I hope to make a new version soon, as the 2.6 release of piwigo is arriving !

Secondly, this other softwares are now written using the flask python framework. I have learned a lot reading Miguel Grinberg’s blog and flask tutoriel. Thanks to him ! Like himself, I demonstrated totally lack of originality in my two last softwares’ names, if you have better ideas, please indicate in comments !


Bib’lib is a software that aim at showing my whole bookshelf on a web-page. All books are linked to their author’s page, if I registered the author and way back (the author’s page contains how many of his books I have). Some weird and funny metadatas are registered as well, like the weight and heigh of the books, when I know them.

The purpose of this specific useless thing is for fun, showing the weight of your bookshelf, but also sizing it correctly (You can guess the average heigh of your books, and their weight, so calculating the heigh of your furniture… Hack the thing !).

Currently, I can register books using their bare-code along Amazon database, which is quite fast, or of course by hand. Each book page should contains author name, photo of the front page and the text at the back of the book. But Actually nothing is mandatory. Same for the authors.

At the end, I want to implement a comments system, and stars showing which books and authors I like or not. That way, you can go there and see what you can buy me as a Christmas present or not (because I don’t like the author, or already have the book !) Acually, this was one of the secret aims of the software !

You can have a look at the functioning software here. The code is available in my git server, under the french CeCill licence.
git clone git://blackblock.22decembre.eu/biblib-flask


Flask torrents is a simple web application aimed at control the transmission torrent daemon of an unix server. It is based on the python rpc transmission library. So, it’s simply a web interface to transmission daemon !

The aim is to simply allow any user on the server to add and control his torrents, and receive them in his home repository. At the end, the daemon, under the control of the application, should mail the user to advertise it’s finished.

That way, torrents could run all day and all night long on the server. You can even let them sharing infinitely (or so long…).

I think also of using html5 video abilities and/or vlc plugin to allow video watching when possible (that should be easy to do !).

As you see, I would like to make it like working by default on the unix server itself, using unix philosophy, and users can access their downloaded data within nfs (I think) or an other way.

To do that simply, I use ldap central user management to do authentication and send mail to the user address. But it’s almost useless : authentication can be done by pam, and we could rely on the mail system itself. It’s the user’s job to fetch his mail in the system ! So if anyone want to implement a pam auth for flask, I would be glad to use it as well and allow both (ldap user management or pam/system).

Here are the screenshots. These are ugly, as webdesign is not my best ability !

Here, each user can control his torrents and add another.

Here, each user can control his torrents and add another.

a torrent page, where a user can fine tune his torrents, file priorities and ratio

a torrent page, where a user can fine tune his torrents, file priorities and ratio

I am currently trying to find a beautiful webdesign/framework. If someone is interested in the project, feel free to contact me on stephane AT 22decembre DOT eu.

The code is available in my git server, as the first project under the Cecill licence, clone it :
git clone git://blackblock.22decembre.eu/flask-torrent


Ldap Users Manager is supposed to be a simple web interface to add and remove users from a Ldap server. It aims at being simple and customizable ! I use Phpldapadmin now, and don’t feel it so easy to manage, and totally uncomfortable for common users, so they don’t want to update their password there !

Functions :

  • add, remove users
  • add, remove groups and manage their users
  • do things when users/groups are added/removed, such as gpg key creation (for exemple)
  • let users easily update their password and profile (such as photo)
  • there should be a public page per user where everything he agree is displayed (photo, gpg key). This last function aims at comply with havatar and pavatar schemes, so this could be reusable along other social networks (if the user wants) and he has one picture always updated on all the websites he is member or network he has a profile. This aims also to work along/as openid.

I have done pretty nothing in it, but you can still look there :

git clone git://blackblock.22decembre.eu/lum

Aarhus : step 6B, The trip

I didn’t talk about the trip itself in my last article. Yet, I have gone across five european countries : France, Belgium, Netherlands (the Limbourg panhandle), Germany and Denmark, a 1200 km journey !

1200 km between Paris and Aarhus

1200 km between Paris and Aarhus

I did the first on two days, stopping for the night in a german hotel, and the way back on a single day.
Usually, I don’t like to drive. I don’t know why, this time, despite tension, I began to feel discomfort the first day only after the german border. So with at least 400 km behind me !

Germany was kind of awesome : everything is giant there ! Crossroads, bridges, motorway rest areas, tunnels…

A bridge in Hambourg Photo Credits :Structurae

Traffic jam ! I have been blocked on a landscape road for three hours because the motorway has been closed. The whole traffic of a four lines motorway has been derivated to a tiny one line landscape road.
An other magnitude moment was going upside the Kiel canal, with seagoing ships going slowly under yourself.

Kiel canal passage : a steamer goes under the motorway. Photos credits : interceptor.nl

This was also an occasion to learn things about Germany ! Germans don’t speak well English or French. So far for the economic model !
During the back trip, I did some carpooling, so that I could rest and we did the journey almost without a stop, except for eating of course. That’s also more ecologic and cheaper.
And during this trip back, we have gone across Belgium at night. With Motorways wider than football fields and so much light you could drive almost car headlights switched off !
Belgians obviously use much nuclear power !

You shall take care of the speed. In Germany, it’s limited in some places, but you can’t guess why. And in Belgium, in plain night, there was nobody on the road, you can easily let the speed raise 140 km/h ! In a twingo ! Guess the noise and the fuel consumption ! Without speaking of danger !

But, as you can see, I have succeeded ! See you soon !

Aarhus : step 6, “Moving in”

As soon as I had a flat in Aarhus, I managed to get back France for few days, to close all my things there, get my belongings and finish all french related affairs.

So, I returned there, have few time with my family, and then packed everything and placed it in my car, and go !

The trip

Let’s start : you drive through five countries, including half of Germany, with all your belongings in 3 cubic meters, at 110 km/h, in a small car. quite an experience !

1200 km trip from France to Aarhus

1200 km trip from France to Aarhus

I say an experience, you need to understand it clearly : if you have any trouble, any accident, any problem with the police, you’re doomed ! Think of it : all your life here, in a small car… That’s not exactly the safest situation !

All my life and belongings in a small twingo across Europe !

All my life and belongings in a small twingo across Europe !

So you’re extremly cautious !

I have done the whole trip in two days, sleeping ina german hotel for the night.
At the end of the trip, at the danish border, it began to rain, like if Denmark was welcoming me in its own kind way ! But I have not came here for the climate.

Make it fit to live in

So I was in Aarhus with a car. Good thing to move in, cause it’s hard to buy furniture when you have only a bike !
I round the city to visit almost every second hand furniture shop, and I get a sleeping sofa, some chairs, a dining table, a small table for living room and a washing machine (this one on dba.dk).
Then I got to IKEA, and bougth the things you prefer to have new, like bedclothes, and duvet, but also some kitchen tools, plates and pans.
This Ikea trip cost me around 1000 danish kroner, so around 130 €, plus the previous furniture which was 2000 DKK.

As you can see, I managed to make my home livable for around 3000 DKK, around 200 €, and I think of it as quite an amazing exploit I am proud of !

I also prepared the next step, arrival of my little furry friend, as I bought some litter and 10 kg of dry cat food. You will read of it soon !

Girlfriend requirements

In a kind of joke, I recently wrote what I search for a wife/girlfriend :

  • open-minded
  • shall accept well the fact that I am a foreign guy (mandatory)
  • shall accept well the fact that I am french (not mandatory)
  • shall accept well to learn french either (not mandatory)
  • shall accept my hobbies (the more important in first and dicreasing) :
    • books
    • computing science and hacking
    • strategy computer games
    • civil engineering hacking
    • archery
  • shall want to participate to my hobbies (not mandatory)
  • shall want to show me her hobbies
  • shall accept I have my own Linux server and the constraints of it (looks like the computer hacking point)
  • shall accept I want to involve in society in much directions (associations, trade unions, political, neiborhood association or cooperative management … don’t know which of these will be followed)
  • shall accept that I have a strong integrity and a social view of the world (but ok that she doesn’t have such).
  • shall accept I love cats and I have one (mandatory)
  • shall love cats either (not mandatory)
  • shall accept me as I am (testing period is fairly accepted)
  • shall never mock me (mandatory)
  • shall criticize me in a fair way and accept either (both kind mandatory) in serious matters
  • busty and feel ok I love boobs either
  • shall not be so thin I feel I could break her just as I am a bit rude (during sex) or as I make her a big hug (I prefer a bit ’round girls’).
  • shall be comfortable with sex (mandatory) :-D
  • shall know sex things (not mandatory)

I know it sounds not fine to ask or require someone to behave like something… But in same time, if you meet somebody in an eve and discuss, understand she/he is gentle, go in bed with her/him and the next days, she hates your little beloved cat, what will you do ?

To go on physics, I feel also not fine or honest to ask a woman to look like a pompom girl or a model. But I don’t ask that ! I just say that I love boobs and I would definitely fall in love with a woman with some. And I know many persons who prefer girls in small ones. Tastes in nature ! :D

Yet, the first girl I fall in love didn’t have much boobs ! :D And eventhough it looks I have great expectations, reading one or two times more, I think it’s still quite “open” !…

Feel free to comment, what do you think of it ? Do you guys recognise some of your own requirements ? Some of you girls recognize yourself ?