# Jails: confining the omnipotent root

08 Jan 2018 | | theory, jails, freebsd, container

### Preamble

Recently I became nostalgic and fascinated with stuff from the past, so I decided to create a Vagrantfile to work with FreeBSD1. Why FreeBSD? Because as a developer, I really like Docker and I started looking in the past to find its historical birth: in fact, as a concept, Docker is no so recent as you think, and I think it exists also because of the works of some other bigs from 80’, such as Poul-Henning Kamp2. Starting from its work and using a FreeBSD installation I did some experiments with jails, to understand better what they really are, how they works - how can you create what it will look like a vintage container - and why you should use them in a FreeBSD environment - at least, to learn something new.

### Introduction

As P.H. Kamp says in its work, FreeBSD’s jail facility provides the ability to partition the operating system environment, while maintaining the simplicity of the UNIX root model. I think its work is really clear, and I would like to follow logic steps behind its reasoning, but…wait: let’s start from the problem.

The traditional UNIX access model assigns numeric uids to each user of the system. For the purposes of human convenience, uid 0 is canonically allocated to the root user. The system can discover whether special privileges are accorded to a process simply by looking at the uid of the process: if it is equal to 0, then the process is acting with super-user privileges. It’s really simple, but there are a few problems.

Formally, let:

• $\{root, u_1, u_2\} \in \cal U$ be respectively the root ($uid \; = \; 0$), and two common users $\{uids \; = \; 1,2\}$ from the set of users $\cal U$;
• $\{p_1, p_2, p_3, p_4\} \in \cal P \in \cal O$ be four different privileged operations from the subset of privileged operations $\cal P$ included in the set of all available operations $\cal O$;
• $G \; = \; \{V, E\}$ be a graph of dependencies between operations, with $V = \cal U$ and $E = \{p_1 \rightarrow p_3, p_2 \rightarrow p_3, ...\}$;

It’s easy to imagine how this scenario could collapse into a difficult dependencies graph that doesn’t let the system to be secure at all. In particular, $G$ itself says that many privileged operations in UNIX - even if seem independent - actually are not: instead, they are closely related and the handing out of one privilege may, in effect, be transitive to the many others. Let assume that users $u_1$ and $u_2$ have to be able to do $p_1$ and $p_2$, but no $p_3$: then you can permit both to be root enabling them doing whetever they want - of course including $p_3$, but also other $p_s$ you want to disable for both the users. What does it means? It means that, if you have to assign different permits over the same operating system - some securelevel mechanism has to be implemented which allows the administrator to block certain configuration and management functions from being performed by root.

However, a system root-dependent is not a good idea, because if the root user is compromised, you’re f***d up, and second, having a single administrative account is not a good idea, even in the simplest environment. There are some features in BSD system that provides - let me say - security capabilities: for instance, the single-user mode available to block certain functions until reboot. This is a great functionality but, it’s not a solution yet to separate several root abilities. A simplest solution should be introducing new security features to split privileged operations, but this often involves introducing new security management APIs. Further, if we assume to introduce fine-grained capabilities to replace the setuid mechanism in UNIX-like operating systems, applications that previously did a check to see if they were running as root before executing must now be changed to know that they need not run as root. This is not a real solution.

#### chroot

The chroot utility can be used to change the root directory of a set of processes, creating a safe and separate environment from the rest of the system: processes created in the chroot environment can not access files or resources out of this: ok, but I think jails improve the concept of the traditional chroot environment in many ways. In a traditional chroot environment, processes are limited only to the portion of file systems that can be accessed. The rest of system resources (such as the set of system users, running processes, or network sub-system) are shared by chrooted processes and host system processes (those not in a chroot environment). The jails expand this model by virtualizing not only the file system access, but also the set of users, the FreeBSD kernel network sub-system and some other things.

### jail

A jail is characterized by four elements:

• A sub-branch of a directory: the starting point from which you enter the jail. Once inside the jail, a process is not allowed to exit this sub-branch. The traditional security issues affecting the original chroot (2) design do not affect FreeBSD jails.

• A hostname: the hostname that will be used inside the jail. Jails are mainly used to host network services, so having a descriptive host name for each jail can really help the system administrator.

• An IP address: this will be assigned to the jail and can not be changed in any way during the life of the jail. The IP address of a jail is usually an alias address of an existing network interface, although this is not strictly necessary.

• A command: the path to an executable to start inside the jail. This is relative to the root directory of the jail environment, and can vary a lot, depending on the specific type of jail environment.

Jail permits to partition a FreeBSD environment (processes, file system, network resources) into a management environment, and optionally subset Jail environments. The administrator of a FreeBSD machine can partition the machine into separate jail and provide access to the super-user account in each of these without losing control of the over-all environment.

Looking for informations about how jails really work, I discovered that jails are foundamentally of two types: the “complete” jails, which resemble a real FreeBSD system, and the “service” ones, dedicated to one application or service, possibly running with privileges. Let’s make an example of how you can create a jail.

#### Instructions

First, Vagrantfile and vagrant ssh your FreeBSD machine

##### Create the environment

Where:

• setenv DESTINATION /path/to/jail sets an environment variable to specify jail location - where the jail is physically in the host file system. A good practise is to put your jails under /usr, better if in a jails dedicated subfolder: for instance, /usr/jail/mark where mark is the name of the jail;
• mkdir -p $DESTINATION creates the directory tree including intermediates one if required; • cd /usr/src changes the folder to the place in which the source code is normally installed - which contains the several subdirectories, including the sys one that contains Kernel source files; • make buildworld && make kernel creates the world and compiles the kernel source: this will take a loooooong time3, but, using the -j - only in the first make - you can increase speed by running multiple jobs. How many jobs to use depends on the processor (number of cores plus one is a start). The kernel target builds and installs the new kernel; • make installworld DESTDIR=$DESTINATION populates the directory subtree chosen with the necessary binaries, libraries, man pages, etc

##### Listing jails

Using jls you can list the jails in your host. jexec 3 /etc/rc.shutdown

NOTE: you can also shotdown a jail using the jexec command: look at the JID’s jail you want to stop using the listing command jls, then run jexec 3 /etc/rc.shutdown

If you to find out more about how the jail mechanism is implemented, you can have a look at this files4 /usr/src/usr.sbin/jail/jail.c, /usr/src/sys/kern/kern_jail. and /usr/include/sys/jail.h header file: in the latter is defined the jail structure, there is an entry for each of the arguments passed to the jail command, and indeed, they are set during its execution.

### Conclusion

The jail facility provides FreeBSD with a conceptually simple security partitioning mechanism, allowing the delegation of administrative rights within virtual machine partitions. The implementation relies on restricting access within the jail environment to a well-defined subset of the overall host environment. This includes limiting interaction between processes, and to files, network resources, and privileged operations. Administrative overhead is reduced through avoiding fine-grained access control mechanisms, and maintaining a consistent administrative interface across partitions and the host environment. So…does it seem familiar?

If something is wrong, please let me know, I’m still waiting for the world to be built -.-

PS: this is the part where you realize that a jail is similar to a container, the jail.conf is kind of a Dockerfile but - wait for it - could be so much more, like a docker compose: further, jexec looks like the docker exec command, and jls looks like docker ps -a, and so on, am I wrong?

1. In this short thread, you can see some order of magnitude: buildworld takes hours so…be patient.

2. More at freebsd.org

## A journey through the network - Layer 1

### A journey through the network - Layer 1

Before the Christmas holidays, I wrote an article about the network: yes. The network is that part of computer science that is no longer considered fundamental as it should, and I must admit that I learn it every day at my expense: as an old friend always says to me “the network is the concept on which everything is based, describes how the body works: after that, you can also become a gastroenterologist, but you will always need to know how the body works”. I think he’s right. As I was saying, I wrote an article about that: it’s a sort of overview and technical / historical introduction on the ISO / OSI and TCP / IP protocols. For those who missed the introduction, here the link. Despite my lack of experience, I promised myself, as far as possible, with the little time available, to retrace the various levels of the network from a theoretical point of view without going into too much detail, also trying to identify the most used commands, understand the level at which they operate and the functioning of the parameters supported by them. It took me a lot of time … but finally, the post on level one is ready. As a main source I use Computer Networks and TCP/IP Illustrated. In this article, I will talk about layer 0, the lowest in the ISO / OSI stack. Enjoy the reading!