Linux Foundation Certified System Administrator (LFCS) – In‑Depth Study Guide
Updated for the May 11 2023 blueprint. Two‑hour, hands‑on exam; distribution‑agnostic; remote‑proctored.
1. Exam at a Glance
Domain | Weight | What You’ll Be Asked to Do |
---|---|---|
Operations & Deployment | 25 % | Kernel tuning, package & service management, virtualization, containers, SELinux policy |
Networking | 25 % | Interface/DNS config, time sync, SSH, firewalls/NAT, routing, bonding/bridging, reverse proxy & LB |
Storage | 20 % | LVM, filesystems, swap, automount, NBD/NFS/SMB, performance monitoring |
Essential Commands | 20 % | Core CLI tools, Git basics, troubleshooting, SSL certificate handling |
Users & Groups | 10 % | Local/LDAP accounts, sudo/PAM limits, ACLs, environment profiles |
- Format – 15–20 practical tasks in a single terminal.
- Two attempts + two Killer.sh simulator runs included.
- Certification valid for 2 years.
2. How to Use This Guide
- Read: digest each domain summary.
- Practice: reproduce every task in a throw‑away VM.
- Validate: finish timed mock labs (see § 7).
- Refine: follow the 12‑week schedule (see § 6).
3. Domain Deep‑Dives & Task Checklists
Below are do‑it‑yourself lab exercises that map 1‑for‑1 to every skill in the “Domain Deep‑Dives & Task Checklists.”
Each exercise is phrased as a mini‑scenario with a clear objective, the resources you must use, and a quick self‑check so you know when you’ve succeeded.
3.1 Operations & Deployment (25 %)
Skill | Exercise |
---|---|
Kernel tuning | Scenario: An application fails because the system hits the default inotify watch limit. Task: Bump fs.inotify.max_user_watches to 524288 persistently.Verify: sysctl fs.inotify.max_user_watches returns 524288 and survives reboot. |
Package operations | Scenario: Your team needs a private repo for a patched RPM/DEB. Task: Build a dummy “hello‑world” package, sign it with a local GPG key, host it via Nginx, and configure DNF/APT on the VM to install it. Verify: hello-world --version prints the custom build string. |
Service mgmt & recovery | Scenario: A developer broke the httpd unit file.Task: Locate the error in /etc/systemd/system/httpd.service , restore a working copy from the package, and make sure the service starts at boot.Verify: systemctl is-active httpd → active and systemctl status shows no failed dependencies. |
Job scheduling | Scenario: You must delete rotated logs older than 14 days nightly. Task: Create a systemd timer (not cron) that calls journalctl --vacuum-time=14d at 03:15 local time.Verify: systemctl list-timers shows next and last runs; force a run with systemctl start . |
Virtualization | Scenario: QA needs a throw‑away VM snapshot before every test run. Task: Using virt-install + cloud‑init, deploy an AlmaLinux 9 guest with a second 2 GiB disk. Take an external snapshot, corrupt /etc/hosts , then roll back.Verify: After rollback, the guest’s /etc/hosts matches the pre‑corruption hash. |
Containers | Scenario: Convert a legacy static‑site build into an OCI image. Task: Write a Containerfile (or Dockerfile) that serves the files with nginx 1.25, tag it local/static:latest , run it with Podman on port 8080, then generate a systemd unit via podman generate systemd and enable it.Verify: curl http://localhost:8080/ returns the site and systemctl is-enabled container-static.service → enabled. |
SELinux | Scenario: You move the web root to /data/www . SELinux blocks access.Task: Add the needed context mapping with semanage fcontext , run restorecon , and make sure HTTP requests succeed without setting SELinux to permissive.Verify: curl -I http://localhost/ returns 200 OK and audit2why shows no new AVCs. |
3.2 Networking (25 %)
Task | Exercise |
---|---|
Configure IPv4/6 + DNS | Assign eth0 static IPv4 192.168.57.10/24 with gateway .1 and configure SLAAC IPv6. Add Cloudflare DNS 1.1.1.1 . Use nmcli (or netplan).Verify: ping -c3 2606:4700:4700::1111 and dig @1.1.1.1 linux.org +short both succeed after reboot. |
Time sync | Replace the default NTP pool with your own LAN NTP server 10.10.10.5 for Chrony.Verify: chronyc sources shows ^* 10.10.10.5 and timedatectl status lists System clock synchronized: yes . |
SSH hardening | Disable password logins entirely and permit only users in group sshusers .Verify: Password attempts fail with Permission denied ; key‑based auth for an sshusers member succeeds. |
Firewall/NAT | Forward incoming traffic on host port 2222 to guest VM 10.0.2.20:22 via nftables.Verify: ssh -p2222 localhost connects to the guest, and nft list ruleset shows your DNAT rule. |
Routing & bonding | Create a bond bond0 (active‑backup) from eno1 and eno2 , assign 172.31.30.50/24 , and set the default route.Verify: Unplugging eno1 keeps connectivity; ip -br link shows state UP for bond0 . |
Reverse proxy/LB | Deploy HAProxy listening on 443 that terminates TLS (use a self‑signed cert) and balances to two backend containers running nginx on ports 8081/8082 (round‑robin). Verify: curl -k https://localhost/ alternates the hostname header between the two back‑ends. |
3.3 Storage (20 %)
Objective | Exercise |
---|---|
Partition & FS | Attach a 4 GiB virtual disk, partition GPT with a single partition, format XFS, mount it at /srv/data by UUID through /etc/fstab .Verify: Reboot and run lsblk -f —the mount persists. |
LVM & snapshots | Convert /home into an LVM logical volume, enable thin‑provisioning, create a snapshot, delete files, then merge the snapshot to restore them.Verify: Files are back and lvs shows snapshot merged. |
Remote storage | Export /srv/nfs_share via NFSv4 on the host and automount it on another VM under /mnt/share using autofs.Verify: `mount |
Swap management | Disable the existing swap partition, create a 2 GiB zram swap device, and make it permanent. Verify: swapon --show lists only the zram device; grep zram /etc/fstab (or /etc/systemd/zram-generator.conf ) exists. |
Performance | Fill /srv/data with random data, identify the top 3 directories by space, add an XFS quota of 500 MiB to one sub‑directory.Verify: Writes beyond quota fail with EDQUOT . |
3.4 Essential Commands (20 %)
Area | Exercise |
---|---|
Shell & Text | Write a one‑liner that lists unique TCP ports a process named java is listening on, sorted numerically.Verify: The command outputs a list like 80 443 8080 with no duplicates. |
Processes | Launch stress to eat 2 CPU cores, lower its priority to 19 without killing it, then send it SIGSTOP and later SIGCONT .Verify: top shows the nice value change, and CPU usage pauses/resumes as expected. |
Monitoring | Attach strace to the PID of sshd , filter only accept syscalls, and write them to /tmp/ssh_accept.log .Verify: A new SSH connection appends a line to that log. |
Git basics | Initialize a repo, create a branch feature/logrotate , stage changes interactively (git add -p ), squash commits with an interactive rebase, and fast‑forward‑merge to main .Verify: git log --oneline --graph shows a clean history. |
SSL certificates | Generate a CSR for CN server.lab , sign it with your own CA, and configure nginx to use the new cert.Verify: openssl s_client -connect localhost:443 -showcerts prints CN=server.lab . |
3.5 Users & Groups (10 %)
Topic | Exercise |
---|---|
Local account lifecycle | Add user analyst with an expired password that must be changed at first login.Verify: First SSH login for analyst forces a password change, then proceeds. |
Password ageing & limits | Set a policy where all new passwords must age at least 1 day before they can be changed again, and expire after 90 days. Verify: chage -l analyst reflects min 1 day and max 90 days. |
Privilege delegation (sudo) | Allow members of group ops to restart nginx without a password.Verify: sudo -l -U <user_in_ops> lists the rule; running sudo systemctl restart nginx skips the password prompt. |
ACLs | Grant user qa read‑only access to /srv/app/config.yml while keeping default group/world permissions unchanged.Verify: sudo -u qa cat /srv/app/config.yml succeeds; echo test >> fails with Permission denied . |
LDAP integration | Spin up the osixia/openldap container, configure SSSD to use it, and login as LDAP user jdoe .Verify: id jdoe shows UID/GID from LDAP and getent passwd jdoe returns the entry even after reboot. |
How to Use These Exercises
- Snapshot or clone a fresh VM before each exercise.
- Time yourself—aim for ≤ 10 minutes per item once comfortable.
- Keep a lab journal: record the command sequence and any gotchas.
- When you can finish every exercise in this list confidently and quickly, you’re LFCS‑ready. Good luck!
4. Lab Environment Setup
- Hypervisor: libvirt + virt‑manager or VirtualBox.
- Base images: Ubuntu 22.04 and AlmaLinux 9 cloud images.
- Automation: Vagrant or Ansible to rebuild labs fast.
- Snapshot before every drill; destroy/revert when solved.
- Optional: shared clipboard + VS Code remote SSH.
5. Must‑Read Resources
- Official man pages (only reference allowed during exam).
- Killer.sh LFCS simulator (2 runs included).
- LFS207 e‑Learning + KodeKloud LFCS labs.
- Practice repos: https://www.linuxtrainingacademy.com/linux-commands-cheat-sheet/
- Community: LF forum, r/linuxadmin on Reddit.
6. 12‑Week Structured Plan
Week | Focus Area | Deliverable |
---|---|---|
1–2 | Lab build, CLI refresher | Bash one‑liner cheat‑sheet |
3–4 | Storage deep dive | LVM‑based NAS VM |
5–6 | Networking mastery | HAProxy + Nginx reverse proxy lab |
7–8 | Operations & Deployment | Containerize legacy app; enforce SELinux |
9 | Users & Groups | LDAP + sudo rules scenario |
10 | Troubleshooting drills | 20 tasks in 90 min |
11 | Killer.sh simulator #1 | ≥70 % score |
12 | Weak‑spot remediation + sim #2 | <5 min per task |
Weekly “Do This Now” Exercises
Week | Core Focus | One Concrete Exercise |
---|---|---|
1 | Lab Scaffold | Spin up a disposable lab VM (Ubuntu 22.04 and AlmaLinux 9) with cloud‑init SSH keys and nested‑virt enabled. Snapshot it and write a 5‑line bash script named reset_lab.sh that destroys/re‑provisions the VM in ≤ 90 seconds. |
2 | CLI Reflexes | Produce a personal “Top‑40 one‑liners” cheat‑sheet. Fill it with find/grep/sed/awk commands that you actually tested. Store it at ~/lfcs-cheats/cli.md and sync to a Git repo. |
3 | LVM Foundations | Add a 10 GiB virtual disk, create a new LVM VG vg_data , LV lv_nas , format XFS, mount on /srv/nas , and set an XFS quota of 2 GiB for a sub‑directory projects/ . |
4 | NAS Services | Export /srv/nas over NFSv4 with read‑write access to a second VM. Automount it on demand using autofs (/net/nas ). Validate by writing a 1 GiB test file from the client. |
5 | Reverse‑Proxy Basics | Inside the lab, start two dockerized Flask apps on ports 5001 & 5002. Install Nginx on the host to round‑robin HTTP 80 traffic to those back‑ends. Prove rotation with five curl hits. |
6 | TLS + HAProxy | Replace Nginx with HAProxy listening on 443, using a self‑signed cert (CN=lab.local ). Terminate TLS and continue to load‑balance the Flask apps. Confirm with openssl s_client -connect localhost:443 . |
7 | Containerize Legacy App | Take a static HTML site, write a Containerfile that serves it with nginx, tag it legacy:web , push to a local registry, and deploy via podman run --name legacy -p8080:80 . |
8 | SELinux Enforcement | Move the site’s volume to /data/legacy , fix contexts with semanage fcontext + restorecon , without setting SELinux to permissive. Show curl http://localhost:8080 returns 200 OK and audit.log is clean. |
9 | Directory Services | Run osixia/openldap + phpldapadmin in containers, configure SSSD on the host, import an LDIF that creates group ops , user jdoe . Make jdoe able to sudo systemctl restart nginx password‑lessly. |
10 | Speed‑Troubleshoot | Randomly pick 10 services (e.g., SSH, chronyd, crond, NetworkManager). Stop or mis‑configure each, then restore them all in ≤ 90 minutes. Log each fault + fix in ~/fire‑drill.log . |
11 | Sim #1 Benchmark | Run the first Killer.sh LFCS simulator. Record score + per‑task times in ~/sim1-results.md . Identify any task that took > 8 minutes or failed. |
12 | Targeted Remediation + Sim #2 | Re‑practice only the > 8 minute tasks from Week 11 until each is < 5 minutes. Run Killer.sh simulator #2 and beat 70 %. Document the delta in ~/sim2-results.md . |
Complete each week’s exercise before moving on; your notes, scripts, and logs will become your pre‑exam “run book.”
7. DIY Mock Labs
https://github.com/LINUXexpert-org/lfcs-labs
- Broken Boot – break root UUID, recover via chroot.
- Network Outage – bad gateway; make fix persistent.
- Disk Full – fill
/var
; rotate/compress logs, grow LV. - SELinux Denial – wrong context; design & apply policy fix.
- LDAP Fail‑over – swap primary/secondary, keep auth working.
Time yourself – aim for ≤10 min per scenario.
8. Exam‑Day Tips
- Skim all tasks first; knock out quick wins for 70 % buffer.
- Use
tmux
splits (logs left, commands right). - Keep man pages open in another pane (
man bash
,man systemd.unit
). - Track progress:
echo OK > /tmp/taskX.done
. - Reserve 10 min for sanity checks (
df -h
,systemctl --failed
).
9. Final Thoughts
The LFCS rewards muscle‑memory troubleshooting more than flag memorization. Spin up labs, time your fixes, and the exam will feel like just another practice run.
Good luck – see you on the other side with a brand‑new badge!