« Back to systemd

Run0: introduction and usage

Introduction

Run0 was introduced in systemd version 256 and is intended as an alternative to sudo. Both commands elevate privileges, but are also somewhat different. Author Lennart Poettering describes run0 as somewhat more similar to the ssh command than it is to sudo.

Basics

When you use run0, it will create a transient service unit. Opposed to a permanent service unit that will run for a long time, transient units typically run very shortly. It can be compared with a towel versus a disposable paper towel. When the task is completed or you switched back to an unprivileged user, the service unit will be gone.

Differences with sudo

  • Run0 uses isolated services (transient units). Almost no execution or security context credentials are transferred into this new service.
  • Run0 allocates a pseudo-tty, further isolating the unit.
  • When possible, the authentication prompt is isolated from the terminal. This is done via polkit authentication.
  • SetUID and SetGID file access bit are not used.
  • No configuration file like /etc/sudoers.

Usage and basic options

Like most tools, run0 comes with a range of options. Here are some of the basic ones that you probably will use.

OptionAction
--background=[COLOR]Set background color, or disable when set empty value
--chdir=PATHSet current working directory to PATH
--description="TEXT"Give the transient unit a custom description
--nice=VALUEDefine nice level (19 to -20)
--property=NAME=VALUESet property (e.g. sandboxing/resource limitation)
--setenv=ENV=VALUEDeclare an environment variable ENV with value VALUE
--unit=NAMEDefine a name of our transient unit instead of random one

Let’s have a look at how to use run0 and apply these options.

Become root user

To elevate permissions without running a specific command, run run0 without any parameters.

run0

Background color

You may notice that the background color changed, one of the features of run0. Don’t like this color? Let’s use a blue background instead of red.

run0 --background=44 ps -ef

Use a blue background with bold characters. Use quotes when using the semicolon character.

run0 --background="44;1" ps -ef

Not interested in a background color at all? Give it an empty value.

run0 --background= ps -ef

Unit and description

When we run a command with run0, it will be assigned a new service unit. This is called an transient unit, one of a short duration. The name that is assigned is somewhat random, something like ‘run-u302’. By using the option --unit= we can give it a custom name. Additionally, we can provide a description as well.

By defining a clear name to the unit, it can easily be monitored. Let’s fire up a new task and look at the status of our new service unit.

$ run0 --nice=19 --unit=slowcopy --description="This is a copy task" systemctl status slowcopy.service           
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ====
Authentication is required to manage system services or other units.
Authenticating as: Michael (michael)
Password: 
==== AUTHENTICATION COMPLETE ====
● slowcopy.service - This is a copy task
     Loaded: loaded (/run/systemd/transient/slowcopy.service; transient)
  Transient: yes
     Active: active (running) since Wed 2024-06-19 10:33:39 CEST; 4ms ago
 Invocation: 1e903a4c842c453dba816188f65ca8d6
   Main PID: 4804 (systemctl)
      Tasks: 2 (limit: 4671)
     Memory: 1.5M (peak: 1.5M)
        CPU: 6ms
     CGroup: /user.slice/slowcopy.service
             ├─4804 /usr/bin/systemctl status slowcopy.service
             └─4805 less

Change work directory

The work directory defaults to the home directory of the user. To adjust this, use --chdir= followed by the work directory.

run0 --chdir=/var pwd

Nice level

Run0 allows to run a task with elevated privileges and directly an assignment of the nice level. This is very useful for longer running tasks like a file copy. This way it won’t impact the production system too much.

run --nice=19 my-task-with-low-priority

Environment variables

If you need to provide an environment variable, then this can be done using --setenv= followed by the variable and its value. To test that it is really available, let’s display the environment variables from within the newly created service.

run --setenv=SECRET=true bash -c 'export'

Sandboxing capabilities with properties

One of the most powerful features with run0 is to set a property. A property defines one or more aspects of the environment that processes are running in. To see available properties, use the show subcommand of systemctl.

systemctl show dmesg.service

Defining a property within run0 is an interesting combination. So even though you elevate privileges, you can still define restrictions and sandbox the command or application.

Example

Let’s say you created a new shell script to automate an important system task. While it may need root privileges to run and interact with other commands, the script should not be able to wreck the system. One option is to use the ProtectSystem setting, which can mark the file system as read-only.

Let’s run a simple task to write a string of text into a file.

$ run0 --property=ProtectSystem=strict bash -c 'echo test > /var/log/write-test'
/usr/bin/bash: line 1: /var/log/write-test: Read-only file system

So even though we run0 will give us root permissions, we are not allowed to write to a new file in our /var/log directory. But what if exactly that directory is what our script requires as part of its tasks? No problem, just set a second property that grants us write permission for that particular location.

run0 --property=ProtectSystem=strict --property=ReadWritePaths=/var/log/write-test bash -c 'echo test > /var/log/write-test'

Now our file can be created, exactly as we intended. Testing a new script that requires root permissions has become a lot safer!

Learn more about run0

This article uses the run0 command to achieve its tasks. For this popular tool there is a cheat sheet available!

» Mastering the tool: run0

run0 cheat sheet

Feedback

Small picture of Michael Boelen

This article has been written by our Linux security expert Michael Boelen. With focus on creating high-quality articles and relevant examples, he wants to improve the field of Linux security. No more web full of copy-pasted blog posts.

Discovered outdated information or have a question? Share your thoughts. Thanks for your contribution!

Mastodon icon