New Year, New sudo: using systemd's run0 as a sudo replacement
Introduction
systemd 256 introduced run0. It isn’t a new tool per se, but rather a symbolic link to systemd-run that changes its behavior to run commands as root, similar to sudo. Some of the motivations to replace sudo with run0 are:
run0doesn’t rely on the setuid bit.run0uses Polkit for authorization and privilege management.run0can be used to run commands in a more controlled environment, with better isolation and resource management.run0automatically integrates with D-Bus when running as a different user, making it easier to run commands that require D-Bus access (No more “Failed to connect to bus: No such file or directory” messages!).run0can be used to run commands in transient systemd services, which can be useful for running long-running commands or services.run0uses systemd’s logging capabilities natively.- By default,
run0has a very cool red background color in the terminal to indicate that you are running a command as root! (take that, sudo!) /s
… and others.
I want to make a special mention to Luca Boccassi (bluca) who has been involved on many improvements to run0 and Polkit, big kudos to him for that!
Configuration
To use run0, you need to have systemd 256 or later installed on your system. After that, you may want to add some Polkit rules to make the experience smoother, similar to what you would do for sudo.
Password-based authentication with password caching
Create a file named /etc/polkit-1/rules.d/90-run0-password-caching.rules with the following content:
1
2
3
4
5
6
/* Allow password-based authentication for run0 with caching like sudo */
polkit.addRule(function(action, subject) {
if (action.id == "org.freedesktop.systemd1.manage-units") {
return polkit.Result.AUTH_ADMIN_KEEP;
}
});
Notes:
- This requires polkit 127 or later to work. See the commit that introduced this feature.
- The default timeout for password caching is 5 minutes. You can change it by setting the
ExpirationSecondsoption in the[Polkitd]section ofpolkitd.conf. See the polkitd.conf manpage and the pull request that introduced this option for more details. Requires polkit 127 or later.
Allow users in the wheel group to use run0 without a password
Create a file named /etc/polkit-1/rules.d/90-run0-wheel-nopasswd.rules with the following content:
1
2
3
4
5
6
7
/* Allow members of the wheel group to use run0 without a password */
polkit.addRule(function(action, subject) {
if (action.id == "org.freedesktop.systemd1.manage-units" &&
subject.isInGroup("wheel")) {
return polkit.Result.YES;
}
});
Allow specific users to use run0 without a password
Create a file named /etc/polkit-1/rules.d/90-run0-specific-users-nopasswd.rules with the following content, replacing username1 and username2 with the actual usernames:
1
2
3
4
5
6
7
8
/* Allow specific users to use run0 without a password */
polkit.addRule(function(action, subject) {
var allowedUsers = ["username1", "username2"];
if (action.id == "org.freedesktop.systemd1.manage-units" &&
allowedUsers.indexOf(subject.user) >= 0) {
return polkit.Result.YES;
}
});
Aliasing run0
To make it easier to use run0, you can create an alias in your shell configuration file (e.g., .bashrc, .zshrc, etc.):
1
alias sudo='run0'
This way, you can use sudo as you normally would, but it will actually use run0 under the hood.
Usage
Using run0 is very similar to using sudo. Here are some examples:
1
2
3
4
5
6
7
8
9
10
# Open a root shell
run0
# Run a command as root
run0 pacman -Syu
# Run a command as another user (e.g., 'postgres')
run0 -u postgres psql
# Run a command in a transient systemd service
run0 --unit=my-service --description="My Service" sleep 3600 # You can systemctl status my-service.service
# Run a command with a specific amount of memory, CPU, and other resource limits
run0 --property=MemoryMax=500M --property=CPUQuota=50% my-command # Note that run0 inherits resource limits from the parent slice, if you want more control, use systemd-run directly.
Conclusion
run0 is a great replacement for sudo, especially for those who want to avoid the security risks associated with setuid binaries. It leverages systemd and Polkit to provide a more secure and flexible way to run commands as root or other users. If you are a systemd lover like me, I highly recommend giving run0 a try in your workflow!
