20.3 Restore Default File Contexts
Key Takeaways
- restorecon reapplies the default context from the policy file-context database to paths; restorecon -Rv is the standard recursive, verbose exam form for a tree.
- chcon changes a label immediately but is not persistent across full relabels the way a semanage fcontext rule is—prefer semanage fcontext + restorecon for custom paths that must survive.
- Add a durable mapping with semanage fcontext -a -t TYPE 'PATH_REGEX', then restorecon -Rv PATH so the live filesystem matches the new rule.
- Compare ls -Z (actual) with matchpathcon (expected) before and after restorecon to prove the fix; wrong types like default_t on web roots are classic restore targets.
- Do not use setenforce 0 or SELINUX=disabled as a substitute for correct labeling when the task expects Enforcing with proper contexts.
20.3 Restore Default File Contexts
Quick Answer: Fix wrong labels with
restorecon -Rv /path. For custom locations that policy does not already map, add a permanent rule withsemanage fcontext -a -t TYPE 'REGEX', thenrestorecon -Rv /path.chconchanges labels now but is the weaker long-term choice without an fcontext rule.
Why restore is a core EX200 skill
Under Manage security, Red Hat expects you to restore default file contexts. Lab wording looks like:
- “Restore the default SELinux context on
/var/www/html.” - “Ensure files under
/srv/webare labeled so Apache can serve them under Enforcing mode.” - “Persistently label
/data/shareaspublic_content_t(or another specified type).” - “Fix contexts after copying content from a home directory into a web root.”
You already know how to list contexts (20.2) and control mode (20.1). This section is the repair path: make the filesystem match policy defaults (or a durable custom mapping you define).
How default contexts are decided
SELinux maintains a file context database (path regex → default context/type). Tools consult it when you:
- Run
restorecon/fixcontext - Boot with a full relabel
- Query with
matchpathcon
matchpathcon /var/www/html
matchpathcon /srv/web
ls -Zd /var/www/html /srv/web
If actual (ls -Z) ≠ expected (matchpathcon), restore (or add a rule, then restore).
Default mappings cover standard FHS locations (/var/www, /home, /etc, …). Custom directories (/web, /srv/myapp, /data/html) often need an explicit semanage fcontext rule before restorecon can apply the type you want every time.
restorecon: the primary repair tool
sudo restorecon -v /var/www/html/index.html
sudo restorecon -Rv /var/www/html
sudo restorecon -Rv /srv/web
| Option | Purpose |
|---|---|
-v | Verbose: show changes |
-R | Recursive |
-F | Force reset even when the tool thinks context is already correct (use when stuck) |
-n | Dry-run (no change)—good for preview if available on the host |
Exam muscle memory:
sudo restorecon -Rv /path/to/tree
ls -Zd /path/to/tree
ls -Z /path/to/tree | head
restorecon sets contexts to whatever the policy database currently says for those paths. It does not invent a type for a path with no matching rule beyond the generic defaults—so custom trees may still show default_t until you add semanage fcontext.
After copy/move mistakes
# Classic problem: content copied from home into web root
sudo cp /home/alice/site/index.html /var/www/html/
ls -Z /var/www/html/index.html
sudo restorecon -Rv /var/www/html/index.html
ls -Z /var/www/html/index.html
Or recursive after bulk copy:
sudo cp -a /home/alice/site/. /var/www/html/
sudo restorecon -Rv /var/www/html
Note: cp -a preserves many attributes; depending on source type, you may still need restorecon so the destination policy wins.
chcon: immediate but not the durable pattern
sudo chcon -t httpd_sys_content_t /srv/web/index.html
sudo chcon -R -t httpd_sys_content_t /srv/web
ls -Z /srv/web
| Tool | Effect | Survives full relabel / “default restore” intent? |
|---|---|---|
chcon | Changes the context now on the inode | No durable policy mapping—later restorecon or autorelabel can overwrite it back to whatever the database says |
semanage fcontext + restorecon | Writes a permanent path rule, then applies it | Yes—the rule is the new default for matching paths |
When chcon appears in training: quick demos, or temporary experiments. When EX200 expects persistence: use semanage fcontext -a then restorecon.
# Temporary-only illustration — prefer fcontext for custom paths:
sudo chcon -R -t httpd_sys_content_t /srv/web
# After a restorecon without a rule, labels may snap back to default_t:
sudo restorecon -Rv /srv/web
ls -Zd /srv/web
That snap-back is the teaching point: chcon without fcontext is fragile.
Persistent labeling: semanage fcontext + restorecon
Add a rule
# Map /srv/web and everything below to httpd content type
sudo semanage fcontext -a -t httpd_sys_content_t '/srv/web(/.*)?'
sudo restorecon -Rv /srv/web
ls -Zd /srv/web
matchpathcon /srv/web /srv/web/index.html
| Piece | Meaning |
|---|---|
semanage fcontext -a | Add a local file context mapping |
-t TYPE | Target SELinux type |
'/srv/web(/.)?' | Regex: the directory and all descendants (quote it!) |
restorecon -Rv | Apply the database to the real files |
Regex tips:
- Quote patterns so the shell does not expand them.
'/srv/web(/.*)?'is the common “directory and below” form taught in Red Hat courses.- Be precise—over-broad regexes can relabel unintended trees.
List, modify, delete rules
sudo semanage fcontext -l | grep '/srv/web'
sudo semanage fcontext -l -C # local customizations only (handy)
# Replace type on existing local rule (syntax family):
sudo semanage fcontext -m -t httpd_sys_rw_content_t '/srv/web(/.*)?'
# Delete local rule:
sudo semanage fcontext -d '/srv/web(/.*)?'
sudo restorecon -Rv /srv/web
After delete, run restorecon again so files pick up whatever broader default now applies.
Equivalent mental pipeline
1) Decide correct TYPE for the service (e.g. httpd_sys_content_t)
2) semanage fcontext -a -t TYPE 'PATH_REGEX'
3) restorecon -Rv /actual/path
4) ls -Z / matchpathcon / test service under Enforcing
Common service scenarios
Web server DocumentRoot moved to /srv/web
sudo mkdir -p /srv/web
# populate content...
ls -Zd /srv/web
matchpathcon /srv/web
sudo semanage fcontext -a -t httpd_sys_content_t '/srv/web(/.*)?'
sudo restorecon -Rv /srv/web
getenforce # should be Enforcing when testing for real
# curl or browser test against the vhost
If writes are required (uploads), you may need httpd_sys_rw_content_t on specific subtrees—or a boolean from Chapter 21. Label the writeable tree correctly; do not blanket chmod 777 as a substitute.
Restore standard path after messy admin work
sudo restorecon -Rv /var/www/html
sudo restorecon -Rv /home/alice
Standard paths usually already have rules; restorecon alone is enough.
Samba/NFS/public files (type awareness)
Tasks sometimes specify types such as public_content_t or public_content_rw_t for shared data. Use the type the task names:
sudo semanage fcontext -a -t public_content_t '/data/public(/.*)?'
sudo restorecon -Rv /data/public
Do not invent exotic types—use what the exam scenario or man pages imply (man httpd_selinux, man samba_selinux when available).
restorecon vs chcon vs semanage (summary table)
| Goal | Tooling |
|---|---|
| Reset a standard path to policy default | restorecon -Rv PATH |
| Temporary/demo label change | chcon -t TYPE PATH (weak for persistence) |
| Custom path must stay labeled correctly | semanage fcontext -a -t TYPE 'REGEX' then restorecon -Rv |
| See expected default | matchpathcon PATH |
| See actual label | ls -Z / ls -Zd |
| See local rules | semanage fcontext -l -C |
Verification under Enforcing
getenforce
sudo setenforce 1 # if you had switched to permissive while testing
ls -Zd /srv/web
ls -Z /srv/web | head
matchpathcon /srv/web
ps -eZ | grep httpd
# functional test: HTTP request, file share access, etc.
If it only works in Permissive, labels (or booleans/ports) are still wrong—return to identification (20.2) and this restore flow, or Chapter 21 for booleans/ports.
Optional denial check
sudo ausearch -m avc -ts recent 2>/dev/null | tail
Absence of new AVCs after a correct restore is a good sign; presence points to remaining type/boolean/port issues.
Exam workflows
Workflow A — Standard tree restore
ls -Z /var/www/html | head
sudo restorecon -Rv /var/www/html
ls -Z /var/www/html | head
Workflow B — Custom web root persistent label
sudo mkdir -p /srv/web
sudo semanage fcontext -a -t httpd_sys_content_t '/srv/web(/.*)?'
sudo restorecon -Rv /srv/web
ls -Zd /srv/web
matchpathcon /srv/web
Workflow C — Prove chcon is not enough (lab learning)
sudo chcon -R -t httpd_sys_content_t /srv/web
ls -Zd /srv/web
sudo restorecon -Rv /srv/web
ls -Zd /srv/web # may return to default_t without fcontext rule
Workflow D — Fix after copy from home
sudo cp /home/alice/index.html /var/www/html/
ls -Z /var/www/html/index.html
sudo restorecon -v /var/www/html/index.html
ls -Z /var/www/html/index.html
Workflow E — Remove wrong local rule and re-restore
sudo semanage fcontext -l -C
sudo semanage fcontext -d '/srv/web(/.*)?'
sudo restorecon -Rv /srv/web
Common traps
chcononly on a custom path, then laterrestoreconor relabel undoes the “fix.”- Running
restoreconon a custom path withoutsemanage fcontextand expectinghttpd_sys_content_t. - Forgetting
-Rso only the top directory changes. - Wrong regex (unquoted glob, missing
(/.*)?, typo in path). - Fixing labels while leaving the host in Permissive, then never confirming under Enforcing.
- Using
setenforce 0or Disabled instead of restore—fails the spirit and often the letter of the task. - Confusing boolean problems with label problems—restore cannot replace
setseboolwhen policy needs a boolean (Chapter 21). - Relabeling the entire OS (
/.autorelabel) when a single tree restore would do—wastes time. - Not verifying with
ls -Zandmatchpathconafter changes. - Applying a type that allows read only when the app must write—need rw type or different path design.
Relationship to other sections
| Skill | Section |
|---|---|
| Modes | 20.1 |
| Identify contexts | 20.2 |
| Restore / persistent file labels | 20.3 (this) |
| Port labels (non-default listen ports) | 21.1 |
| Booleans | 21.2 |
| DAC permissions / umask | Chapters 5 / 19 |
SELinux file labels work with DAC: restore contexts and keep sane ownership/modes.
Section checkpoint
You should restore defaults with restorecon -Rv, understand that restore applies the policy file-context database, use chcon only with awareness that it is non-durable relative to that database, create persistent mappings with semanage fcontext -a -t TYPE 'REGEX' followed by restorecon, verify with ls -Z and matchpathcon, and keep the system Enforcing with correct labels rather than disabling SELinux. That meets the EX200 objective to restore default file contexts on RHEL 10.
Which command recursively restores default SELinux file contexts under /var/www/html and shows what changed?
Why is semanage fcontext + restorecon preferred over chcon alone for a custom web directory that must stay correctly labeled?
You added a custom DocumentRoot at /srv/web. restorecon alone leaves it as default_t. What is the correct persistent fix pattern?
After restorecon, which pair best verifies that the live label matches policy expectations?