Setting up the FreeBSD host system for Jails

From JonDonym Wiki
Jump to: navigation, search

JonDos GmbH thanks www.secure-internet.org for the right to publish the following article. We made some changes in it but the original text was provided by www.secure-internet.org

navigation: Main Page | FreeBSD and Jails

Preparing the FreeBSD host system for Jails

To prepare the machine for creating jails we now need to initiate the encryption of the partitions in which the jails will be "living". After this was done, we need to change some kernel settings.

Edit /boot/loader.conf

vi /boot/loader.conf

Enter a line there:

geom_eli_load="YES"

Save and close the file. This will load the kernel module needed for disc encryption with the next bootup. To avoid a reboot just to get the module loaded we can load it this time manually:

kldload /boot/kernel/geom_eli.ko

Check whether the module was loaded:

kldstat

Besides other modules, the GEOM GELI module should get displayed. The output should look similar to this example:

Id Refs Address    Size     Name
1   14 0xc0400000 9fab68   kernel
2    1 0xc0dfb000 111b8    geom_eli.ko
3    2 0xc0e0d000 25ff8    crypto.ko
4    2 0xc0e33000 ab40     zlib.ko
5    2 0xc0e3e000 36f44    pf.ko
6    1 0xc0e75000 be30     aio.ko
7    1 0xc0e81000 2bec     pflog.ko
8    1 0xc0e84000 6a45c    acpi.ko
9    1 0xc5a30000 22000    linux.ko
10    1 0xcccb3000 2000     accf_http.ko

Don't worry if you do not have all modules from the list above displayed. Just the GEOM GELI module needs to be present (line #2 in the example above).

Now check once more the /etc/fstab file. The entries for the two jail partitions MUST get commented out (made invalid) or get removed completely. Leaving the two lines in with comment signs („#“) in the first column just helps you to remember what partitions you in generally have on the system.

But remember: you cannot boot the system any more if you miss the comment signs. The boot process would get stuck and you then will be happy to ask your provider for a KVM to fix the issue in BSD's single user mode (where you have to deal with a line oriented editor to edit /etc/fstab) ;-)

To encrypt the SWAP partition when booting the next time you also need to edit the entry for the SWAP space in /etc/fstab. The entry for the SWAP space usually looks as follows:

/dev/ad4s1b            none            swap    sw              0       0

Change it to the version below meaning just add a dot and „eli“ to the device name:

/dev/ad4s1b.eli         none            swap    sw              0       0

Please note that the device name on your system will probably differ from the one in the example. But no matter what the device name is, just add „.eli“ to it.

Encrypting the SWAP space will NOT result in asking you for a passphrase during the boot process. You then still can boot without the need of access to the console.

Now edit the entry in /etc/fstab for the old /tmp directory (the one on the disc). Put a comment sign in the first column also here to make the line invalid. We already have another /tmp directory as memory disc and do not need the hard disc version of /tmp any more.

Save the /etc/fstab file and exit.

Next, we will initiate encryption on the two jail partitions.

To enter these two partitions after encryption one will need a keyfile (one for each partition) plus a passphrase (also one for each partition). It would be perfect if you would not need to have the two keyfiles for the two partitions residing on the hard disc. You might achieve this by some measures but for now we assume the keyfiles will be on the server's hard disc (while the passphrases still are stored in your head only).

At first we will create keyfiles. Change the directory to your home directory or another place suitable for you. You might hide the keyfiles at exotic places and give them filenames not remembering anybody that the file could be a keyfile. But of course those are not really security measures.

Create the keyfiles for the first and second partition by typing:

dd if=/dev/random of=/yourdirectory/yourkeyfilename1 bs=64 count=1
dd if=/dev/random of=/yourdirectory/yourkeyfilename2 bs=64 count=1

You might change the permissions of those files (chmod 400) but again, this, too, is not really a security measure. Best is, not to have the files on the server at all. Perfect is, to never have saved them to the server disc at all (because even then there is data from it left on the disc after deletion).

Now assign pass phrases to the partitions (you must type in a pass phrase for each):

geli init -s 4096 -K /yourdirectory/yourkeyfilename1 /dev/ad4s2d
geli init -s 4096 -K /yourdirectory/yourkeyfilename2 /dev/ad4s2e

Please note that the device names of the two partitions in the above example again are only examples. The device names on your system will probably differ.

Now assign the keyfiles to the partitions:

geli attach -k /yourdirectory/yourkeyfilename1 /dev/ad4s2d
geli attach -k /yourdirectory/yourkeyfilename2 /dev/ad4s2e

We are nearly done. The two partitions need newly created filesystems now:

newfs /dev/ad4s2d.eli
newfs /dev/ad4s2e.eli

Please note that now (since encryption is in effect) you need to use other device name versions. All device names now need to get used with a dot plus „eli“ added at their end.

And finally we mount the partitions (assuming /jails/mix1 and /jails/mix2 already exist as directories):

mount /dev/ad4s2d.eli /jails/mix1
mount /dev/ad4s2e.eli /jails/mix2

And now check whether the two partitions appear

df -H

The two partitions are now ready for use. Leave them in this state for now. The explanations below are just for later use.

Before we go ahead installing the jails on them here's again how you open up the partitions for use after booting the system and how to „close“ them again after usage (do not execute the following command lines now):

When you booted your machine you cannot access the partitions. That is why we wanted them as encrypted partitions.

After booting first enter

geli attach -k /yourdirectory/yourkeyfilename1 /dev/ad4s2d
geli attach -k /yourdirectory/yourkeyfilename2 /dev/ad4s2e

and answer the questions for the pass phrases.

Then mount the partitions

mount /dev/ad4s2d.eli /jails/mix1
mount /dev/ad4s2e.eli /jails/mix2

After usage first unmount the partitions:

umount /dev/ad4s2d.eli 
umount /dev/ad4s2e.eli 

Then separate the keys from the partitions:

geli detach ad4s2d.eli 
geli detach ad4s2e.eli 

Done. The secrets are secured again.

But we still leave the partitions „opened“ at this point since we soon will install the jail files on them.

Before we could go ahead installing the jails, some kernel settings need to be made now.

Edit /etc/sysctl.conf, the configuration file for system settings at boot time:

vi /etc/sysctl.conf

Add the following entries:

# jail regarded setting, non default
security.jail.set_hostname_allowed=0
security.jail.allow_raw_sockets=1
# jail regarded setting, default
security.jail.socket_unixiproute_only=1
security.jail.sysvipc_allowed=0
security.jail.enforce_statfs=2
security.jail.chflags_allowed=0
# blocking portscans
net.inet.tcp.blackhole=2
net.inet.udp.blackhole=1

Save and exit the file.

The jail related settings are to limit the jails options as far as possible. Through this measures, security can get increased. As an example, System V IPC memory data exchange is disabled for jails. A user in one jail cannot access memory data of another jail or of the host.

By the way, the latter two entries are not related to jails. They disable espionage through port scans from possible attackers.

The file entries in /etc/sysctl.conf will be in effect only from the next boot on. But rebooting is not strictly needed. We also can make the settings on the fly to have them in effect right now. Enter:

  1. sysctl security.jail.set_hostname_allowed=0
  2. sysctl security.jail.allow_raw_sockets=1
  3. sysctl security.jail.socket_unixiproute_only=1
  4. sysctl security.jail.sysvipc_allowed=0
  5. sysctl security.jail.enforce_statfs=2
  6. sysctl security.jail.chflags_allowed=0
  7. sysctl net.inet.tcp.blackhole=2
  8. sysctl net.inet.udp.blackhole=1

You sometimes may get displayed that a value has not been changed when entering the commands above because it already had been set to the required value. Doesn't matter. We, however, are sure that the values are set properly.

Personal tools