Sandboxing is a software management strategy that isolates applications from critical system resources and other programs. It provides an extra layer of security that prevents malware or harmful applications from negatively affecting your system.
Here at Ibmi Media, as part of our Server Management Services, we regularly help our Customers to perform Systemd tasks on Linux.
In this context, we will look into how to use systemd’s sandboxing techniques on Ubuntu 20.04 for an efficient workflow to implement and to test these techniques.
Sandboxing is used for isolating a program or process from parts of a system that are not needed during normal operations.
When a new program runs it will have all the privileges that the user has. These privileges are usually much more than the program needs to perform its function.
This can cause security issues if anyone manipulates the program to access some of its unused privileges to do something unusual than the program usually does.
With the help of sandboxing, we can fix this since it allows the programs to use only the required privileges and thus not allowing them to access all the privileges a user has.
Here, we will be using systemd here as it has many sandboxing options to restrict the process from accessing the host system unnecessarily.
This will make the server more secure. Here we will discuss the steps to sandbox processes on Ubuntu 20.04.
1. Installing lighttpd
We will sandbox the lighttpd web server as it is a small program with a single function that is easy to the sandbox.
It can be installed using the following commands:
$ sudo apt update
$ sudo apt install lighttpd
This installation will automatically install and enable a systemd service file for lighttpd and will make lighttpd start on a system reboot.
2. How to use Systemd to sandbox processes on Ubuntu
As we know systemd uses service files to define how to manage a process.
i. The following command will show you the location of the active service file and display any overrides that are in use:
$ sudo systemctl cat lighttpd.service
ii. We will receive an output of the following form:
# /lib/systemd/system/lighttpd.service
[Unit]
Description=Lighttpd Daemon
After=network-online.target
[Service]
Type=simple
PIDFile=/run/lighttpd.pid
ExecStartPre=/usr/sbin/lighttpd -tt -f /etc/lighttpd/lighttpd.conf
ExecStart=/usr/sbin/lighttpd -D -f /etc/lighttpd/lighttpd.conf
ExecReload=/bin/kill -USR1 $MAINPID
Restart=on-failure
[Install]
WantedBy=multi-user.target
iii. We will use overrides to sandbox lighttpd with a dedicated override file.
Override files are located at /etc/systemd/system/process.service.d/override.conf.
systemd has a dedicated edit command that will create an override file at the correct location. And this will run systemctl daemon-reload after saving and exiting the editor.
iv. The systemctl daemon-reload instructs systemd to use any new configuration you wrote.
Comand that is used for editing is given below:
$ sudo systemctl edit process.service
v. During sandboxing, we will make many changes that break the process we are trying to sandbox. So we will open a second terminal and dedicate it to following the system log.
Use the following command in the new terminal.
$ sudo journalctl -f -u process.service
vi. To print only lighttpd’s errors use the following command:
$ sudo journalctl -f -u lighttpd.service
3. Creation of User and Group
We will set the non-root user that lighttpd will run as.
By default configuration, lighttpd starts running as the root user and then changes to the www-data user and group.
And running as root it can do anything that root can do.
systemd provides the ability to start and run the process as a non-root user to fix this problem.
i. In the first terminal session run the following command:
$ sudo -E systemctl edit lighttpd.service
And add the following lines:
[Service]
User=www-data
Group=www-data
ii. Next, we can save and exit the editor.
iii. Finally, restart lighttpd with the following command:
$ sudo systemctl restart lighttpd.service
We will see that lighttpd will not be able to start because it was using the root authority to write a PID file to a location owned by root.
From the system log in the other terminal session we will be able to see the following:
journalctl error message
Oct 29 11:37:35 systemd lighttpd[7097]: 2020-10-29 11:37:35: (server.c.1233) opening pid-file failed: /run/lighttpd.pid Permission denied
iv. The next step is managing PID to sandbox processes on Ubuntu.
3. Managing the PID File
We found that lighttpd was unable to write its PID file to /run/lighttpd.pid as /run/ belongs to root.
systemd uses RuntimeDirectory option to give lighttpd a location to write its PID file to.
The RuntimeDirectory option allows specifying a directory under /run/ that can be created by the user and group we set when systemd starts lighttpd.
After this lighttpd will be able to write its PID into this directory without root permission.
i. First, open and edit the override file with the following command:
$ sudo -E systemctl edit lighttpd.service
ii. And then add the following line under the two lines that we already added to the override file:
RuntimeDirectory=lighttpd
iii. Save and exit.
iv. Now we need to configure lighttpd to write its PID file into the new directory /run/lighttpd/ instead of /run/.
Open lighttpd’s configuration file with a text editor:
$ sudo nano /etc/lighttpd/lighttpd.conf
And change the following line:
server.pid-file = "/run/lighttpd.pid"
To:
server.pid-file = "/run/lighttpd/lighttpd.pid"
v. Save and exit the editor.
vi. Now, restart lighttpd:
$ sudo systemctl restart lighttpd.service
We can see that the service is still not active and running. To fix this we will go to the next step of providing proper privileges.
5. Obtaining Capabilities for User from Root.
From the logs, in the other terminal, we will be able to see the following error.
journalctl error message
Oct 29 12:07:22 systemd lighttpd[7220]: 2020-10-29 12:07:22: (network.c.311) can't bind to socket: 0.0.0.0:80 Permission denied
The issue is resolved by giving the lighttpd process a small part of the root’s privilege to open ports below 1024.
The systemd option to give a process one or more of root’s capabilities is using the AmbientCapabilities.
i. First, open the override file:
$ sudo -E systemctl edit lighttpd.service
ii. Then add the following line under the lines you already added:
AmbientCapabilities=CAP_NET_BIND_SERVICE
The CAP_NET_BIND_SERVICE capability allows a process to open ports under 1024.
iii. Save and exit the file.
lighttpd will be started now.
In the next step, we will restrict lighttpd to access the whole file system unnecessarily in order to sandbox processes on Ubuntu.
6. Locking Down the Filesystem
The lighttpd process runs as a ‘www-data’ user and can access any file on the system that www-data has permission to read and write to.
i. The first and easiest sandbox setting is the ProtectHome option.
This option stops the process from reading or writing to anything under /home/.
lighttpd does not need access to anything under /home/ so we can protect all other private files without affecting Lighttpd.
ii. First, open the override file:
$ sudo -E systemctl edit lighttpd.service
iii. And add the following line at the bottom of the file:
ProtectHome=true
iv. Save and exit.
v. Finally, restart lighttpd with the following command:
$ sudo systemctl restart lighttpd.service
Now we have protected /home/, but that still leaves the rest of the file system.
We can use the ProtectSystem option, which stops a process from writing to parts of the file system.
The ProtectSystem option has three settings that offer increasing levels of protection.
They are as follows:
1. true: Sets the following directories to read only:
/usr/
/boot/
/efi/
2. full: Sets the following directories to read only:
/usr/
/boot/
/efi/
/etc/
3. strict: Sets the following directories to read only:
Entire file system
For a higher level of protection we can set the ProtectSystem option to strict by adding the following line to the override file:
ProtectSystem=strict
Save and exit.
Using the below command we can make a few more changes:
$ sudo -E systemctl edit lighttpd.service
The lighttpd log directory is /var/log/lighttpd/ so we need to add the following line to the bottom of the override file:
LogsDirectory=lighttpd
Save and exit the editor and restart lighttpd.
This article will guide you how to #Sandbox #Processes on Ubuntu 20.04 with Systemd for Lighttpd using different methods. Here we made the #lighttpd program more secure by using the #systemd sandboxing options. You can use these techniques with any process that systemd manages allowing you to continue to improve the #security of your system.
#Sandboxing is designed to prevent #threats from getting on the #network and is frequently used to inspect untested or untrusted code.