3

I often set my work computer running some time-consuming computations before I go home in the evening. After they're done, I'd like it to shutdown. However, as shutdown requires root privileges, it must be executed using sudo. Obviously I'm not there to enter my password 7 hours later, so thus far I've had to execute the entire list of commands (cmd1; cmd2; cmd3;... shutdown) as root - not ideal.

Is there a way I can "pre-authorise" the sudo at the end of a list of commands? Some way I can entire my password at the start of execution so bash doesn't need me later on?

Thanks!

  • How are you running these events? Can you sudo the thing that is running the events in the first place? You said you don't want to run the whole script as root does that also include running the whole script as sudo too? – Scott Chamberlain Sep 3 '13 at 17:15
  • 1
    Have you seen any answers that you would qualify as "Best" mate? One usually marks an answer as best in the question to help anyone else who has a similar problem. – PsychoData Sep 7 '13 at 20:29
5

To complete the first answer:

Set up a way that your non-privileged time-consuming computations can initiate the shutdown that’s waiting in the privileged shell (started by sudo -s or sudo su).  Using a file as a flag is a good, simple way of doing this.  So, in your non-privileged shell, do

cmd1; cmd2; cmd3; > ok_to_shutdown_now

and in your privileged shell, run a script that says

while [ ! -f ok_to_shutdown_now ]
do
        sleep 60
done
shutdown
  • This is the best solution IMHO. inotifywait may be used to wait for the ok_to_shut file to be created but for shutting down purpose this should be enough. – jaychris Sep 3 '13 at 21:11
  • I acknowledge this approach is faster to set up than mine. However, it does require running a privileged program for extended periods of time, which seems to be a less nice aspect to this approach. – TOOGAM Jan 15 '18 at 2:55
2

You have quite a few options here to reach your goal, depending on what you are willing to risk. Not all of them having to do with caching your sudo credentials.

You can switch off needing a password for your user or for your user executing shutdown by adding a line with the tag NOPASSWD to your sudoers file.

You can authenticate to sudo by running sudo -v. Your password will be cached for 15 minutes so you would have to run a sudo -v all, say, 12 minutes, to update your credentials and kill that task after the last batched process is done.

If you know how long your batched processes take, you can simply tell shutdown the time after which it shall shut down the system.

You can increase the default 15 minute timeout of the password cache with the option timestamp_timeout in the sudoers file. Either arbitrarily, or, if you know how long the batches processes take, to that time. Or you could switch off the timeout completely with a negative value and use sudo -v to authenticate and sudo -k to "log out" of sudo when you are done. In between these two calls, you can run sudo without entering your password again.

If you are not fine with not requiring a password for sudo, but instead store your password in a text file, readable only by your user, then you can create a little batch script which outputs your password to stdout and either use this as the askpass program for sudo or simply use it in a pipe with sudo -S, which read the password from stdin. Combined with a little script you could store your password in a text file at the beginning, from which it is read by the script providing it to sudo and at the end delete this file again.

Echo script

#!/bin/bash
echo mypassword

or

#!/bin/bash
cat /mysecretpwfile

and then ./echopw | sudo -S or

export ASKPASS=~/echopw
sudo -A shutdown -h now

Or, at last, you could simply put the shutdown command in a shell script and set the shell script to suid, owner root, your group, 750.

1

You can run commands in a root environment so that you enter in your password once when you are at the computer and then run root commands after without entering your password.

You can use

   sudo -s

or

   sudo su

(Read here for the difference)

This will give you root privileges and stop you from entering your password in again. Then, you can run sudo commands after this and they will not prompt you for a password.

1

you could

sudo sh -c 'cmd1; cmd2; cmd3;... shutdown'

or give your userid privilege to sudo shutdown without a password. There is an example just for this here: Shutting down without root

  • I'd go for the sudoers config. That file is quite long; the relevant example is in the section headlined "Shutting Down From The Console Without A Password" – rici Sep 3 '13 at 23:32
1

A better way...

Yes, there is a better way to do this. Make it so that shutting down does not require superuser privileges.

This requires a bit of setup in advance. Then it minimizes who can perform the privileged action, and just what can be accomplished by a person who uses that method. (In other words, potential abuse of the power is constrained by some other limits that exist.)

I am presuming installation of some common software, including sudo (seems like a safe presumption, considering the question), and OpenSSH (or, probably more likely, "OpenSSH Portable").

Create a user account

Since you seem to have sudo access, I presume you probably have the ability to create a user.

You may want to call the user _sysstop, or _sysoff, etc. Although "shutdown" is eight characters or less, that is also the name of a command to run, so using a different name may be nice. I also like the standard of starting entirely automated accounts, like this one, with an underscore, just so that visually this account ends up looking different than a standard user account.

Let user shut down without password

Modify /etc/sudoers, and insert this:

_sysstop ALL=(ALL) NOPASSWD:/sbin/shutdown -h*, SETENV: ALL

Naturally, you may want to customize that first part, which is the name of the user account you created.

A lot of people seem to oppose using NOPASSWD, probably because they don't like the idea of giving full access to do anything on the system. However, this is giving rather restricted access. The only thing that this person is going to be able to do is to run a command that starts with "/sbin/shutdown -h", which will halt the system. If some unauthorized person manages to take advantage of that line without a password, they may be able to shut down the system, but that doesn't mean that such an attacker would be unrestricted in ability to do lots of other types of damage (like setting up additional user accounts, etc.) So, this usage of NOPASSWD is rather safe in contrast to what most people try to discourage.

The "/sbin/shutdown -h" is what I wanted to use. Depending on your operating system, and what you desire, you might want to use a different command, such as "halt" or "reboot", and may want different parameters. Since you're already practiced in shutting down the system the way you want it, then presumably you know already know how you want to be doing this.

Create an SSH key

ssh-keygen -t rsa -vvv -f mykey -N "" -C "mykey" | tee mykey.fng

Some people won't like -N "". Well, that is an entirely different discussion that I choose not to go into further here, beyond the rest of this statement: customize according to whatever security practices make you more comfortable.

There may be other changes, to the above example, that some people would recommend. Again, that may be excellent, but is a separate topic from the core of this answer. Customize the above however appropriate.

Notice the "mykey" shows up three times in the above example. You are absolutely welcome to customize the first example, and then the other occurrences are intended to match whatever the first occurrence says.

You don't need the mykey.fng file. I just got into the habit of preserving it so that I could have a record of the VisualHostKey (a.k.a. "random-art"), before I learned that such keys can be seen again later, e.g. "ssh-keygen -lvf /etc/ssh/ssh_host_ecdsa_key"

Restrict what can be done with the key

Modify the ~$( echo username-just-created )/.ssh/authorized_keys* file. (e.g., ~_sysstop/.ssh/authorized_keys although some systems might use ~_sysstop/.ssh/authorized_keys2, although you probably want to be using authorized_keys)

Implement the ssh key, by inserting a line that looks approximately like this in the file:

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAA... Optional-comment-after-the-space

For the "Optional-comment-after-the-space", I like to include the filename of the private key. If I ever want to add an additional key (which I might not for this particular type of user, but out of habit, some users may want additional keys), then the authorized_keys file may have lots of lines that are identifiable by the key's text. If I have multiple keys, and then months later want to remove one, I might have a hard time remembering which public key is related to which key file, and so I wouldn't know which public key to remove. By utilizing the optional comment, I can keep that of this better in the future.

Note: if you automatically add the key (perhaps with ssh-add), maybe you have a default comment that contains a username. Such comments are often pretty useless. Customize in a way that may be useful down the road.

Ensure ~/.ssh/authorized_keys has the needed permissions to make OpenSSH happy.

Test the single steps

Can you test this (by shutting down the system)? If so, doing that can test some components separately, which may allow you to have a more-narrowed-down problem if something is broken.

  • Test that the key is set up right.
    • On the client, use ssh -i ~/keys/privkey-file _sysstop@localhost
    • If you use PuTTY, PuTTY also supports -i filename (and -ssh), or use the GUI to specify the filename in Connection\SSH\auth (in the left frame of options), which you can only do on the "New Session" screen. (Specifically, I say "only" because the "auth" screen does not appear when trying to use PuTTY's "system menu" and using "Change session" on an existing session)
    • At this stage of the process, this should give you a shell. If not, you may need to adjust the implementation of using the SSH keys.
  • Once you are logged in, test that the sudo works (without a password) to shut down the system

Restrict the key

See the ~/.ssh/authorized_keys* file? Great. Now, modify it.

Find the line that starts with ssh-rsa

Insert some text before it, so that the line looks more like this:

command="sudo /sbin/shutdown -hp now Shutdown initiated with SSH by \\"$USER\\" CONN rem/lcl=\\"$SSH_CONNECTION\\" CLI rem/lcl=\\"$SSH_CLIENT\\" CMD=\\"$SSH_ORIGINAL_COMMAND\\"",no-agent-forwarding,no-port-forwarding,no-X11-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAA... Optional-comment-after-the-space

Result

Guard that private SSH key file. With it, anybody could shut down the system. However, that is really all they can do.

Now, shutting down the system simply requires running the unprivileged command "ssh", and access to that file. As long as you control access to that file, you're keeping things as secure as they need to be. However, even if the file does get compromised, the amount of damage that can be done is pretty limited.

Now you don't even need to type sudo when you want to shut down the system. You do need to make sure that nobody unauthorized gets that key (or else they could shut down the system). Presumably anybody who could use "sudo" to steal that file could also just use "sudo" to shut down the system, so in many cases, leaving the file in a private area of the computer is probably a relatively safe and reasonable risk.

-1

The easiest solution is probably storing the password in a variable and then later pipe it from this variable to sudo -S.

#!/bin/bash
echo "Please enter your password:"
read -s mypasswd

#additional stuff

echo $mypasswd | sudo -S shutdown -h now
  • -1 because: Bad bad bad. Do not echo the command. Some systems will create a log file of every command that is created. The password would also show up in "ps" (admittedly, pretty briefly). What I've read is that experts say this is actually much riskier than most people seem to give it credit for. (Much better is to find a way to get a password into a file, and then specify that file on the command line.) – TOOGAM Jan 15 '18 at 2:52
  • @TOOGAM Do you have any reference for systems that log every command called inside a bash script with variables resolved? I never heard of that. I know about ps, but am much more comfortable with that than writing the password into a file where other people could read it for a much longer time. Having the password in the logs would however be something that I would not like even on my home pc. – Tim Jan 15 '18 at 19:30

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.