OpenBSD Sysadmin


OpenBSD based LAN gateway

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:

1 	# /etc/hostname.em0
2 	inet 10.0.2.40 255.255.255.0 NONE -inet6
3 	# /etc/hostname.em1
4 	inet 10.4.4.1 255.255.255.0 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 10.0.2.1. For the network configuration changes to take effect, we have to run the following command:

1sh /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:

1sysctl net.inet.ip.forwarding=1

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

1echo "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.

 1	# /etc/pf.conf
 2	ext_if="em0"
 3	int_if = "em1"
 4	lan_net = "10.4.4.0/24"
 5	set skip on lo0 				# allow all on localhost
 6	match in all scrub (no-df) 		# scrub incoming packets
 7	block log all 					# by default block all
 8	block in quick from urpf-failed 	# protect from spoofing
 9	pass in on \$int_if from \$lan_net	# allow all incoming packet on em1 coming from the LAN
10	pass out on \$int_if to \$lan_net	# allow all outgoing packet on em1 going to the LAN
11	pass out on \$ext_if proto { tcp udp icmp } all modulate state # allow all outgoing on em0
12	# enable natting
13	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:

 1	#/var/unbound/etc/unbound.conf
 2	server:
 3        interface: 127.0.0.1
 4        interface:  10.4.4.1
 5        do-ip6: no
 6        verbosity: 3
 7        log-queries: yes
 8
 9        access-control: 0.0.0.0/0 refuse
10        access-control: 127.0.0.0/8 allow
11        access-control: 10.4.4.0/24 allow
12        access-control: ::0/0 refuse
13        access-control: ::1 refuse
14
15        hide-identity: yes
16        hide-version: yes
17
18	forward-zone:
19        name: "."                               
20        forward-addr: 8.8.8.8
21        forward-addr: 8.8.4.4

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:

1	rcctl enable unbound
2	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:

 1	#/etc/dhcpd.conf
 2	shared-network BINOR-LOCAL {
 3        default-lease-time 86400;
 4        option  domain-name "BINOR.LOCAL";
 5        option  domain-name-servers 10.4.4.1;
 6        subnet 10.4.4.0 netmask 255.255.255.0 {
 7                option subnet-mask 255.255.255.0;
 8                option broadcast-address 10.4.4.255;
 9                option routers 10.4.4.1;
10                range 10.4.4.100 10.4.4.200;
11        }
12	}

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 :

1	#/etc/rc.conf.local
2	...
3	dhcpd_flags="10.4.4.1"
4	...

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.

1	rcctl enable dhcpd
2	rcctl start dhcpd
3	echo "nameserver 127.0.0.1" > /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.

References: http://www.openbsd.org/faq/faq6.html