Breaking into RedHat/CentOS 7
So, that time’s come around I guess — time to get moving and figure out how Red Hat Enterprise Linux 7 / CentOS 7 tick. Today’s fun-time task was to get familiar with systemd, the controversial replacement for init.
Being relatively au-fait with starting and stopping services with systemctl already (despite my tendancy to type sysctl instead), I decided to brush up on runlevels. Or rather, the lack thereof!
I soon gathered that we’ve replaced runlevels with targets. Four important ones:
- graphical.target is basically runlevel 5.
- multi-user.target is basically runlevel 3.
- rescue.target, single-user(-ish). Root mounted read-write.
- emergency.target, closest to runlevel 1. Root mounted read-only.
We can switch to these targets by using systemctl isolate <target>. However, it amused me that the init command still works in the classic fashion (for example, issuing init 6 to reboot the system), even though it’s a symlink to /usr/lib/systemd/systemd. A nice touch, for backwards compatibility!
rescue.target and emergency.target both need the system’s current root password in order to obtain a shell. However, one reason for going into single-user mode may be to reset a root password that someone’s long since lost.
In el5 and el6, the trick was to pass init=/bin/bash to the kernel parameter from the bootloader. This executed a root shell as process ID 1 instead of the usual init program.
That doesn’t work in el7, however. We’ve got a slightly different dance to do. Instead, we pass rd.break as a kernel parameter from the bootloader to interrupt the boot sequence and drop to a root shell. Here’s how:
- Reboot.
- Press any key before your kernel boots to access at the GRUB2 menu.
- Hit `e` to edit the default kernel line.
- Find the line that starts with linux16 and append rd.break to it.
- Continue with Control+X.
After a minute, we’re at the same place you’d be if you’d appended init=/bin/bash to the kernel parameters of any init-controlled Linux box. Except that our root partition is handily already mounted read-only under /sysroot.
Let’s change that root password:
- Remount /sysroot read-write with mount -o remount,rw /sysroot.
- Switch into a chroot jail using with chroot /sysroot.
- Change root’s password with passwd.
I rebooted here. Big mistake.
My test box was set to boot into graphical.target (runlevel 5, to me). However, my graphical user environment failed to load. I had a black screen. From outside, I could see that sshd was running and responding to my connection attempts, but none of my login attempts were honoured — I kept getting authentication failures. What happened?
I rebooted, broke back in and checked out the system log. Read some stuff. Saw the ill-fated word: SELinux. Damn.
To fix it, I had to:
# touch /.autorelabel
# exit
# exit
Everything came back up in a few minutes, sweet as a nut.
Cause? The passwd command seems to create a new set of files before moving them into place. So, that’ll be a new file with an incorrect SELinux context, then.
That’ll teach me for being itchy with the ol’ reboot. Story of my life, really.