Posted by Binor on 03/01/2016

In this post, we show how to setup a simple LAN gateway running a DHCP server and DNS forwarder. The setup is based on OpenBSD and uses the DHCPD and Unbound.

We are assuming to have a box with two NIC cards. The first one is connected to the internal network. The second is connected to your internet access device (e.g. DSL router). We also assume that the box is running OpenBSD. The installation of OpenBSD is straight forward.

First we have to configure the static IP on the two network interfaces. Assuming the internal interface is named em1 and the external interface is em0, this is done by editing the files /etc/hostname.em0 and /etc/hostname/em1 to look like the following:

# /etc/hostname.em0 inet NONE -inet6 # /etc/hostname.em1 inet NONE -inet6

Since we are using static IP, we need to define the default gateway. This is done by adding the IP of the network gateway to the file /etc/mygate. For example in our example, the default gateway is For the network configuration changes to take effect, we have to run the following command:

sh /etc/netstart

After the configuration of the network interfaces of our gateway, we need to configure it to be able to forward IP packets between these two interfaces. This is necessary to be able latter to configure the gateway to do NAT. The following command enables this feature:

sysctl net.inet.ip.forwarding=1

To make this change permanent, we have to run the following command:

echo "net.inet.ip.forwarding=1" >> /etc/sysctl.conf

Next step is the configuration of pf (packet filter) to enable NAT. We also by default block all incoming connections on the external interface. The file /etc/pf.conf contains the configurations of the packet filter program.

# /etc/pf.conf
int_if = "em1"
lan_net = ""
set skip on lo0 				# allow all on localhost
match in all scrub (no-df) 		# scrub incoming packets
block log all 					# by default block all
block in quick from urpf-failed 	# protect from spoofing
pass in on \$int_if from \$lan_net	# allow all incoming packet on em1 coming from the LAN
pass out on \$int_if to \$lan_net	# allow all outgoing packet on em1 going to the LAN
pass out on \$ext_if proto { tcp udp icmp } all modulate state # allow all outgoing on em0
# enable natting
match out log on \$ext_if from \$int_if:network nat-to (\$ext_if:0)

The pf configuration is enable by running the command pfctl -f /etc/pf.conf

The above configurations provide the basic setup of a LAN gateway. Our box is now able to route traffic between our LAN and the internet. To make life easier for our LAN users, we need to have at least a DHCP and DNS servers. The first one enables the users to get dynamically an IP. The second is used mainly as a DNS cache/forwarder. It can also be used to define local host mapping for some of the LAN services.

For the DNS service, we use Unbound, a DNS cache solution that ships by default with OpenBSD. The configuration file should look like the following:

    do-ip6: no
    verbosity: 3
    log-queries: yes

    access-control: refuse
    access-control: allow
    access-control: allow
    access-control: ::0/0 refuse
    access-control: ::1 refuse

    hide-identity: yes
    hide-version: yes

    name: "."                               

In the configuration above, we first define the interfaces the Unbound daemon will be accepting request on. In our case, the loopback and the LAN interfaces. After that, we disable IPv6 and enable DNS query logging. Access controls settings define from where the DNS queries can be accepted. The final lines of the configuration file define to where the queries are forwarded. We use here the Google public DNS servers. The next step is now to enable the Unbound daemon service and start it:

rcctl enable unbound
rcctl start unbound

The final step of our gateway setup is the configuration of the DHCP server using dhcpd. The configuration file should look like the following:

shared-network BINOR-LOCAL {
    default-lease-time 86400;
    option  domain-name "BINOR.LOCAL";
    option  domain-name-servers;
    subnet netmask {
            option subnet-mask;
            option broadcast-address;
            option routers;

The dhcpd configuration next step is to define the network interface the daemon will be listening on. This is done by appending the following line to the file /etc/rc.conf.local :


The final step of the configuration is to enable the auto start of the dhcpd service and updating the gateway /etc/resolv.conf to point to localhost.

rcctl enable dhcpd
rcctl start dhcpd
echo "nameserver" > /etc/resolv.conf

After these steps, we have a working small LAN gateway offering a DHCP and DNS caching/forwarding services. Possible next steps is to setup our mail and/or XMPP services.


Let's Get In Touch!

+222 45 29 00 29

+222 45 29 85 40