norboten · cheat sheet
Ninety minutes on a machine that will not boot — cheat sheet
users-permissions, boot-systemd, storage-lvm, networking, linux-basics
# getting in
# at the GRUB menu: any key to stop the countdown, `e` to edit, Ctrl-X to boot
rd.break # stop in the initramfs; root is /sysroot, read-only, no policy
# (the linux line wraps: cursor onto it, Ctrl-E, append; Ctrl-X boots)
mount -o remount,rw /sysroot ; chroot /sysroot ; passwd ; touch /.autorelabel ; exit ; exit
init=/bin/bash # PID 1 is a shell; remount / rw yourself; no clean exit
enforcing=0 # boot permissive once, to repair labels
systemd.debug-shell=1 # a root shell on tty9
# labels after a rescue edit
restorecon -v /etc/shadow /etc/passwd /etc/group /etc/gshadow
restorecon -n -v PATH # dry run: silence means correct
touch /.autorelabel && reboot # relabel everything (then it reboots again by itself)
# repositories and packages
dnf repolist ; dnf repolist --all
dnf config-manager --set-enabled|--set-disabled REPO
dnf clean all # after changing a baseurl
dnf -y install|remove PKG ; rpm -q PKG ; dnf provides '*/file'
# /etc/yum.repos.d/x.repo: [id] / name= / baseurl=file:///opt/repos/local / enabled=1 / gpgcheck=0
# timers
systemctl list-timers --all
systemd-analyze calendar '*:0/15'
systemd-analyze verify /etc/systemd/system/foo.timer # names unknown keys
systemctl enable --now foo.timer # the TIMER, not the service
systemctl start foo.service # test the work now
# OnCalendar=*:0/15 | hourly | Mon..Fri 09:00 ; Persistent=true ; WantedBy=timers.target
# accounts
groupadd -g 5000 auditors
useradd -u 5001 -G auditors maria
useradd -u 5002 -G auditors -s /sbin/nologin sam
usermod -aG wheel USER # administrator, the standard way
chage -M 90 -m 7 -W 14 USER ; chage -E 2026-12-31 USER ; chage -d 0 USER
chage -l USER # verify
passwd -l USER # password auth off — does NOT stop key login
# time
vi /etc/chrony.conf # comment out pool/server; add: server 192.168.5.2 iburst
systemctl enable --now chronyd ; chronyc -n sources ; chronyc tracking ; timedatectl
# journal
# Storage=auto (default) uses /var/log/journal if it exists; persistent always; volatile never
ls /etc/systemd/journald.conf.d/ # drop-ins apply in filename order: the LAST Storage= wins
mkdir -p /var/log/journal ; systemd-tmpfiles --create --prefix /var/log/journal
systemctl restart systemd-journald ; journalctl --flush ; journalctl --list-boots
# ssh keys
ssh-keygen -t ed25519 -N '' -f ~/.ssh/id_ed25519
ssh-copy-id user@host # or append the .pub to ~/.ssh/authorized_keys
chmod 700 ~/.ssh ; chmod 600 ~/.ssh/authorized_keys
ssh -o BatchMode=yes user@host true && echo ok # proves the KEY worked
journalctl -u sshd -n 20 # why it refused
# script arguments
"$1" "$2" "$#" "$@" "${1:-}" # positional, count, all, defaulted
case "${1:-}" in -o) … ;; *) echo "msg" >&2 ; exit 2 ;; esac
hostname -s ; uname -r ; df --output=pcent / # used percent: free is 100 minus this