Running network services on FreeBSD: a DHCP server with ISC dhcpd, DNS with local Unbound or BIND, and time synchronization with ntpd or chronyd. You will also assemble FreeBSD into a router or gateway with IP forwarding, NAT via pf, and integrated DHCP.

In the previous episode 10, you configured interfaces, routing, and basic DNS. Now we go one level up: running network services — DHCP to hand out IP configuration, DNS for name resolution, and NTP for time synchronization. By the end of the episode, you'll assemble all of it into a FreeBSD router or gateway.
pkg install isc-dhcp44-serversysrc dhcpd_enable="YES"
sysrc dhcpd_ifaces="em0"
service isc-dhcpd startThe main configuration is in /usr/local/etc/dhcpd.conf. An example subnet for a lab:
subnet 192.168.1.0 netmask 255.255.255.0 {
range 192.168.1.100 192.168.1.200;
option routers 192.168.1.1;
option domain-name-servers 192.168.1.1;
}Info
dhcpd requires the interface serving DHCP to have a static address. Don't run a DHCP server on an interface that itself uses a DHCP client — you'll be dealing with constantly changing addresses.
service isc-dhcpd status
tail -f /var/log/messagesUnbound is a lightweight, secure resolver — great for local DNS caching:
pkg install unbound
sysrc local_unbound_enable="YES"
service local_unbound startUnbound's configuration is in /usr/local/etc/unbound/unbound.conf. Once active, point resolv.conf to 127.0.0.1:
sysrc nameserver="127.0.0.1"dig @127.0.0.1 example.comSuccess
A local Unbound improves privacy (DNS no longer leaks to your ISP) and speed (caching). It's a small service with a big impact on every FreeBSD machine.
If you need to run authoritative DNS for your own domain, BIND is the mature choice:
pkg install bind916
sysrc named_enable="YES"
service named startsysrc ntpd_enable="YES"
service ntpd startFor environments demanding precision, chronyd from packages is an alternative:
pkg install chrony
sysrc chronyd_enable="YES"
service chronyd startchronyc trackingWarning
Don't enable ntpd and chronyd at the same time — they compete to manage the clock and overwrite each other. Pick one and stay consistent.
sysrc gateway_enable="YES"
sysctl net.inet.ip.forwarding=1To let LAN clients reach the internet, set up NAT with pf. The pf configuration goes in /etc/pf.conf:
ext_if = "em0"
lan_if = "em1"
nat on $ext_if from $lan_if:network to any -> $ext_if
pass allsysrc pf_enable="YES"
service pf start
pfctl -f /etc/pf.confDanger
When enabling pf with a pass all rule, make sure your administrative connection doesn't drop. Test pf rules with pfctl -f while the session is still open, and keep console access ready as a fallback.
A single machine can hold everything at once — a WAN interface for the internet, a LAN interface for clients, DHCP to hand out configuration, Unbound for DNS, and pf for NAT:
sysrc ifconfig_em0="inet 203.0.113.1/24"
sysrc ifconfig_em1="inet 192.168.1.1/24"
sysrc gateway_enable="YES"
sysrc pf_enable="YES"
sysrc dhcpd_enable="YES"
sysrc local_unbound_enable="YES"
service netif restart
service pf start
service isc-dhcpd start
service local_unbound startdhcpd is running and the interface is right, then tail /var/log/messages.dig @127.0.0.1 and make sure resolv.conf points to the correct server.pfctl -s info, make sure forwarding is active, and test pings from a LAN client to a public IP.service -e
service -rIn this episode 11, you ran network services on FreeBSD: a DHCP server with isc-dhcpd, DNS with Unbound and BIND, time synchronization with ntpd or chronyd, and you assembled everything into a router or gateway with IP forwarding, pf NAT, and DHCP.
Key takeaways: