In 02-07 you saw an s where you expected an x and I promised you would understand it thoroughly in this lesson. The moment has arrived, and it comes together with the other piece you have been using for four modules without asking any questions: sudo. You type sudo dozens of times a day, but who decided you could? Where is it written down? What would happen if Marta asked you to let luis restart the application — just restart it — without handing him the whole machine? This lesson answers all three questions and adds the tools the classic ugo/rwx model does not cover: capabilities, ACLs and immutable attributes. By the end, operator will be able to deploy Tramontana with a sudoers rule you wrote yourself, and Luis will read the logs without being in adm.
Contents
- Why you do not work as root
su,su -,sudo -iandsudo -scomparedsudoin depth: the cache, the environment and the redirection mistakesudoers: syntax,visudoand safe rules- Traceability: where
sudoleaves its trace - Recovering from a broken
sudoers - SUID: real UID versus effective UID
- SGID on directories: the teamwork bit
- The sticky bit and
/tmp - Capabilities: the modern replacement for SUID
- ACLs: permissions
ugocannot express - Extended attributes and immutability
- Tramontana case: the deployment
sudoersrule
- Why you do not work as root
Root does not have permissions: root has no permission checking. Faced with a process whose effective UID is 0, the kernel skips the whole verification. That means three things:
- A mistake is irreversible.
rm -rf /opt/tramontana /with one space too many, run asoperator, fails with "Permission denied" on the second path. Run as root, it wipes the system. - There is no traceability. If five people share the root password,
auth.logwill say "root did X" and nobody will know who it was. Withsudo, it will say "operator ran X as root". - There is no least privilege. Somebody who needs to restart a service does not need to be able to read
/etc/shadowor reformat a disk.
That is why Ubuntu ships with root having no usable password (! in shadow, as you saw in 05-01) and all administrative work goes through sudo.
su, su -, sudo -i and sudo -s compared
su, su -, sudo -i and sudo -s compared| Command | Password it asks for | Resulting environment | PATH |
Directory |
|---|---|---|---|---|
su |
root's | Inherits almost all of yours | Yours | The current one |
su - |
root's | A full root login, a clean environment | root's | /root |
sudo -s |
Yours | A shell with your environment, HOME preserved |
secure_path |
The current one |
sudo -i |
Yours | A full root login, like su - |
root's | /root |
sudo command |
Yours | Just that command, a sanitised environment | secure_path |
The current one |
The dash in su - (and in -i) is what makes the difference: without it you carry your variables, your aliases and your PATH into a session with UID 0, and that is exactly the vector by which a tampered PATH with a fake ls ends up running as root. If you need a root session, use sudo -i. And as a general rule, neither of the two: one sudo per action leaves a better trail than a root session left open for half an hour.
sudo in depth: the cache, the environment and the redirection mistake
sudo in depth: the cache, the environment and the redirection mistakeWhat sudo does when you invoke it: it checks your identity against /etc/sudoers, asks for your password (not root's), logs the order, builds a fresh environment and runs the command with the target identity.
$ sudo -l # what does sudo let me do here?
Matching Defaults entries for operator on srv-tramontana:
env_reset, mail_badpass, secure_path=/usr/sbin\:/usr/bin\:/sbin\:/bin
User operator may run the following commands on srv-tramontana:
(ALL : ALL) ALLThe credential cache remembers that you already authenticated for 15 minutes per terminal (timestamp_timeout, in minutes; 0 disables it and -1 makes it eternal, which is a bad idea). sudo -k invalidates it right now, sudo -v renews it without running anything, which is useful at the start of a long script.
Options used every day:
sudo -u svc-tramontana /opt/tramontana/app/bin/check # as ANOTHER user, not root
sudo -E ./script.sh # keep the environment (if sudoers allows it; use it with fear)By default env_reset wipes your environment and secure_path imposes a fixed PATH. It is a deliberate protection: without it, exporting LD_PRELOAD or altering the PATH before a sudo would be an immediate promotion to root. That is also why sudo sometimes cannot find one of your binaries in /home/operator/bin: it is not in secure_path, and you have to give the absolute path.
And the classic we have been carrying since Module 3:
$ sudo echo "something" > /etc/tramontana/note.conf
bash: /etc/tramontana/note.conf: Permission deniedIt is not echo that fails: the redirection fails, and your shell — which is still operator — does it before sudo even gets to run. The two correct solutions:
echo "something" | sudo tee /etc/tramontana/note.conf >/dev/null # the usual one
sudo bash -c 'echo "something" > /etc/tramontana/note.conf' # when there are several redirections
sudoers: syntax, visudo and safe rules
sudoers: syntax, visudo and safe rulesThe file is /etc/sudoers, but you do not edit it: you edit it with visudo, and your own rules go in separate files inside /etc/sudoers.d/, which sudoers pulls in with @includedir. visudo locks the file against simultaneous edits and, above all, validates the syntax before saving. A sudoers with a syntax error leaves the system without any working sudo, and that is an emergency.
sudo visudo # edits /etc/sudoers with validation
sudo visudo -f /etc/sudoers.d/tramontana # edits a single file, also validated
sudo visudo -c # -> /etc/sudoers: parsed OKThe files in /etc/sudoers.d/ must have mode 0440, ownership root:root, and contain no dot and not end in ~ in the name, or sudo silently ignores them.
The syntax of a rule
operator ALL=(ALL:ALL) ALL %sudo ALL=(ALL:ALL) ALL luis srv-tramontana=(root) NOPASSWD: /usr/bin/systemctl status tramontana.service
- A
%in front of the name means group: that is why belonging tosudogives you powers, it is this line. machinelets you distribute the samesudoersacross a whole fleet; on a standalone server you writeALL.(root)is the target identity;(ALL:ALL)additionally lets you choose a group with-g.NOPASSWD:avoids asking for the password. Convenient for what a script runs; dangerous for everything else.
Aliases
User_Alias OPERATIONS = operator, intern
Host_Alias PRODUCTION = srv-tramontana
Cmnd_Alias SERVICE = /usr/bin/systemctl start tramontana.service, \
/usr/bin/systemctl restart tramontana.service
Runas_Alias APP = svc-tramontana
OPERATIONS PRODUCTION = (root) SERVICEWhy blacklists do not work
sudoers accepts ! to deny, and it is a trap:
It can be bypassed in a thousand ways. If you can run ALL, you can run cp /bin/bash /tmp/sh && chmod u+s /tmp/sh, or simply:
sudo vim -c ':!/bin/bash' # a shell from the editor
sudo find /etc -maxdepth 0 -exec /bin/bash \; # a shell from find
sudo awk 'BEGIN{system("/bin/bash")}' # a shell from awkThe golden rule: a sudo rule is a whitelist. Enumerate what is allowed; do not try to enumerate what is forbidden. And be suspicious of any command that knows how to run other commands or edit arbitrary files (vim, less, find, awk, tar --to-command, systemctl without a fixed subcommand, any interpreter).
Safe rules:
| Practice | Reason |
|---|---|
| Always an absolute path | sudo my_script would search a PATH the user controls |
| Fixed arguments in the rule | systemctl restart tramontana.service, not plain systemctl |
| Avoid wildcards | /bin/chown operator /var/log/* allows /var/log/../../etc/shadow |
| Your own script with root:root 0755 permissions | If the user can edit it, the rule gives them full root |
NOPASSWD only where it is essential |
And never on a command with free-form arguments |
- Traceability: where
sudo leaves its trace
sudo leaves its trace$ sudo grep -F 'sudo:' /var/log/auth.log | tail -2
Aug 18 09:41:07 srv-tramontana sudo: operator : TTY=pts/0 ; PWD=/home/operator ; USER=root ; COMMAND=/usr/bin/systemctl restart tramontana.service
Aug 18 09:41:19 srv-tramontana sudo: luis : user NOT in sudoers ; TTY=pts/1 ; PWD=/home/luis ; USER=root ; COMMAND=/usr/bin/apt install nginxThe same information is in the journal (journalctl -t sudo, which we will see in 05-06). Failed attempts are logged just the same, and they are the cheapest alarm signal a server has.
If you need more, sudoers can record the entire session with Defaults!SERVICE log_input, log_output and Defaults iolog_dir=/var/log/sudo-io; it is played back with sudoreplay -l and sudoreplay ID. Careful: it records what is typed, including passwords typed by mistake, so that directory is sensitive material and its retention must be agreed.
- Recovering from a broken
sudoers
sudoersIf you saved an invalid sudoers without visudo, any sudo answers with something like >>> /etc/sudoers: syntax error near line 22 <<< and refuses to work. Ways out, in order of preference:
- A root session still open in another terminal: fix it from there. That is why it pays to have one open while you touch these files.
pkexec, which uses polkit and does not depend onsudoers:pkexec visudo(it requires a polkit rule to exist for your user, which is usual on desktop installations).- Recovery mode: reboot, choose Advanced options → recovery mode → root shell, remount with
mount -o remount,rw /and runvisudo. The full procedure is the subject of 07-01.
The habit that avoids all of this: always edit with visudo, and before you close the session, check in another terminal that sudo -l still works.
- SUID: real UID versus effective UID
Every process carries two identities: the real UID (who launched it) and the effective UID (the one permissions are checked against). Normally they match. The SUID bit breaks that equality: when a binary with SUID is executed, the kernel sets the effective UID to that of the file's owner, not that of whoever runs it.
The canonical example is passwd, which has to write to /etc/shadow (640 root:shadow) while being invoked by an ordinary user:
That s in place of the owner's x is SUID. While it runs, passwd is root, and its code is written to do exactly one thing and nothing else.
A SUID root binary of your own is almost always a security flaw, because any slip inside the program — a call to system(), an inherited PATH, an overflow — turns into root for whoever invokes it. A shell script with SUID does not even work: Linux ignores the bit on interpreters, precisely because it is impossible to secure.
A mandatory audit on any server:
$ sudo find / -xdev -perm -4000 -type f -printf '%M %u %p\n' 2>/dev/null | head -4
-rwsr-xr-x root /usr/bin/su
-rwsr-xr-x root /usr/bin/sudo
-rwsr-xr-x root /usr/bin/passwd
-rwsr-xr-x root /usr/bin/mountKeep that list as a baseline. Any binary that appears afterwards and does not come from a package is an alarm. -perm -2000 does the same for SGID.
- SGID on directories: the teamwork bit
On an executable, SGID is the group's equivalent of SUID. But its important use is another one: on a directory, SGID makes everything created inside inherit the directory's group instead of the primary group of whoever creates it. It is the piece that makes shared work viable.
Without SGID, if operator (whose primary group is operator) leaves a backup in /srv/tramontana/backups, the file belongs to the operator group and luis cannot read it even though they are both in tramontana. With SGID:
$ sudo chmod 2770 /srv/tramontana/backups # 2 = SGID, 770 = rwxrwx---
$ ls -ld /srv/tramontana/backups
drwxrws--- 5 operator tramontana 4096 Aug 18 04:20 /srv/tramontana/backups
$ touch /srv/tramontana/backups/test && ls -l /srv/tramontana/backups/test
-rw-r----- 1 operator tramontana 0 Aug 18 09:55 /srv/tramontana/backups/testThe tramontana group without having asked for it: that is SGID. Apply it to the whole shared tree and not just to the root:
The SGID bit does not fix the permissions: if your umask is 027, the file comes out rw-r----- and the group can only read. For the group to write as well you need umask 007, or better, a default ACL (section 11).
- The sticky bit and
/tmp
/tmp/tmp is writable by everybody. Without extra protection, anybody could delete somebody else's temporary file, because the permission to delete depends on the directory, not on the file. The sticky bit corrects that: in a directory with sticky set, only the file's owner, the directory's owner and root can delete or rename it.
That final t is the sticky bit (octal 1). It is the reason why the mktemp in your Module 4 scripts is safe from the neighbour, even though it still needs a trap to clean up.
A summary of the three bits:
| Bit | Octal | Symbol | On an executable file | On a directory |
|---|---|---|---|---|
| SUID | 4 | u+s → rws------ |
Runs with the owner's UID | No effect on Linux |
| SGID | 2 | g+s → ---rws--- |
Runs with the group's GID | Children inherit the group |
| Sticky | 1 | +t → ------rwt |
No effect nowadays | Only the owner deletes |
chmod 4755 /usr/local/bin/tool # SUID + rwxr-xr-x
chmod 2775 /srv/shared # SGID + rwxrwxr-x ; 1777 would be stickyA capital S or T in ls -l means the special bit is set but the corresponding x is missing: nearly always a typo.
- Capabilities: the modern replacement for SUID
SUID is all or nothing: you hand over the whole of root to obtain a single faculty. Linux capabilities split root's privileges into about forty independent pieces, and they can be granted one at a time.
The textbook case: Tramontana wants to listen on port 80, and ports below 1024 require privilege. Instead of running the application as root:
$ sudo setcap 'cap_net_bind_service=+ep' /opt/tramontana/releases/3.2.1/bin/tramontana
$ getcap /opt/tramontana/releases/3.2.1/bin/tramontana
/opt/tramontana/releases/3.2.1/bin/tramontana cap_net_bind_service=epe is effective and p is permitted. Now the binary opens port 80 as svc-tramontana and cannot do anything else that root could. Other common ones: cap_net_raw (for a ping of your own), cap_dac_read_search (read any file: almost as dangerous as root, be careful), cap_sys_time.
capsh --print | head -3 # which capabilities your shell has right now
sudo setcap -r /path/binary # remove them; getcap -r / audits the whole systemReal warnings: capabilities are an extended attribute of the file, so they are lost when you copy it, when you replace the binary in a deployment and on a filesystem that does not support them. If deploy.sh replaces the release, they have to be applied again — or, better, let systemd do it with AmbientCapabilities in the unit, which is what we will build in 05-05.
- ACLs: permissions
ugo cannot express
ugo cannot expressThe classic model has three subjects: owner, group, others. Marta asks for something that does not fit there: "let Luis read /var/log/tramontana for diagnostics, but without putting him in adm, which gives access to every log on the system". With ugo you could only change the directory's group or open it up to "others". With ACLs, you give exactly that permission to that person.
$ getfacl /var/log/tramontana
# file: var/log/tramontana
# owner: svc-tramontana
# group: adm
user::rwx
group::r-x
other::---We grant read and traverse to luis, and make anything created afterwards inherit it:
sudo setfacl -m u:luis:rx /var/log/tramontana # on the directory
sudo setfacl -R -m u:luis:r /var/log/tramontana/*.log # on the current files
sudo setfacl -d -m u:luis:r /var/log/tramontana # DEFAULT ACL: future ones$ ls -ld /var/log/tramontana
drwxr-x---+ 2 svc-tramontana adm 4096 Aug 18 10:02 /var/log/tramontana
$ getfacl /var/log/tramontana | grep -A1 '^user:luis'
user:luis:r-x
mask::r-xThat + at the end of the permissions is the mark that an ACL exists; without it, ls -l would be lying to you by omission.
| Operation | Command |
|---|---|
| Add/modify | setfacl -m u:luis:r file (g:group:rw for groups) |
| Default ACL on a directory | setfacl -d -m u:luis:r directory |
| Remove one entry | setfacl -x u:luis file |
| Delete every ACL | setfacl -b file |
The mask (mask::) is the ceiling of effective permissions for every entry except user:: and other::. If the mask is r--, an entry of user:luis:rw- is effectively left at r--, and getfacl flags it with an #effective:r-- comment. And here is the trap: chmod g=... rewrites the mask, so a later chmod -R 750 can silently cancel all your ACLs. If you use ACLs, review them after any chmod on that path.
A requirement: the filesystem must be mounted with ACL support, which on Ubuntu 24.04's ext4 is enabled out of the box. And do not forget that cp does not copy ACLs unless you use -p or -a, nor does tar unless you use --acls.
- Extended attributes and immutability
Underneath the permissions there is one more layer: the filesystem attributes. The useful one for an administrator is i, immutable: the file cannot be modified, deleted, renamed or linked, not even by root, until the attribute is removed.
$ sudo chattr +i /etc/tramontana/app.conf && lsattr /etc/tramontana/app.conf
----i---------e------- /etc/tramontana/app.conf
$ sudo rm /etc/tramontana/app.conf
rm: cannot remove '/etc/tramontana/app.conf': Operation not permitted
$ sudo chattr -i /etc/tramontana/app.conf # so it can be edited againIt is a safety net against human error and against overenthusiastic scripts, not against an attacker with root (who can remove it just as you can). Another useful attribute is a (append-only), designed for log files: you can append, but not rewrite or truncate. And a practical warning: an immutable file breaks any automation that touches it, including apt and your own deploy.sh. Write it down in the HISTORY or you will pay for it at 4:20 in the morning.
- Tramontana case: the deployment
sudoers rule
sudoers ruleMarta approves the deployments, but the person who runs them is operator, who today has full sudo by virtue of being in the sudo group. The goal: let them do their job — manage the service and deploy — without total root, and let luis check the status without touching anything.
# /etc/sudoers.d/tramontana (mode 0440, root:root, edited with visudo -f)
# Service management and deployment of Tramontana Bookings.
# Reviewed by: Marta Vidal (operations) — 2026-08-18
Cmnd_Alias TRAMO_SERVICE = /usr/bin/systemctl start tramontana.service, \
/usr/bin/systemctl stop tramontana.service, \
/usr/bin/systemctl restart tramontana.service, \
/usr/bin/systemctl reload tramontana.service
Cmnd_Alias TRAMO_READ = /usr/bin/systemctl status tramontana.service, \
/usr/bin/systemctl is-active tramontana.service, \
/usr/bin/journalctl -u tramontana.service *
Cmnd_Alias TRAMO_DEPLOY = /home/operator/bin/deploy-safe
operator srv-tramontana = (root) TRAMO_SERVICE, TRAMO_READ, TRAMO_DEPLOY
luis srv-tramontana = (root) NOPASSWD: TRAMO_READ$ sudo visudo -c -f /etc/sudoers.d/tramontana
/etc/sudoers.d/tramontana: parsed OK
$ sudo -l -U luis
(root) NOPASSWD: /usr/bin/systemctl status tramontana.service, ...Details that are not decorative:
deploy-safeis a wrapper owned byroot:rootwith mode 0755 in/home/operator/bin/. If it belonged tooperatorand were writable by them, the rule would be equivalent to handing over full root: they could rewrite the script with/bin/bashinside. This is the most frequent flaw when granting "just one script".- The subcommands are fixed: plain
systemctlwould allowsystemctl edit, and from there to an editor as root is a single step. luishas read-only access and withNOPASSWD, because he calls it from his diagnostics panel.operatorremains in thesudogroup for as long as the transition lasts; the medium-term goal is to take them out and keep only these rules.
Compliance warning. A
sudorule is a grant of privilege with a direct impact on the system's security and on access to guests' personal data (the logs and the backups contain it). Every addition, change or withdrawal of rules must be documented, with a date and the person who authorised it, and it must be reviewed by the security or compliance officer (GDPR) before being applied in production. Reviewsudo -l -U userfor each account at least once a quarter and at every staff departure.
And the pieces from the previous sections applied to the project:
sudo chmod 2770 /opt/tramontana/shared/uploads /srv/tramontana/backups # SGID: inherited group
sudo setfacl -m u:luis:rx -m d:u:luis:r /var/log/tramontana # Luis reads logs without being in adm
sudo chattr +i /etc/tramontana/app.conf # nobody touches it by accidentCommon Mistakes and Tips
- Editing
/etc/sudoerswith a normal editor. One syntax error and you are locked out: alwaysvisudo, and keep a second terminal open while you edit. - A badly named file or one with the wrong permissions.
sudosilently ignores files in/etc/sudoers.d/that contain a dot or are not 0440. Check withsudo -l -U user. - Granting a script the user can edit. It is full root in disguise. The target of a rule must be
root:rootand not writable by its beneficiary. - Using wildcards or commands "that run things".
systemctl,vim,less,find,tar, any interpreter: all of them have a known route to a shell. Fix the subcommand and the arguments, and do not rely on!to deny: blacklists are always bypassed. - Applying SGID only to the top folder of a shared tree: the existing subdirectories do not inherit it; use
find -type d -exec chmod g+s {} +. - Losing the capabilities in a deployment.
setcaplives in the file; if you replace the binary, it disappears. Declare it in the systemd unit. - A
chmodthat wipes out the ACLs by rewriting the mask: after anychmodon a path with a+, verify withgetfacl. - Tip: keep the baseline of
find / -perm -4000and ofgetcap -r /next to theHISTORY. Comparing that list is the cheapest and most effective audit you can carry out.
Exercises
- A minimal, correct rule. The intern must be able to restart only
tramontana.serviceand see its status, with no password for the status and with a password for the restart. Write the file, install it with the right permissions, validate it and demonstrate thatsudo systemctl restart nginxis forbidden to them. - A SUID audit. Find the system's SUID binaries, check which package each one belongs to and explain why finding
/usr/local/bin/utilwith SUID root would be an alarm. - A write ACL for a third party. Marta needs to drop a rates file into
/srv/tramontana/backups/outgoing/without belonging to thetramontanagroup. Grant her write access only in that subdirectory, with inheritance, and verify the effective mask.
Solutions
1.
# /etc/sudoers.d/intern, created with: sudo visudo -f /etc/sudoers.d/intern intern srv-tramontana = (root) NOPASSWD: /usr/bin/systemctl status tramontana.service intern srv-tramontana = (root) PASSWD: /usr/bin/systemctl restart tramontana.service
$ sudo chmod 0440 /etc/sudoers.d/intern && sudo visudo -c -f /etc/sudoers.d/intern
/etc/sudoers.d/intern: parsed OK
$ sudo -l -U intern
(root) NOPASSWD: /usr/bin/systemctl status tramontana.service
(root) /usr/bin/systemctl restart tramontana.serviceWhen trying what is forbidden, as intern:
Sorry, user intern is not allowed to execute '/usr/bin/systemctl restart nginx' as root on srv-tramontana.
Note that the list is a whitelist: we have not written a single prohibition, and everything not enumerated is left out by construction.
2.
$ sudo find / -xdev -perm -4000 -type f 2>/dev/null | while read -r f; do
printf '%-28s %s\n' "$f" "$(dpkg -S "$f" 2>/dev/null | cut -d: -f1 || echo '*** NO PACKAGE ***')"
done
/usr/bin/sudo sudo
/usr/bin/passwd passwd
/usr/local/bin/util *** NO PACKAGE ***/usr/local/bin/util does not belong to any package: nobody in the distribution vouches for it, it is not updated by apt and nobody has audited its code. With SUID root, any flaw in it — or any system() that inherits the PATH of whoever invokes it — hands root to any user on the system. A binary like that on a production server is investigated as a possible compromise, it is not "left there just in case".
3.
$ sudo setfacl -m u:marta:rwx -d -m u:marta:rw /srv/tramontana/backups/outgoing
$ getfacl /srv/tramontana/backups/outgoing
# file: srv/tramontana/backups/outgoing
# owner: operator
# group: tramontana
user::rwx
user:marta:rwx
group::rwx
mask::rwx
other::---
default:user:marta:rw-
default:mask::rw-u:marta:rwx on the directory lets her enter and create; the default: entry makes the files she leaves inside be born with rw- for her. The mask is rwx, so the effective permissions are the ones granted: if it were r-x, getfacl would flag #effective:r-x and Marta could not write despite the entry. And remember: a later chmod g=rx on that directory would rewrite the mask and cancel the permission without touching Marta's entry.
Conclusion
The magic of sudo is over, and so is that of the s you had been carrying since 02-07. You know that root does not have permissions but rather an absence of checks, and why that forces you to work with least privilege and traceability; you tell su from su - and sudo -s from sudo -i by the environment each one inherits; you understand env_reset, secure_path and why the redirection in sudo echo fails; you write sudoers rules with visudo, in /etc/sudoers.d/, with absolute paths, fixed arguments and in whitelist form, knowing that blacklists are bypassed from vim, find or awk; you know where the trace is left and how to get out of a broken sudoers.
And you have mastered the permission layer the ugo model does not cover: SUID and the difference between the real and the effective UID, with find -perm -4000 as an audit; SGID on directories so that a team really shares files, already applied to /opt/tramontana/shared/uploads and to /srv/tramontana/backups; the sticky bit that makes /tmp safe; the capabilities that replace an entire SUID with a single faculty such as cap_net_bind_service; the ACLs with which Luis reads /var/log/tramontana without joining adm, with their mask and their chmod trap; and chattr +i to armour /etc/tramontana/app.conf. In /etc/sudoers.d/tramontana there is a real, validated, documented rule that lets the service be operated without handing out root.
The next loose end is the software. You have been installing things with apt for four modules without asking where they came from, who signs them or what happens if the database engine jumps a major version one night while you sleep. In Package Management you will see Debian's two layers, dpkg and apt, the anatomy of a .deb, Ubuntu 24.04's deb822-format repositories with their keys in /etc/apt/keyrings/, how to pin versions so that Tramontana's database does not move on its own, and the uncomfortable debate about whether a server should reboot itself after a security update.
Linux Course: From Beginner to System Administrator
Module 1: Introduction to Linux
- What Is Linux?
- History of Linux
- Linux Distributions
- Installing Linux
- First Contact with the System
- The Linux File System Structure
Module 2: Basic Linux Commands
- Introduction to the Command Line
- Getting Help and System Documentation
- Navigating the File System
- File and Directory Operations
- Viewing and Editing Files
- Hard and Symbolic Links
- File Permissions and Ownership
Module 3: Advanced Command-Line Skills
- The Shell Environment: Variables, Aliases and History
- Using Wildcards and Regular Expressions
- Searching Files and Content: find, locate and grep
- Pipes and Redirection
- Text Processing: cut, sort, uniq, sed and awk
- Process Management
- Scheduling Tasks with Cron
- Networking Commands
Module 4: Shell Scripting
- Introduction to Shell Scripting
- Variables and Data Types
- Script Input, Output and Arguments
- Control Structures
- Functions and Libraries
- Debugging and Error Handling
- Production Scripts: Best Practices
Module 5: System Administration
- User and Group Management
- sudo and Special Permissions
- Package Management
- Disk Management
- systemd and Service Management
- System Logs: journald and syslog
- System Monitoring and Performance Tuning
- Backup and Restore
Module 6: Networking and Security
- Network Configuration
- SSH and Remote Access
- Firewalls and Perimeter Security
- Intrusion Detection Systems
- Secrets Management and TLS Certificates
- Securing Linux Systems
Module 7: Advanced Topics
- The Boot Process and System Recovery
- Advanced Diagnostics: strace, perf and eBPF
- Linux Kernel Tuning
- Virtualization with Linux
- Linux Containers and Docker
- Automation with Ansible
- High Availability and Load Balancing
