4

I run a small group of macOS machines for students (say 20) and they all need to be setup with things like homebrew and other packages and applications. I'm writing a bash script to automatically install all the things needed on each computer. Some of the commands I'll be using require being run as root, but not most of them.

I was wondering if it would be better to individually sudo each of these commands in the script, or leave sudo out of the script and sudo the entire script. I'd like to know which one will be safer (security wise), and better for my situation. I'd rather not be prompted for a password throughout the script, but I also dont want to run every line in the script as root, as it's unsafe.

6

Following the principle of least privilege, run as little as you can as root. Therefore, sudo from within the script.

Note that the first time there is a command that needs sudo, you may be prompted. (That won't be true if you applicably use NOPASSWD in /etc/sudoers which is a technique that many people will shun as also being insecure.) However, when you run sudo and provide a password, sudo will remember the success for a period of time. By default that period of time is five minutes. So if you ran "sudo echo hi", typed in your password, and then ran the script soon after that, then there would be no need for you to be prompted for a password when you run the script. More realistically, if you just run the script, you will likely just be asked to sudo once... presuming that you script takes less than give minutes to complete the remaining tasks.

I might not worry about a few echo commands, but if there is significant content that can be done without extra permissions, then, for the sake of security, I generally like to maximize how much is done with minimal elevation.

As an example of minimizing permissions, let me show you another sample scenario. Instead of:
sudo -c "sample-command >> /var/log/output.txt"

I like to use:
sample-command | sudo tee -a /var/log/output.txt >> /dev/null

By doing this, the entire command runs without sudo, and the only part that ends up having enhanced permissions is the part that needs enhanced permissions, which is the part that writes to the file.

Clearly, my goal here is to minimize how much is done elevated. Similarly, if your entire script doesn't require elevation, the preferred approach (from a security perspective) is to minimize how much is done elevated.

  • Welcome, 10k ;-) – Arjan Jan 19 '18 at 7:57
  • @TOOGAM Could you do the same thing without using tee like this instead? sample-command | sudo cat >> /var/log/output.txt Or is there a difference? – adjenks Sep 24 '18 at 2:14
  • Hmm, I see, cat does not work... – adjenks Sep 24 '18 at 2:25
  • @adjenks : right. In your example, the shell realizes there is a pipe and a redirection. sample-command runs at the same time as the second thing it runs, which is "sudo cat" (the part between the pipe and the >>). Then the output of that will get redirected using the initial user account that ran the command. To handle this situation, you can place the >> inside quotes that cause >> to just be part of a single argument, as shown in the answer (where I mentioned sudo -c), or, better yet, become practiced with using tee as described by my answer. – TOOGAM Nov 17 '18 at 2:26
0

Depends on what the commands are. For the command that download from the internet it’s better to not run them as root. But the other command should be ok to run as root. What I would do is separate the command in two scripts: one for non-root commands and one for root commands

Maybe I could help more if I can get the list of the commands.

  • zerobin.net/… – James C. Oct 2 '17 at 21:00
  • woops, mispelled firefox, hopefully you get the idea – James C. Oct 2 '17 at 21:01
  • Is the script in order? – Patrick inc Oct 3 '17 at 17:09
  • "For the command that download from the internet it’s better to not run them as root" - it's best NOT to run them at all, just pasting & running random commands is a terrible idea in general. At least look up their man pages and understand what you're trying to do first, then run only if it looks safe. – Xen2050 Mar 1 at 2:59
0

Usually, (I assume) you would want the script to be treated just like any other command/application/utility. In which case, you typically wouldn't be prompted for a password to escalate your privileges; you'd just be denied, and receive an error. Something like:
Permission denied, or Operation not permitted.

But, you specifically mentioned that you:
"..don't want to run every line in the script as root.."
So I don't really see an alternative to explicitly, and exclusively invoking sudo in / from the specific lines of code where it's relevant.

You also mentioned that you'd:
"..rather not be prompted for a password throughout the script.."
And chances are you won't. You won't be prompted every time sudo is invoked unless a significant amount of time passes between operations.

0

I have used this throughout my scripts when I wanted just some commands to be executed as root and others not

echo $admpass | sudo -S *COMMAND*
  • It's a very bad idea to store passwords in the shell script directly. This is reasonable if and only if $admpass came from user input. – Duncan X Simpson Jun 14 '18 at 17:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.