9

I want to know how to create (if possible) a bash script that runs as root on Debian regardless of the user that executes it, without asking for any kind of authentication.

This file will run all its commands as it were the root user, but only the real root user will be able to read it or write on it.

I need this because I want to run commands like swapoff, swapon, apt, etc... But through another application, and I want it to not ask me any password.

The commands will be fixed (those root commands will have their parameters in the file, not as input), so security implications are not exactly my preoccupation, but I accept explanations as well.

terdon
  • 242,166
DATALOT
  • 457
  • 1
    Most likely related: https://unix.stackexchange.com/questions/364/allow-setuid-on-shell-scripts – Panki Nov 06 '20 at 14:41
  • fakeroot could perhaps help here. The idea of file permissions is for this question to have the answer "obviously not". – Vorac Nov 12 '20 at 15:29

3 Answers3

10

The low-level way to have a program always run under a particular UID, is the setuid bit on the binary file. That's how e.g. sudo and su get their root permissions, even if they're usually started by normal uses. But in general, Unix-like systems don't support setuid scripts, see: Allow setuid on shell scripts

However, what you can do, is to configure sudo or some other such tool to allow the users to run some particular files with the appropriate privileges. E.g., this would allow a user named viceadmin to run /usr/local/bin/sudoswapon with any arguments, and without authentication:

viceadmin ALL = NOPASSWD:/usr/local/bin/sudoswapon

Now, since sudo deals with changing privileges itself, sudoswapon can be a shell script.

You're right to note that the script would need to be careful with how it deals with command line arguments, and that all the gotchas of the shell language will apply. Luckily, sudo filters out most environment variables, at least if the env_reset option is set.

ilkkachu
  • 138,973
10

You cannot make a bash script that runs setuid. However, you can make use of sudo (or similar programs, like calife) to ensure they are run with root privileges.

There are two basic approaches to do this.

Lets suppose your script is called reset-swap and does:

#!/bin/sh
swapoff /dev/sdb
shred -n0 -z /dev/sdb
mkswap /dev/sdb
swapon /dev/sdb

Option A: would be to let any user to run these individual commands, and prefix them with sudo:

#!/bin/sh
sudo swapoff /dev/sdb
sudo shred -n0 -z /dev/sdb
sudo mkswap /dev/sdb
sudo swapon /dev/sdb

and add on /etc/sudoers a series of lines which let everyone do that:

ALL     ALL = NOPASSWD: /sbin/swapoff /dev/sdb
ALL     ALL = NOPASSWD: shred -n0 -z /dev/sdb
ALL     ALL = NOPASSWD: mkswap /dev/sdb
ALL     ALL = NOPASSWD: swapon /dev/sdb

However, while the actions specified may be safe to be done by everyone as done by the script, it might not be so independently. For example mkswap checks that the swap partition is not mounted before processing it, but shred would happily wipe a mounted swap partition.

Thus, it would be preferable to use

Option B: let only that script to be run with sudo.

ALL     ALL = NOPASSWD: /usr/local/bin/reset-swap

You would then call it as sudo reset-swap rather than reset-swap. If you get fancy, the script could elevate itself if it wasn't run as root, letting it be run without specifying the sudo prefix:

#!/bin/sh
if [ "`id -u`" -ne 0 ]; then
 echo "Switching from `id -un` to root"
 exec sudo "$0"
 exit 99
fi

swapoff /dev/sdb shred -n0 -z /dev/sdb mkswap /dev/sdb swapon /dev/sdb

Last, let me finish with a couple of points from the sudo lecture: Think before you type, With great power comes great responsibility.

Ángel
  • 3,589
2

It was realized long ago that setuid scripts presented insurmountable security problems (they're easily subverted by fooling with IFS), so we don't do that anymore. Linux has been changed to help us avoid setuid scripts.

You can achieve your desires with sudo, using NOPASSWD. Read man sudoers sudo.

waltinator
  • 4,865