cswork / libraryOpen practice workspace

Articles

SELinux Interview Questions: Diagnose Access Denials Without Disabling Enforcement

Practice SELinux interview questions with a worked AVC denial, persistent file labels, port and boolean decisions, and checks that keep enforcement enabled.

A web server returns “permission denied.” The file is readable, the directory permissions look reasonable, and restarting the service changes nothing. An interviewer asks what you would do next. A useful SELinux answer starts by identifying the denied access and ends by proving a narrow, persistent repair.

The central idea: Unix permissions, SELinux labels, service configuration, and the application's intended behavior answer different questions. Trace all four before deciding which one to change. Disabling enforcement supplies neither a durable diagnosis nor a suitably scoped fix.

Evidence boundary: This guide uses official RHEL 9 documentation and upstream command manuals checked on October 4, 2026. The web-service trace below is an original interview exercise, not output captured from a running host. Policy types and available tools depend on the installed distribution and policy. No candidate reports are used to claim that a particular employer asks these questions.

If you want a broader troubleshooting prompt first, practice How would you troubleshoot Linux services?, then return to the specific denial below.

Why can SELinux reject access when Unix permissions allow it?

Official fact: SELinux provides mandatory access control. In enforcing mode, policy denials are enforced; permissive mode allows accesses that policy would deny while recording relevant audit events. A process domain and an object's security context matter beyond ordinary ownership and mode bits. See the SELinux manual.

For an interview, explain the checks separately. Does the actual service identity have ordinary access to the file and each parent directory? What SELinux domain is the requesting process running in? What label does the object actually carry? Does the active policy permit that domain to perform this operation on this object class and type?

A successful read from an administrator's shell does not answer the service-domain question. Likewise, changing a file to be world-readable cannot establish an SELinux permission. The same pathname can appear in two tests with different identities, domains, namespaces, or mounts. State which test reproduced the failure before interpreting its result.

A compact answer is: “I would correlate the failed service request with an AVC, inspect its source and target contexts, and compare the intended file label with the actual one. I would keep enforcement enabled while testing the scoped repair.”

Read an AVC as an access request, not a command recommendation

Consider this original, abbreviated fixture. Apache serves static content from /srv/interview-site. Assume ordinary file access and directory traversal have already been checked under the service identity. A deployed file retained a home-directory label.

avc: denied { read } for pid=4201 comm="httpd"
path="/srv/interview-site/index.html"
scontext=system_u:system_r:httpd_t:s0
 tcontext=unconfined_u:object_r:user_home_t:s0
 tclass=file permissive=0

The line is schematic; a real audit event contains additional fields. Read it as a structured statement:

EvidenceInterpretation in this exerciseNext check
httpd_t in scontextThe requester is in the web-server domainConfirm the PID/domain matches the affected service
user_home_t in tcontextThe file carries a home-content typeCompare its actual and expected labels
{ read }, tclass=fileThe denied operation concerns reading a fileAvoid investigating a port-binding problem first
permissive=0This event describes an enforced denialCorrelate it with the failing request and timestamp
File path and process informationUseful correlation cluesInspect related records in the same audit event

Inference from the fixture: A label mismatch is a strong hypothesis because static site content and a home-content type do not fit the stated design. It is not proof that every user_home_t denial should be relabeled. The application could be trying to read a private home file that should remain inaccessible.

Use a fresh reproduction window. Official guidance: Red Hat starts denial investigation with Audit records and cautions against generating an allow module before checking labels and service configuration. Its troubleshooting chapter also explains that missing search results require checking the logging path.

getenforce
sudo ausearch -m AVC,USER_AVC,SELINUX_ERR,USER_SELINUX_ERR -ts recent
ps -eZ
ls -Zd /srv/interview-site
ls -Z /srv/interview-site/index.html

These are diagnostic examples, not commands executed for this article. The ausearch manual documents message-type and time filters and event-oriented output. Record the request time, relevant event identifier, executable, and path. A pile of older denials can send you toward an unrelated repair.

What makes a label repair persistent?

The important distinction is between the label currently stored on an object and the configured label expected for a pathname.

Official fact: chcon changes a file's security context. It does not create a persistent pathname-to-label rule. semanage fcontext manages those rules; restorecon applies the expected context to files. Their manuals describe separate responsibilities: chcon, semanage fcontext, and restorecon.

This distinction gives you a useful follow-up answer. A label changed manually may remain on the same inode across a reboot, yet a subsequent restore operation or replacement file can expose the missing persistent configuration. “Temporary” does not mean that every reboot necessarily erases chcon.

For the exercise, first inspect expected labels with matchpathcon, which compares paths against file-context definitions. Its manual documents verification with -V. Also inspect existing local customizations before adding another rule.

matchpathcon /srv/interview-site/index.html
sudo semanage fcontext -l -C

Official RHEL example, adapted to our path: Static Apache content in a nonstandard directory can use httpd_sys_content_t. The configuration and relabeling are separate steps in Red Hat's nonstandard-service configuration guidance.

# Example assumes this exact local rule does not already exist.
sudo semanage fcontext -a -t httpd_sys_content_t \
  '/srv/interview-site(/.*)?'

# Preview label changes, then apply within the intended tree.
sudo restorecon -nRv /srv/interview-site
sudo restorecon -Rv /srv/interview-site
matchpathcon -V /srv/interview-site/index.html

If the exact local rule already exists, review and modify it deliberately rather than repeatedly adding it. Avoid a broad /srv(/.*)? rule when only one subtree is website content. The semanage fcontext manual warns that local rule ordering has special precedence; a newer broad rule can defeat your intended labeling.

Reasoning about scope: This service only needs to read static content. A writable-content type would grant a different class of access and needs a separate design justification. Identify upload or cache directories separately instead of treating every website file as writable.

How do labels, port mappings, booleans, and policy changes differ?

Do not pick a repair solely because a search result contains the word “httpd.” Start with the denied operation and object class.

Original follow-upEvidence to inspectDecision to explain
The service cannot read static contentFile context, expected context, parent directoriesRepair a justified label mismatch
The service cannot bind its configured portname_bind, socket class, protocol and port typeInspect the relevant SELinux port mapping
The service cannot connect to its databaseDestination, operation, service policy and booleansDetermine whether an existing supported option fits
A correctly configured custom service needs new accessDomain, object types, required operations and policy versionReview a minimal policy change with the security owner

Official fact: semanage port manages SELinux port definitions. A port label is not a firewall rule, and changing it does not establish that a process can bind an occupied socket. Inspect the protocol as well as the port number. See the port-management manual.

For the database case, describe the intended connection before selecting a boolean. Official fact: getsebool displays boolean state. Supported booleans and their meaning are policy-specific; consult the installed service policy documentation instead of enabling every similarly named switch. See getsebool.

Inference: An access attempt that contradicts the service's design could reflect a configuration bug or compromise. A denial is evidence about an attempted operation, not an instruction to authorize it. Generated allow rules need review for their domain, type, class, permission, and expected lifecycle. In a supported RHEL environment, also check the vendor's guidance and support boundaries before adopting a custom module.

What if no AVC appears, or the first fix reveals another denial?

“No matching AVC” is an observation about one search, not a complete verdict about the host. Confirm the time window and machine, check whether the Audit daemon is running, and inspect the relevant journal or available kernel messages. Some denials can be suppressed by dontaudit rules. Changing diagnostic logging and changing enforcement are separate actions; any temporary logging change needs a planned restoration.

A request can also fail through ordinary permissions, application configuration, missing files, mount behavior, or another security layer. Explain what evidence would distinguish these possibilities. Reproducing the request once with a known timestamp is usually more informative than changing several controls together.

In our exercise, fixing the file label might expose a directory-search denial earlier in the path, or the request could now reach an application error. Recheck the exact operation. Do not declare success merely because the original AVC stopped appearing.

A second denial deserves a second diagnosis. It does not automatically justify extending the first repair to a larger subtree or generating permissions for everything the process attempted during an unrelated workload.

Prove the repair through a deployment regression

This original verification matrix distinguishes an operational fix from a one-time successful read:

TestExpected resultWhy it matters
Fetch the intended static page under enforcing modeCorrect response from the actual serviceConfirms the user-visible operation
Verify the page and directory labelsMatch the approved file-context ruleChecks the explanation behind the response
Replace the page using the real deployment mechanismRelabel if needed; page remains readable afterwardExercises newly created or moved files
Attempt an unrelated private-file read through the same domain in a controlled testRemains denied under the intended policyDetects an overly broad repair
Recheck the fresh audit windowNo unexplained denial for the intended requestConfirms the diagnosis rather than log disappearance

State how deployment applies labels. A persistent rule gives relabeling tools a durable target; it does not guarantee that every copying or moving mechanism automatically applies that target. Treat label verification as part of the deployment contract.

A clear interview close is: “The observed requester was httpd_t, the target carried user_home_t, and the operation was file read. For this approved static-content subtree, I configured the expected content type and applied it with restorecon. I would verify the request and a fresh deployment under enforcement, then confirm unrelated access remains restricted.”

Sources and Further Reading