root.whispers/ssh.md

12 KiB

root.whispers — Linux Commands Cheatsheet

AlmaLinux 9 / RHEL 9 family and Ubuntu 22.04 tested. Some commands vary by distro. Read before you run.


Table of Contents


System Basics

hostnamectl                     # Hostname / chassis / OS info
lsb_release -a                  # Distro info (Debian/Ubuntu)
cat /etc/os-release             # Generic OS info
uname -a                        # Kernel
uptime -p                       # Pretty uptime
whoami && who && last -n 5      # User/session audit
free -h                         # Memory
vmstat 1                        # Quick CPU/mem view
df -hT                          # Disks with FS types
lsblk -f                        # Block devices with labels/UUIDs

Users & Groups

# Key files
/etc/passwd                     # User accounts
/etc/group                      # Groups
/etc/shadow                     # Password hashes
/etc/login.defs                 # Defaults for new users
/etc/skel                       # Skeleton for new home dirs
/etc/security/pwquality.conf    # Password complexity rules

# Users
useradd <username>
useradd -r <username>           # System account
passwd <username>               # Set/change password
echo "user:pass" | chpasswd     # Batch update passwords

id <user>                       # Show uid/gids
userdel <username>
userdel -r <username>           # Remove and delete $HOME

# Groups
groupadd <group>
groupdel <group>
usermod -a -G <group> <user>    # Add user to group
gpasswd -a <user> <group>       # Alternative add
gpasswd -d <user> <group>       # Remove from group

# Lock / unlock user (account)
passwd -l <user>                # Lock
passwd -u <user>                # Unlock

# Shell
chsh -s /bin/bash <user>        # Change login shell
usermod -s /sbin/nologin <user> # Disable interactive logins
usermod -s /bin/false <user>    # Drop immediately on login

# Sudo
usermod -a -G sudo <user>       # Debian/Ubuntu
usermod -a -G wheel <user>      # RHEL/CentOS/Fedora

# Password aging
chage -m MIN -M MAX -W WARN -I INACT -E EXPIRE <user>

Permissions & Modes

ls -l tmp                       # List perms
chmod g-w tmp                   # Remove write (group)
chmod a-r tmp                   # Remove read (others)
chmod u+rw file                 # Add rw (user)
chmod u+x file                  # Add execute (user)
chmod a+rwx path                # rwx for all

# SetUID / SetGID / Sticky
chmod u+s file                  # SetUID on executable
chmod g+s file_or_dir           # SetGID on file/dir
chmod +t dir                    # Sticky bit on dir (only owner can delete)
chmod -t dir                    # Remove sticky

# chown / chgrp
chown -R user path
chgrp -R group path

ACLs

setfacl -m u:USER:rwx PATH
setfacl -m g:GROUP:r PATH
setfacl -Rm g:GROUP:r PATH      # Recursive
setfacl -x g:GROUP PATH         # Remove entry
setfacl -b PATH                 # Remove all ACLs
getfacl PATH                    # Show ACLs

Files, Search & Text

# Existence tests
test -f FILE && echo "file exists"
test -d DIR  && echo "dir exists"

# Find / grep
find . -type f -mtime -1
grep -Rni --color "pattern" .
grep -E "foo|bar" file
grep -c "pattern" file          # Count matches

# sed / awk
sed -n '1,120p' file            # Show lines 1..120
awk '{print $1,$2}' file

# Sorting / uniq
sort -nr file
uniq file

# Copy/move including dotfiles
# Zsh
setopt glob_dots; mv Foo/* Bar/; unsetopt glob_dots
# Bash
shopt -s dotglob; mv Foo/* Bar/; shopt -u dotglob

# rsync
rsync -avh --progress SRC/ DST/

# Checksums
sha256sum file
echo "<checksum>  file" | sha256sum -c

Processes & Services

# Processes
ps -ef | grep <name>
ps -ef --sort=-%cpu | head -10
ps -ef --sort=-%mem | head -10
pgrep <name>                    # PIDs by name
pkill <name>                    # Kill by name
kill <PID>; kill -9 <PID>       # SIGTERM, SIGKILL
killall -s 9 <proc>             # Force kill all by name
top -H -p <PID>                 # Threads view
pstree                          # Tree view
strace -f -p <PID>              # Syscalls (careful)
perf top                        # Hot functions

# systemd
systemctl status/start/stop/restart NAME.service
systemctl reload NAME.service
systemctl enable/disable NAME.service
systemctl mask/unmask NAME.service
systemctl list-units --type=service --no-pager | grep -i term
systemctl --all

Time & NTP

timedatectl                      # Show time settings
timedatectl list-timezones
timedatectl set-timezone Europe/Stockholm
timedatectl set-time '2025-08-08 20:15:50'
timedatectl set-ntp true

# Chrony (RHEL family)
dnf install -y chrony ntpstat
systemctl enable --now chronyd
ntpstat
chronyc sources -v
vi /etc/chrony.conf && systemctl restart chronyd
chronyc makestep

Networking

ip a                             # Addresses
ip r                             # Routes
ss -tulpn                        # Listening sockets
lsof -i :443                     # Who bound 443
nc -zv host 1-1024               # Quick port sweep
curl -I https://example.com      # HEAD request
dig +short A example.com         # Just the answers
traceroute example.com

# tcpdump
tcpdump -i eth0 -nn port 53 -vv

# View & sort sizes
du -h ~ | sort -nr

SSH (Client & Server)

# Client quality-of-life
ssh -J jumpbox user@target
ssh -o StrictHostKeyChecking=accept-new host
scp -3 user1@host1:/p user2@host2:/p

# ~/.ssh/config
# ---
# Host prod
#   HostName 203.0.113.10
#   User ubuntu
#   IdentityFile ~/.ssh/id_ed25519
#   ForwardAgent no

# Keys
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -C "comment"
ssh-copy-id USER@HOST -i ~/.ssh/id_ed25519.pub

# Server (/etc/ssh/sshd_config)
# Client keepalive
ClientAliveInterval 600
ClientAliveCountMax 1
# Disable root login
PermitRootLogin no
# Disable empty passwords
PermitEmptyPasswords no
# Allow only certain users
AllowUsers user1 user2
# Change port
Port 2222
# Reload
# systemctl restart sshd

Firewall

# firewalld (RHEL family)
firewall-cmd --list-all
firewall-cmd --get-active-zones
firewall-cmd --zone=public --list-all
firewall-cmd --get-services
firewall-cmd --add-service=http --permanent
firewall-cmd --add-port=8080/tcp --permanent
firewall-cmd --reload
firewall-cmd --runtime-to-permanent

# iptables (legacy)
iptables -L
iptables -F

# nftables
nft list ruleset

Packages (RPM & Debian)

# RHEL / Fedora
dnf install PACKAGE
dnf remove PACKAGE
rpm -qa                     # List installed
rpm -qi PACKAGE             # Info
rpm -qc PACKAGE             # Config files
rpm -qf /path/to/file       # What pkg owns this file?
rpm -ihv PACKAGE.rpm        # Install local rpm
cat /etc/redhat-release
yum update                  # Minor updates
yum upgrade                 # Full upgrade

# Debian / Ubuntu
apt update && apt list --upgradable
apt install PACKAGE
apt remove PACKAGE
dpkg -S /usr/bin/foo        # What pkg owns file
apt-cache policy PACKAGE    # Candidate version/source
cat /var/log/apt/history.log

Disks, Filesystems & Mounting

lsblk
blkid
fdisk -l /dev/sda
df -hT

# Quick single-partition + format (ext4)
fdisk /dev/sdx        # g|o, n (defaults), w
mkfs.ext4 /dev/sdx1
mkdir -p /data && mount /dev/sdx1 /data

# Labels & mounts
e2label /dev/sdx1 DATA_VOL
mount -L DATA_VOL /data
echo "UUID=$(blkid -s UUID -o value /dev/sdx1) /data ext4 defaults 0 0" >> /etc/fstab
mount -a

# Integrity
e2fsck -f /dev/sdx1

# Loop ISO
mount -o loop file.iso /mnt/iso

LVM / VDO / Stratis

# LVM
pvcreate /dev/sdb1
vgcreate vg0 /dev/sdb1
lvcreate -n lvdata -L 50G vg0
mkfs.ext4 /dev/vg0/lvdata
mount /dev/vg0/lvdata /data

lvextend -l +100%FREE /dev/vg0/lvdata
resize2fs /dev/vg0/lvdata

lvremove vg0/lvdata && vgremove vg0 && pvremove /dev/sdb1

# VDO (RHEL 9+ note: requires correct packages)
lvcreate --type vdo -n vdotank -L 100G -V 300G vg0
lvs -o lv_name,vdo_compression,vdo_deduplication
vdostats --human-readable
lvchange --compression y /dev/vg0/vdotank

# Stratis
dnf install -y stratis-cli stratisd
systemctl enable --now stratisd
stratis pool create pool0 /dev/sdb
stratis filesystem create pool0 fs0
mount /dev/stratis/pool0/fs0 /stratis

Logging

# Classic logs (RHEL)
/var/log/boot
/var/log/messages
/var/log/secure
/var/log/cron
/var/log/maillog
/var/log/chronyd
# Debian/Ubuntu auth
/var/log/auth.log

# journald
journalctl -b -1                 # Previous boot
journalctl -u ssh --since "2h"
journalctl -xe                   # Errors with context
journalctl -k -f                 # Kernel (follow)

# Persistent journal
vi /etc/systemd/journald.conf    # Storage=persistent
mkdir -p /var/log/journal
systemctl restart systemd-journald
journalctl --flush

Scheduling (cron / at)

# Access control
echo USER >> /etc/cron.allow
echo ALL  >> /etc/cron.deny

crontab -e                       # Edit current user
crontab -e -u <user>             # Edit other user
crontab -l                       # List

# at
echo "echo hi" | at now + 1 hour
systemctl enable --now atd
echo USER >> /etc/at.allow
echo ALL  >> /etc/at.deny

Containers (Podman & Docker)

# Podman
dnf install -y podman
podman info
podman images && podman ps -a
podman run -dt --name web -p 8080:80 docker.io/library/nginx:alpine
podman exec -it web /bin/sh
podman logs -f web
podman rm -a -f

# Generate systemd unit for rootless container
podman generate systemd --new --files --name web
loginctl enable-linger <user>
systemctl --user enable --now container-web.service

# Docker parity
docker images && docker ps -a
docker run -dt --name web -p 8080:80 nginx:alpine
docker exec -it web /bin/sh
docker logs -f web
docker compose up -d
docker compose logs -f <service>

Git Essentials

git config --local user.name "Your Name"
git config --local user.email "you@example.com"

git switch -c fix/thing
git add -A && git commit -m "message"
git pull --rebase origin main
git push

git stash push -m "wip: foo" && git stash list
git reflog                          # Recover lost refs
git reset --soft HEAD~1             # Undo last commit keep changes
git reset --hard HEAD~1             # Dangerous: drop changes
git push --force                    # Use sparingly
git commit --amend --reset-author

Security Quick Checks

sudo -l                              # What can current user sudo?
getcap -r / 2>/dev/null | grep cap_  # Files with caps
stat -c "%a %n" *                    # Numeric perms
sha256sum FILE                       # Hash

Misc Snippets

# Nice / renice
nice -n 10 command
renice -n 19 -p <PID>

# Generate password
tr -dc 'A-Za-z0-9' </dev/urandom | head -c 20; echo

# exiftool scrub
exiftool -All= *.jpg
exiftool -All= -overwrite_original *.png

# Tail
tail -f FILE

# DNS
dig example.com A +noall +answer

# sosreport (RHEL)
sosreport

# wget
wget -O out.html https://example.com

# traceroute
traceroute example.com