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
  • 6,138

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
  • 6,138
Adrien M.
  • 3,566
  • 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 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
  • 67,283
  • 35
  • 116
  • 255
  • 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