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.
Last updated: August 2026

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 with semanage fcontext -a -t TYPE 'REGEX', then restorecon -Rv /path. chcon changes 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/web are labeled so Apache can serve them under Enforcing mode.”
  • “Persistently label /data/share as public_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
OptionPurpose
-vVerbose: show changes
-RRecursive
-FForce reset even when the tool thinks context is already correct (use when stuck)
-nDry-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
ToolEffectSurvives full relabel / “default restore” intent?
chconChanges the context now on the inodeNo durable policy mapping—later restorecon or autorelabel can overwrite it back to whatever the database says
semanage fcontext + restoreconWrites a permanent path rule, then applies itYes—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
PieceMeaning
semanage fcontext -aAdd a local file context mapping
-t TYPETarget SELinux type
'/srv/web(/.)?'Regex: the directory and all descendants (quote it!)
restorecon -RvApply 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)

GoalTooling
Reset a standard path to policy defaultrestorecon -Rv PATH
Temporary/demo label changechcon -t TYPE PATH (weak for persistence)
Custom path must stay labeled correctlysemanage fcontext -a -t TYPE 'REGEX' then restorecon -Rv
See expected defaultmatchpathcon PATH
See actual labells -Z / ls -Zd
See local rulessemanage 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

  1. chcon only on a custom path, then later restorecon or relabel undoes the “fix.”
  2. Running restorecon on a custom path without semanage fcontext and expecting httpd_sys_content_t.
  3. Forgetting -R so only the top directory changes.
  4. Wrong regex (unquoted glob, missing (/.*)?, typo in path).
  5. Fixing labels while leaving the host in Permissive, then never confirming under Enforcing.
  6. Using setenforce 0 or Disabled instead of restore—fails the spirit and often the letter of the task.
  7. Confusing boolean problems with label problems—restore cannot replace setsebool when policy needs a boolean (Chapter 21).
  8. Relabeling the entire OS (/.autorelabel) when a single tree restore would do—wastes time.
  9. Not verifying with ls -Z and matchpathcon after changes.
  10. Applying a type that allows read only when the app must write—need rw type or different path design.

Relationship to other sections

SkillSection
Modes20.1
Identify contexts20.2
Restore / persistent file labels20.3 (this)
Port labels (non-default listen ports)21.1
Booleans21.2
DAC permissions / umaskChapters 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.

Test Your Knowledge

Which command recursively restores default SELinux file contexts under /var/www/html and shows what changed?

A
B
C
D
Test Your Knowledge

Why is semanage fcontext + restorecon preferred over chcon alone for a custom web directory that must stay correctly labeled?

A
B
C
D
Test Your Knowledge

You added a custom DocumentRoot at /srv/web. restorecon alone leaves it as default_t. What is the correct persistent fix pattern?

A
B
C
D
Test Your Knowledge

After restorecon, which pair best verifies that the live label matches policy expectations?

A
B
C
D