Creating a FreeBSD jail to run DHCP and DNS

I’m in the process of setting up a new gateway/firewall. The new hardware will be faster and have more space. At present, the old firewall is also providing DHCP and DNS services. I want to move those off the gateway and onto another server. Why? I want the gateway to run only services that are related to gateway/firewall services. That keeps things simple.

At present, the new firewall has just 43 packages installed. Not all of those are directly related to firewall-related services (e.g. joe, portupgrade, nrpe, postfix, protaudit). I could also take the opportunity to move SMTP and, perhaps, OpenVPN to an internal jailed server. But I won’t. One thing at a time.

I’m using FreeBSD 9.1 here, on a server I just set up. I’ll add an IP address, create the jail, install the software, add in the configuration files, and get it running.

I assume you already have ezjail installed and you know how to use it. I also assume you know how to configure DHCP and DNS configuration files.

This solution puts the DHCP server in a jail, but it is not chrooted within that jail. i.e. I do not use dhcpd_chroot_enable=”YES” in /etc/rc.conf. Why? It’ll be running in a jail. Additional configuration is required to chroot it. I figure: running in a jail is enough. chroot is more applicable to situations where are not already jailed.

Adding the IP address

To add the IP address to the server, I did this:

Add it to /etc/rc.conf

The following line in /etc/rc.conf will add this IP address at boot time:

ifconfig_em0_alias10="inet 10.55.0.13/32"       # toiler

em0 refers to the NIC used on this computer. If you have one, it’s that one. If you have two or more, pick the NIC you want. If you have two NICs, you’re probably too advanced to be following this article. The comment at the end of the line refers to the hostname I assign to this IP address. It relates to the DNS name. Configuring the DNS file themselves is outside the scope of this article.

To manually add the IP address, I issued this command:

# ifconfig em0 add 10.55.0.207 255.255.255.0

Creating and starting the jail

I have ezjail installed. I also have a jail flavor installed.

The command to create the jail is:

# ezjail-admin create -f bacula toiler.unixathome.org 10.55.0.13

In this case, my ezjail flavor is called bacula. It is a jail that comes preinstalled with a Bacula client.

Starting the jail:

# service ezjail start toiler.unixathome.org

Then I can ssh in:

$ ssh toiler
The authenticity of host 'toiler.unixathome.org (10.55.0.13)' can't be established.
ECDSA key fingerprint is 99:b4:08:a4:2a:30:86:99:6b:22:e6:39:b3:43:48:e7.
Are you sure you want to continue connecting (yes/no)? yes

Configuration of jail host

These steps are performed on the jail host.

If you were to install and run dhcpd in the jail, you’d see this error:

Aug 18 15:52:17 toiler dhcpd: unable to create icmp socket: Operation not permitted
Aug 18 15:52:17 toiler dhcpd: WARNING: Host declarations are global.  They are not limited to the scope you declared them in.
Aug 18 15:52:17 toiler dhcpd: No bpf devices.   Please read the README section for your operating system.

In a jail, things are terribly restricted, by default. You need to allow the jail to have access to the bpf device. This is identical to the permissions I changed for my tape library. You can also see what someone else did for this. I used their method.

I added this to /etc/devfs.rules on the jail host:

[devfsrules_jail_bpf=7]
add include $devfsrules_hide_all
add include $devfsrules_unhide_basic
add include $devfsrules_unhide_login
add path 'bpf*' unhide

Then, to my jail configuration file (/usr/local/etc/ezjail/toiler.example.org) I changed the devfs_ruleset line:

export jail_toiler_example_org_devfs_ruleset="devfsrules_jail_bpf"

To avoid this message:

dhcpd: unable to create icmp socket: Operation not permitted
  1. add the following to /etc/sysctl.conf:
    # to allow dhcp to run without: dhcpd: unable to create icmp socket: Operation not permitted
    security.jail.allow_raw_sockets=1
    
  2. Issue this command:

    # sysctl security.jail.allow_raw_sockets=1
    security.jail.allow_raw_sockets: 0 -> 1
    

After making those changes, I restarted the jail:

# ezjail-admin restart toiler.unixathome.org

Installing DHCP

These steps are performed in the jail.

I assume you already have the FreeBSD ports tree installed. I will also assume you have dhcpd.conf configured to your liking. Configuration dhcpd is outside scope. We’re all about getting it running in the jail.

But, here’s my configuration file:

default-lease-time 600;
max-lease-time 7200;

authoritative;
ddns-update-style none;

# dhcpd.conf
#
# Sample configuration file for ISC dhcpd
#


default-lease-time 86400;
max-lease-time     86400;


# This is a very basic subnet declaration.

subnet 10.105.0.0 netmask 255.255.255.0 {
	# option definitions common to all supported networks...
	option domain-name "example.org";
	option domain-name-servers 10.105.0.1, 10.105.0.73;

	option routers 10.105.0.1;

	range 10.105.0.200 10.105.0.250;
}

IP addresses will be in the range shown above. Adjust it for your needs.

To install the DHCP server, I did this:

cd /usr/ports/net/isc-dhcp42-server
make install clean

For the configuration options, I selected:

  • IPv6 protocol support
  • Enable support for chroot

To start the DHCP server at boot time, add this to /etc/rc.conf:

dhcpd_enable="YES"
dhcpd_flags="-q"

If you don’t have the -q, you’ll see something like this when you start dhcpd:

# service isc-dhcpd start
Starting dhcpd.
Internet Systems Consortium DHCP Server 4.2.5-P1
Copyright 2004-2013 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/
WARNING: Host declarations are global.  They are not limited to the scope you declared them in.
Wrote 0 deleted host decls to leases file.
Wrote 0 new dynamic host decls to leases file.
Wrote 0 leases to leases file.
Listening on BPF/em0/00:15:30:22:24:5a/10.105.0.0/24
Sending on   BPF/em0/00:15:30:22:24:5a/10.105.0.0/24
Sending on   Socket/fallback/fallback-net

Then I tried started dhcpd:

# service isc-dhcpd pd start
# ps auwx | grep dhcpd
dhcpd 16019  0.0  0.0 24324 11952 ??  IsJ   4:15PM 0:00.00 /usr/local/sbin/dhcpd -q -cf /usr/local/etc/dhcpd.conf -lf /var/db/dhcpd/dhcpd.leases -pf /var/run/dhcpd/dhcpd.pid -user dhcpd -group dhcpd
root  16035  0.0  0.0 10228  1532  1  R+J   4:15PM 0:00.00 grep dhcpd

And as you can see, it’s running, but not without a warning:

Aug 18 15:59:50 toiler dhcpd: WARNING: Host declarations are global.  They are not limited to the scope you declared them in.

I’m pretty sure that message can be safely ignored.

Is dhcpd handing out IP addresses?

I wanted to know if my new dhcpd instance was working. I stopped dhcpd on the old server, and watched the lease file on the new server. Then I turned off WIFI on my cellphone, and turned it back on. Here’s what was added to the lease file, /var/db/dhcpd/dhcpd.leases:

lease 10.105.0.200 {
  starts 0 2013/08/18 16:41:52;
  ends 1 2013/08/19 16:41:52;
  cltt 0 2013/08/18 16:41:52;
  binding state active;
  next binding state free;
  rewind binding state free;
  hardware ethernet c2:e0:ea:d4:dc:ff;
  uid "\001\310\340\353\324\334\377";
}

OK, that proves dhcpd is running.

DNS

These steps are performed in the jail.

For DNS, I will be using the version of BIND which comes with FreeBSD 9.1:

$ named -v
BIND 9.8.3-P4

I added this to /etc/rc.conf:

named_enable="YES"

And then I [attempted] to start it:

# service named start
/etc/rc.d/named: ERROR: named chroot: devfs cannot be mounted from within a jail. Thus a chrooted named cannot be run from within a jail. To run named without chrooting it, set named_chrootdir="" in /etc/rc.conf.
[code]

OK, let's add that, and try again.

[code]
# service named start
wrote key file "/etc/namedb/rndc.key"
Starting named.

Here’s what I found in /var/log/messages

Aug 18 16:58:35 toiler named[22184]: starting BIND 9.8.3-P4 -u bind
Aug 18 16:58:35 toiler named[22184]: built with '--prefix=/usr' '--infodir=/usr/share/info' '--mandir=/usr/share/man' '--enable-threads' '--enable-getifaddrs' '--disable-linux-caps' '--with-openssl=/usr' '--with-randomdev=/dev/random' '--without-idn' '--without-libxml2'
Aug 18 16:58:35 toiler named[22184]: ----------------------------------------------------
Aug 18 16:58:35 toiler named[22184]: BIND 9 is maintained by Internet Systems Consortium,
Aug 18 16:58:35 toiler named[22184]: Inc. (ISC), a non-profit 501(c)(3) public-benefit 
Aug 18 16:58:35 toiler named[22184]: corporation.  Support and training for BIND 9 are 
Aug 18 16:58:35 toiler named[22184]: available at https://www.isc.org/support
Aug 18 16:58:35 toiler named[22184]: ----------------------------------------------------
Aug 18 16:58:35 toiler named[22184]: not listening on any interfaces
Aug 18 16:58:35 toiler named[22184]: command channel listening on 127.0.0.1#953
Aug 18 16:58:35 toiler named[22184]: running

That’s not bad for a start. I used the default named.conf file without any modifications. Next, I’ll copy over my configuration from the old server and restart named. But that too is outside scope.

Remember!

Once you move your DNS server into the jail, update your DHCP configuration to let your clients know about that new DNS server.

Website Pin Facebook Twitter Myspace Friendfeed Technorati del.icio.us Digg Google StumbleUpon Premium Responsive

Leave a Comment

Scroll to Top