29

I have a raspi type device in a data center, and recently accidentally fat fingered and pasted a shutdown command into the wrong terminal on my screen. Is there a way to keep shutdown -r but remove #poweroff #shutdown -P -H options?

I want to keep shutdown -r command. I like to put a timer on it if I manage to freeze the system, or lock myself out with ip table rules. example shutdown -r +10

0

6 Answers 6

45

You should be using a systemd-based Linux distribution. In this case, you ought to be able to mask the poweroff target, so that systemd will refuse to execute it (and power off). e.g.:

systemctl mask poweroff.target

This makes it utterly impossible to shutdown the system, other than by rebooting. See that nothing happens:

Debian9 animated demo

In this case, this VM's virtual power switch doesn't even work to shutdown the system anymore. But it still reboots perfectly well.

To undo the change, of course, just unmask the target. Then you can shutdown the system.

systemctl unmask poweroff.target
4
  • 2
    Is there a systemd command which lists all services/targets/devices with their description (if available)? I've recently started reading up on this and would love to explore the possibilities.
    – hjpotter92
    Sep 4, 2018 at 10:24
  • 1
    @hjpotter92 Run systemctl with no arguments. It will list all active units, their status, and descriptions. Add --all and it will also list units which aren't active. Sep 4, 2018 at 12:05
  • 3
    @hjpotter92 Take a look at man systemd.special.
    – TooTea
    Sep 4, 2018 at 12:15
  • 1
    Masking poweroff.target for systemd-based distros is the correct answer, since all poweroff commands ultimately resolve into systemctl isolate poweroff.target.
    – iBug
    Dec 31, 2019 at 6:10
16

There are a few ways to achieve this . One would be working with a regular non-privileged account which will require running the command with sudo and entering a password. Then you can append the follwing to /etc/sudoers (by running visudo):

## user is allowed to execute reboot -r only
jdoe ALL=NOPASSWD: /sbin/shutdown -r *

Also, to disable sudo credentials caching , add the following as well :

Defaults timestamp_timeout=0

This will prevent credentials caching incase you invoked a command with sudo before.

Example:

[root@ops ~]# su - jdoe
[jdoe@ops ~]$ sudo shutdown -c
[sudo] password for jdoe:
[jdoe@ops ~]$ sudo shutdown -r +10
Shutdown scheduled for Mon 2018-09-03 18:51:13 IDT, use 'shutdown -c' to cancel.
[jdoe@ops ~]$ sudo shutdown -H
[sudo] password for jdoe:
^[[A[jdoe@ops ~]$ sudo shutdown -c
[sudo] password for jdoe:

Notice how in the above example I was not required to enter my password when running sudo shutdown -r +10 , but for the rest I was . If you want to remove the need for typing sudo before the command (sudo shutdown -r +10), add the following to your .bash_profile or .bashrc:

alias shutdown="sudo shutdown"

Example:

[jdoe@ops ~]$ source ~/.bash_profile
[jdoe@ops ~]$ shutdown -r +10
Shutdown scheduled for Mon 2018-09-03 19:03:14 IDT, use 'shutdown -c' to cancel.
[jdoe@ops ~]$ shutdown -c
[sudo] password for jdoe:

Note that it's best practice to work with a non-privileged account and escalate with sudo when required.

5
  • 1
    This is great, except sudo's default configuration will have it cache credentials for some time after the first invocation. This can be convenient when repeated execution of commands as root is required in a user session. In such a session, (or indeed, if a root shell is running), it would be entirely possible to transact the command shutdown and bypass the checks. Sep 3, 2018 at 20:09
  • Thanks for the input. However , in this case, we're configuring shutdown -r to not prompt for password when running with sudo , therefore, if he runs sudo shutdown -r ... the credentials will not be cached since they will not be entered. Look at the example I gave above , You can see I ran it followed by a sudo shutdown -H and I was prompted for password.
    – John Doe
    Sep 3, 2018 at 21:02
  • 3
    Indeed, that's understood. But, consider the scenario in which the last command was prefixed with sudo and was not a NOPASSWD operation; e.g. a call to edit a config file as root. In this instance, the password will be cached and a subsequent call to sudo shutdown -H would go through. sudo's password caching would need to be disabled to avoid this. Sep 3, 2018 at 21:04
  • 2
    In this case you are right , +1 for disabling password caching . Edited my comment with the suggestion. Thanks!
    – John Doe
    Sep 3, 2018 at 21:08
  • 2
    I actually don't like this at all, precisely because it relies on the presence of the sudo password prompt to supposedly remind the user not to do whatever it is they aren't supposed to be doing. But the password prompt really doesn't serve this purpose. It's so commonly asked for by sudo that we just type in the password and move on. See here for an alternate approach using sudo (that is probably a lot better despite not being very good). Sep 4, 2018 at 13:45
10

There is a tool called molly-guard that requires you to state the hostname of the machine you want to shut down or reboot.

In case you're not using Debian, it should be trivial to compile this from source, given that the program is rather primitive.

9

To prevent mishaps RHEL based distributions already set up aliases for rm , cp and mv which can be somewhat more destructive when performed by the root user.

You could add your own, for instance:

#/root/.bashrc
alias poweroff='echo  "poweroff: Command disabled - THINK before you type.
  Use /usr/sbin/poweroff if you really want to drive to the DC to restore power."'
1
  • 2
    How does this keep the shutdown -r while disabling shutdown -P -H ?
    – MSalters
    Sep 4, 2018 at 13:10
3

Rename the shutdown executable to something impossible to invoke accidentally.

Then alias shutdown to be (whatever) -r

4
  • 1
    Could you please explainw how to rename the executable? Could it break packages upgrades in the future?
    – A.L
    Sep 4, 2018 at 9:34
  • 2
    @A.L Could it break packages upgrades in the future? Yes it could. It could also break things already installed. In general, messing with parts of the OS installation is a very bad idea. Sep 4, 2018 at 12:19
  • 1
    Agree. It's sufficient to alias shutdown to /sbin/shutdown -r. Renaming is not necessary; as the alias expansion refers to an absolute path it's not subject to recursive alias expansion.
    – MSalters
    Sep 4, 2018 at 13:12
  • One caveat -- I would think that 'nothing is impossible' -- just unlikely Sep 4, 2018 at 19:58
0

Addendum to Michael's answer: masking just poweroff.target still allows (sudo) halt to succeed. If you want to block that as well, do this:

systemctl mask poweroff.target
systemctl mask halt.target

Bonus note: this configuration persists across reboots, at least for me.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .