Securing network services with SELinux: NFS labeling and mount options including noexec, the consequences of storage shared between hosts, samba booleans and contexts for exporting directories and homes, and port labeling for non-standard services.

In episode 10, you protected containers — but data still has to move between hosts. File sharing through NFS and Samba is the backbone of enterprise environments: shared storage for applications, user home directories, and data used by many servers at once. Unfortunately, once data crosses the network, the SELinux labeling rules you've learned become more complicated.
This episode 11 covers three things: how labels survive (or don't) on NFS, how Samba interacts with file types and booleans, and port labeling for non-standard services.
On a local filesystem, file labels are determined and managed by the host itself. With NFS, the story is different: exported files don't carry the SELinux labeling system automatically. As a consequence, from the client's side, NFS files appear with a special type called nfs_t:
ls -Z /mnt/web/index.htmlThe problem is that nfs_t is a very permissive type: almost all domains are allowed to read it. For ordinary data that's fine, but for sensitive data it's an open invitation. Labeling with semanage fcontext on the client side has no effect on NFS files — labels come from the server, not the client.
The solution is to force the label at mount time with the context option:
sudo mount -t nfs -o context="system_u:object_r:httpd_sys_content_t:s0" server:/export /mnt/webImportant
The context= option forces the entire share contents to use one identical type — low flexibility, but that's exactly its strength: you know precisely who's allowed to read that data. Alternatively, use NFS with NFS labeling (security labels) support when both sides and the filesystems support it, so labels are sent from the server along with every file. Unfortunately not all kernels and filesystems are ready, so context= remains the most portable choice.
Note that NFS allows binary execution from a mount by default. For shares that only store data (backup, upload, archives), execution is pure risk: an attacker who manages to drop a binary on the share doesn't need extra effort to run it. Mounting with noexec closes that gap:
sudo mount -t nfs -o noexec,nodev,nosuid server:/data /mnt/dataAlso combine nodev and nosuid for general-purpose shares. The rule of thumb: shares whose contents aren't programs — always noexec.
One directory shared by many hosts carries labeling consequences that often go unnoticed:
context= options, the result is a confusing denial on one side. Set one standard context per share, and propagate it to all hosts.s0:c1 can only be read by hosts or processes whose level matches. Make sure all share consumers have the same level range, or MCS denials will appear silently.restorecon on the client side doesn't change NFS file labels. Label changes must go through the server or mount options — don't waste debugging time in the wrong direction.Warning
Don't treat an NFS share as a "just dump it there" place without thinking about level and type. Two hosts with different policies writing to the same share is one of the hardest SELinux denials to diagnose in production — because the error appears on the side that isn't writing. Document the type and level of every share, and apply it with provisioning tooling so it's consistent from the start.
Samba (the SMB/CIFS protocol) exports Linux directories to Windows and Linux clients. The smbd daemon runs in the smbd_t domain, and its rules follow the patterns you already know: shared directories must have a special label, and booleans control the scope of exports.
Dedicated share directories are labeled samba_share_t:
sudo semanage fcontext -a -t samba_share_t "/srv/share(/.*)?"
sudo restorecon -Rv /srv/shareAfter that, add the directory to the Samba configuration and smbd_t can read its contents. Three main booleans control the export scope:
| Need | Solution |
|---|---|
| Export user home directories | samba_enable_home_dirs on |
| Export all files smbd can read | samba_export_all_ro on |
| Export all files with write access | samba_export_all_rw on |
User homes need a special boolean because home directories are labeled user_home_t — a type smbd_t may not read by default. Enabling samba_enable_home_dirs lets smbd into homes in a controlled way:
sudo setsebool -P samba_enable_home_dirs onTip
samba_export_all_rw and samba_export_all_ro are emergency doors: they allow smbd to read almost all files on the system, not just directories labeled samba_share_t. Use them only for short-term migration, then switch to proper directory labeling. A permanent "export all" is the same as opening up SELinux for the entire Samba service.
The principle you learned in episode 9 applies to all network services: a port the policy doesn't know is a port without a label, and a domain trying to bind or connect to it will hit a name_bind or name_connect denial. Look at the port labels already known:
semanage port -l | grep -E 'smbd|nfs'Standard ports are already labeled: smbd_port_t for 139 and 445, nfsd_port_t for 2049. When a service runs on a non-standard port — for example Samba on port 4450 or a web app on 8080 — add a new label:
sudo semanage port -a -t smbd_port_t -p tcp 4450
sudo semanage port -a -t http_port_t -p tcp 8080Note
Think of ports as a building's entry doors. The SELinux policy has a list of "official doors" for each domain: http_port_t for httpd, smbd_port_t for samba, and so on. Opening a new door without registering it in semanage port makes the security guard (SELinux) refuse anyone passing through — even though everything looks normal at the UNIX permission level. This is the source of the most confusing denials for those who don't yet understand it.
In this episode 11, you've understood the uniqueness of cross-network labeling: NFS files labeled with the permissive nfs_t and the context= solution at mount time with noexec, the consequences of sharing storage between hosts with different policies, samba booleans and the samba_share_t context for Samba exports, and non-standard port labeling with semanage port.
The key takeaways:
context= option and noexec for data.semanage port, not by turning off SELinux.Starting with this episode, we shift from securing built-in services to building protection for special cases. In episode 12, we'll discuss Virtualization & Custom Policies — protecting the KVM hypervisor and virtual machines, and writing custom policies from scratch for applications that have no built-in policy.