10

Note: I asked a similar quesiton concerning version 6 of these bundles here. Note that 7 uses systemd and may have a different implementation

In the rare cases that a RHEL or CentOS 7 system is prevented from booting by (for instance) an improper shutdown, or a forced fsck-check failure on boot, the console will prompt the user for a root password.

How do I disable the password check and drop directly to a root-shell?

Unacceptable answers:

  • overriding init on kernel command line (ie, grub)
  • linking / replacing /sbin/sulogin with /sbin/sushell. (This would work, but it would raise red flags with the security framework).
  • booting from some other device
Otheus
  • 5,945
  • 1
  • 22
  • 53

2 Answers2

11

Systemd is working with services and targets. Targets is the equivalent of runlevels, services is the equivalent of init scripts. Most of systemd configuration is located in /usr/lib/systemd, while standard init are in /etc/{init.d,rc*.d,inittab}.

When an issue kicks in during the boot process (default are getty.target or graphical.target, you can get them with systemctl get-default) systemd is switching to emergency.target.

This "emergency" target will in turn, load the file emergency.service. This service contains multiple lines, and among them:

...
[Service]
Environment=HOME=/root
WorkingDirectory=/root
ExecStartPre=-/bin/plymouth quit
ExecStartPre=-/bin/echo -e 'Welcome to emergency mode! After logging in, type "journalctl -xb" to view\\nsystem logs, "systemctl reboot" to reboot, "systemctl default" to try again\\nto boot into default mode.'
ExecStart=-/bin/sh -c "/sbin/sulogin; /usr/bin/systemctl --fail --no-block default"
...

We just need to replace the call to /sbin/sulogin:

ExecStart=-/bin/sh -c "/sbin/sushell; /usr/bin/systemctl --fail --no-block default"

And we will be dropped directly to a shell, instead of getting prompted for the password via sulogin. (We can use /bin/sh, but /sbin/sushell falls in line with the answers for CentOS6/RHEL6. In fact, sushell simply exec's $SUSHELL which defaults to /bin/bash.)

To make this change "permanent", ie, immune to yum updates, make the change to a copy of this file and place it in /etc/systemd/system/. Also, to make the "rescue mode" work the same way, replace the same line in rescue.service. Here's a shell/sed script to simplify the process:

for SERVICE in rescue emergency ; do 
   sed '/^ExecStart=/ s%"/sbin/sulogin;%"/sbin/sushell;%' /usr/lib/systemd/system/$SERVICE.service > /etc/systemd/system/$SERVICE.service
done

To test this, make sure the system is otherwise not in use, and tell systemd to switch to the rescue target:

systemctl rescue

This will close network connections and open a shell at the console. You can test with the emergency target, but that doesn't work quite as cleanly (For some reason) and may require a full reboot to come out of.

You can also test these from the boot-menu (grub). For testing the emergency mode, it's easy. Boot and when you get the menu, hit "e" to edit, and use the D-pad to navigate to the line beginning with linux16 and append (hit CTRL-A to get to the end of the line) emergency:

linux16 ... emergency

For testing rescue mode, it's the same steps as above but you must be more explicit:

linux16 ... systemd.unit=rescue.target
Otheus
  • 5,945
  • 1
  • 22
  • 53
Adrien M.
  • 3,466
  • 1
  • 17
  • 17
  • Hum you're right, seem machinectl is only for VMs and Containers. I'm checking more in details about the systemd-ask-password systems with my local fedora & will edit the post as needed. – Adrien M. Jul 27 '15 at 18:21
  • 1
    Ok, try this : edit `/usr/lib/systemd/emergency.service`. On line `"ExecStart=-/bin/sh -c "/sbin/sulogin; /usr/bin/systemctl --fail --no-block default"`, remove the `/sbin/sulogin ;` part. Tell me if that works, so I'll update the post. – Adrien M. Jul 27 '15 at 18:39
  • Woops, maybe not remove it, but replace it by `/bin/sh`, or any other shell. And you can do the same replacement in `/usr/lib/systemd/rescue.service` – Adrien M. Jul 27 '15 at 18:46
  • 1
    "You need at least 2k reputation to review suggested edits." Even on my own post ? lol, some bugs for the devs :) Thanks for the test & edit ! – Adrien M. Jul 27 '15 at 21:14
  • 1
    In my test, I changed my /home mount, and it dropped to rescue. From what I saw (in this post: http://forums.fedoraforum.org/showthread.php?t=270936), "rescue" is the equivalent of Singleuser, "emergency" is the equivalent of init=/bin/sh. We're all in for a whole lot of tricks to learn with systemd :) – Adrien M. Jul 27 '15 at 21:25
  • Great idea about changing mountpoints. I did the same for `/tmp` by simply modifying the fstype in `fstab` and on reboot, it dropped me to `emergency`'s service, not `rescue`. The grub-based "rescue" does not actually enter rescue mode on CentOS7. Answer edited again per RedHat docs and testing. – Otheus Jul 28 '15 at 12:43
  • +1 for pointing me in the direction of `emergency.service`: in my case, I **want** a password prompt and wasn't getting one on Ubuntu. The man page states "if the root account is locked .... no password prompt is displayed and `sulogin` behaves as if the correct password were entered." – James Johnston Mar 31 '16 at 00:32
  • It is quite important to check that `/sbin/sushell` exists first. (It does on RHEL7, but not on Debian, where this answer is otherwise perfectly fine...) – Gert van den Berg Feb 12 '18 at 17:20
  • Could you use `sulogin`'s `--force` option because that'll force it to work even if PW is locked. I think. I haven't tested yet. – IMTheNachoMan Jan 30 '19 at 05:37
  • Or, how about opening a shell as a regular user with login and `sudo` as `root` privileges? – IMTheNachoMan Jan 30 '19 at 06:25
  • Since [systemd 240](https://github.com/systemd/systemd/pull/10397) you should actually just append the `ENABLE_FORCED_SULOGIN=1` variable to the *Environment* field. – mirh Nov 01 '20 at 18:24
-3

The method I used to follow for bypassing the root password and reach the root shell is by editing the init in grub (kernel line).

init=/bin/bash
Jeff Schaller
  • 66,199
  • 35
  • 114
  • 250
  • 1
    Downvoted because I specifically mentioned overriding init is not an option. There are technical reasons this works poorly -- primarily because "init" does a lot "behind the scenes" to make the system somewhat usable. – Otheus Jul 21 '15 at 16:23
  • With `init=/bin/bash`, you'll lose job control for the console, which means that Ctrl-C will not work. In an emergency situation, not being able to stop a command on your single console is a lot graver than "poor"... – Laszlo Valko Jul 28 '15 at 01:35
  • See also https://unix.stackexchange.com/a/251228/5132 . – JdeBP Sep 16 '17 at 13:14