Level 3 — Advanced: kernel & security · wrap-up
Cheat sheet & self-check
Every command from this section on one page.
Kernel & modules
uname -r | Running kernel version |
lsmod | grep br_netfilter | Is a module loaded? |
modinfo overlay | Module details and parameters |
sudo modprobe br_netfilter | Load a module now |
echo br_netfilter | sudo tee /etc/modules-load.d/k8s.conf | Load it at every boot |
sysctl
sysctl net.ipv4.ip_forward | Read one parameter |
sudo sysctl -w vm.swappiness=10 | Change it now (lost at reboot) |
sudo sysctl --system | Apply all files in /etc/sysctl.d/ |
cat /proc/cmdline | Parameters the kernel was booted with |
Namespaces
lsns | List namespaces on the host |
sudo unshare --pid --fork --mount-proc bash | A shell in a new PID namespace (it becomes PID 1) |
sudo unshare --net bash | A shell with its own, empty network stack |
sudo nsenter -t <pid> -n ip addr | Run a command inside another process's network namespace |
ls -l /proc/<pid>/ns | Which namespaces a process belongs to |
cgroups v2
stat -fc %T /sys/fs/cgroup | cgroup2fs = cgroup v2 in use |
systemd-cgls | The cgroup tree |
systemd-cgtop | Live resource use per cgroup |
sudo systemd-run --unit=demo -p MemoryMax=64M -p CPUQuota=20% sleep 600 | Run something in a limited cgroup |
cat /sys/fs/cgroup/<path>/memory.max | A cgroup's memory limit |
Inspect the hardware
lscpu | grep -i -E 'numa|socket|thread' | Sockets, NUMA nodes, threads per core |
numactl --hardware | NUMA nodes, their CPUs, memory and distances |
lscpu -e | Each CPU with its core, socket and NUMA node |
grep -i huge /proc/meminfo | Huge page totals and usage |
Control placement
taskset -c 2,3 ./app | Run on CPUs 2 and 3 only |
numactl --cpunodebind=0 --membind=0 ./app | Run and allocate memory on NUMA node 0 |
sudo sysctl -w vm.nr_hugepages=512 | Reserve 512 × 2 MiB huge pages |
cat /sys/kernel/mm/transparent_hugepage/enabled | Transparent huge pages mode |
perf (CPU profiling)
sudo perf top | Live view of the hottest functions system-wide |
sudo perf record -F 99 -a -g -- sleep 30 | Sample all CPUs at 99 Hz for 30 s, with stacks |
sudo perf report --stdio | head -50 | Where CPU time went |
sudo perf record -F 99 -g -p <pid> -- sleep 30 | Profile one process |
eBPF tools (bcc; Ubuntu names end in -bpfcc)
sudo execsnoop-bpfcc | Every new process, as it starts |
sudo opensnoop-bpfcc -p <pid> | Files a process opens |
sudo biolatency-bpfcc 10 1 | Disk I/O latency histogram over 10 s |
sudo tcpconnect-bpfcc | Outgoing TCP connections as they happen |
sudo runqlat-bpfcc 10 1 | How long tasks wait for a CPU |
bpftrace one-liners
sudo bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[comm] = count(); }' | System calls per process (Ctrl+C to print) |
sudo bpftrace -e 'tracepoint:syscalls:sys_enter_execve { printf("%s\n", comm); }' | Which programs call execve |
SELinux (RHEL, Rocky, Alma, Fedora)
getenforce / sestatus | Mode: Enforcing, Permissive or Disabled |
ls -Z /var/www/html / ps -eZ | grep nginx | File and process contexts (labels) |
sudo ausearch -m AVC -ts recent | Recent denials from the audit log |
sudo restorecon -Rv /srv/www | Reset files to their policy-defined labels |
sudo semanage fcontext -a -t httpd_sys_content_t '/srv/www(/.*)?' | Teach the policy a new web content path |
sudo setsebool -P httpd_can_network_connect on | Flip a policy boolean permanently |
sudo semanage port -a -t http_port_t -p tcp 8081 | Allow a service type to use another port |
AppArmor (Ubuntu, Debian, SUSE)
sudo aa-status | Loaded profiles and their modes |
sudo journalctl -k | grep -i apparmor | Denials (apparmor="DENIED") |
sudo aa-complain /etc/apparmor.d/<profile> | Log instead of block (for debugging) |
sudo aa-enforce /etc/apparmor.d/<profile> | Enforce again |
Attack surface
sudo ss -ltnup | Everything listening on TCP and UDP |
systemctl list-unit-files --state=enabled | Services that start at boot |
sudo find / -xdev -perm -4000 -type f 2>/dev/null | setuid programs |
SSH & firewall
sudo sshd -t | Validate sshd_config before reloading |
sudo ufw default deny incoming && sudo ufw allow OpenSSH && sudo ufw enable | Default-deny firewall (Ubuntu) |
sudo firewall-cmd --permanent --add-service=https && sudo firewall-cmd --reload | Open HTTPS (RHEL family) |
Updates & audit
sudo apt install unattended-upgrades | Automatic security updates (Ubuntu/Debian) |
sudo systemctl enable --now dnf-automatic.timer | Automatic updates (RHEL family; configure apply_updates) |
sudo auditctl -l | Active audit rules |
sudo ausearch -k identity -ts today | Audit events tagged 'identity' |
Evidence to capture before and after
sudo ss -ltnup > listen.txt | Open ports |
systemctl list-unit-files --state=enabled > enabled.txt | Enabled services |
sudo sysctl -a 2>/dev/null > sysctl.txt | All kernel parameters |
vmstat 1 10 > vmstat.txt; iostat -xz 1 10 > iostat.txt | Performance baseline |
diff before/listen.txt after/listen.txt | What changed |
Load test (from another machine)
ab -n 20000 -c 100 http://<server>/ | Apache Bench: requests/second and latency |
wrk -t4 -c200 -d60s --latency http://<server>/ | wrk: throughput and latency percentiles |