Fedora

Samba File Share on Fedora: SELinux, Firewall and Clients

Most Samba guides treat a share as a block of text in smb.conf, and on Fedora that assumption breaks on the first write. A Samba share on Fedora is the agreement of four separate layers: firewalld has to let port 445 through, Samba has to know the user in its own password database, Linux permissions have to allow the mapped user, and SELinux has to see a label it lets smbd write to. The first two fail loudly, with an unreachable host or NT_STATUS_LOGON_FAILURE, but the last two both hand the client the same NT_STATUS_ACCESS_DENIED.

Original content from computingforgeeks.com - post 67022

We built a team share on a Fedora server, mounted it permanently on a Fedora client with systemd automount and opened it from a Mac, and the one failure we hit is the instructive part: listing the share worked, a local write as the same user worked, and only the remote write was refused. The sections below walk through how each layer makes its decision, then the fix and the encryption setting worth turning on. The behavior described here was checked against Samba 4.25 on Fedora 45 in October 2026.

How smbd decides whether a write succeeds

Every file operation from a client passes the same checkpoints in a fixed order, and knowing the order is what makes an access error readable. A failure at an early step usually produces a clear message, while the last two steps both surface as a plain access denied:

  1. firewalld accepts the TCP connection to port 445, or rejects it.
  2. smbd authenticates the user against its own database (tdbsam), not against /etc/shadow.
  3. The share’s valid users line decides whether that user may connect to this share at all.
  4. smbd switches to the user’s Linux UID and groups, so ordinary file permissions apply.
  5. SELinux checks whether the smbd_t domain may touch the file’s label.

Steps 4 and 5 are where Fedora differs from guides written for distributions without SELinux, because a directory can pass the permission check and still fail the label check. That is also why the same share works without this step on Ubuntu 26.04, which runs smbd unconfined unless you install and enforce the optional AppArmor profiles, and needs the same extra step on AlmaLinux and Oracle Linux. We’ll set up each layer in that order, so each one can be confirmed before the next one depends on it.

What the Samba packages give you

The server needs the samba package for smbd, samba-client for testing, and policycoreutils-python-utils for the semanage command used later. Our server started from the Fedora Cloud image, which ships without firewalld, so it got that too; on Fedora Server it’s already running:

sudo dnf -y install samba samba-client firewalld policycoreutils-python-utils
sudo systemctl enable --now firewalld smb

Only smb needs to run. The nmb service handles NetBIOS names and browsing, which clients connecting by DNS name or IP address don’t use, and it stayed inactive throughout our tests. smbd listens on 445 for SMB and on 139 for the older NetBIOS session transport:

sudo ss -tlnp | grep -E ":445|:139"

Both ports are open on IPv4 and IPv6, so smbd itself is ready before any share exists. Nothing in this output says a client can reach them yet, which is the next layer:

LISTEN 0      50           0.0.0.0:445       0.0.0.0:*    users:(("smbd",pid=1323,fd=29))
LISTEN 0      50           0.0.0.0:139       0.0.0.0:*    users:(("smbd",pid=1323,fd=30))
LISTEN 0      50              [::]:445          [::]:*    users:(("smbd",pid=1323,fd=27))
LISTEN 0      50              [::]:139          [::]:*    users:(("smbd",pid=1323,fd=28))

Listening is not the same as reachable. firewalld’s samba service covers both ports, and it isn’t open in the default zone until you add it (the firewalld guide for Fedora explains zones if your server uses a different one):

sudo firewall-cmd --permanent --add-service=samba
sudo firewall-cmd --reload
sudo firewall-cmd --info-service=samba | head -3

The service opens the two TCP ports smbd uses and includes the samba-client service for the NetBIOS UDP ports, so you do not need to open anything one by one. Opening it in the zone your server’s interface sits in is what matters:

samba
  ports: 139/tcp 445/tcp
  protocols: 

Fedora’s default smb.conf already defines [homes] and two printer shares, which is why a client lists more shares than the one you create. The [homes] share only works after you also turn on the samba_enable_home_dirs SELinux boolean, which is off by default; we leave it alone and build a dedicated share instead.

Why the share directory gets its own group

Step 4 of the checklist means smbd writes as whichever Linux user logged in, so a share used by several people needs a group that owns the directory and a setgid bit that keeps new files in that group. Without the setgid bit, each file would get its creator’s primary group, and the next colleague couldn’t edit it. Create the group, add each user, and give the directory mode 2770:

sudo groupadd smbshare
sudo usermod -aG smbshare gedion
sudo mkdir -p /srv/samba/shared
sudo chgrp smbshare /srv/samba/shared
sudo chmod 2770 /srv/samba/shared
ls -ldZ /srv/samba/shared

The s in the group permissions is the setgid bit. Look at the SELinux label too, because it is the one layer this setup hasn’t touched yet, and it is the one an ls -l without -Z never shows:

drwxrws---. 1 root smbshare unconfined_u:object_r:var_t:s0 0 Oct 20 12:28 /srv/samba/shared

A directory created under /srv inherits var_t, a generic label that SELinux doesn’t associate with Samba. We kept it that way on purpose for the first test, so the failure it causes is visible.

What the share definition controls

The share stanza names the path, restricts it to the group with valid users = @smbshare, and sets the modes Samba applies to new files and directories, which keeps them group-writable. That valid users line is layer 3 of the checklist, so a user who authenticates but is not in the group gets refused before Linux permissions are even consulted. Keeping the group check in both places is deliberate, because a later chmod mistake on the directory then still leaves outsiders out. Open the main configuration file:

sudo vim /etc/samba/smb.conf

Add the share at the end of the file. A mask can only remove permission bits, so the setgid bit on new folders comes from the kernel, which copies it from the setgid parent; a folder we created over SMB came out as drwxrws--- owned by group smbshare:

[shared]
	comment = Team share
	path = /srv/samba/shared
	valid users = @smbshare
	read only = no
	browseable = yes
	create mask = 0660
	directory mask = 2770

Validate the file before restarting anything. testparm parses the whole configuration and prints the effective share, and warns about any parameter name it doesn’t recognize, so a typo shows up before smbd silently ignores it:

testparm -s 2>&1 | sed -n "/\[shared\]/,\$p"
testparm -s 2>&1 | head -3

browseable = yes is the default, so it disappears from the share, and the directory mask gains a leading zero. The GnuTLS line in the header is informational, not an error:

[shared]
	comment = Team share
	create mask = 0660
	directory mask = 02770
	path = /srv/samba/shared
	read only = No
	valid users = @smbshare
Load smb config files from /etc/samba/smb.conf
Loaded services file OK.
Weak crypto is allowed by GnuTLS (e.g. NTLM as a compatibility fallback)

Why Samba keeps its own passwords

SMB authentication uses NTLM or Kerberos exchanges that need a hash format /etc/shadow does not store, so Samba keeps a separate database. A Linux account with a perfectly good login password cannot connect until it also has a Samba password. Add one for each user; smbpasswd prompts twice:

sudo smbpasswd -a gedion
sudo pdbedit -L
sudo systemctl restart smb

pdbedit -L lists the accounts in that database with their UID. Each entry must match an existing Linux user, because step 4 switches to that UID, and Samba has no account to switch to otherwise:

gedion:1001:fedora Cloud User

The two passwords are independent from here on. Changing the Linux one with passwd leaves the Samba one untouched, which is a common reason for a share that “suddenly” rejects a user after a password rotation.

What SELinux does to an unlabeled share

With the first four layers in place, we connected from the Fedora client. Testing from a second machine matters here, because smbclient //localhost/shared on the server never crosses the firewall, and a plain touch there runs in your shell’s SELinux context instead of smbd_t, so either can pass while every real client fails. Install the client tools there, then list the shares and try a listing and an upload in one session:

sudo dnf -y install samba-client cifs-utils
smbclient -L //10.0.1.50 -U gedion
smbclient //10.0.1.50/shared -U gedion -c "ls; put /etc/hostname hello.txt"

Authentication worked and the listing worked, so layers 1 to 3 were fine, and reading a directory is something SELinux allows smbd on many labels. Creating a file is where the failure appeared:

  .                                   D        0  Tue Oct 20 12:28:45 2026
  ..                                  D        0  Tue Oct 20 12:28:45 2026

		20865024 blocks of size 1024. 19179380 blocks available
NT_STATUS_ACCESS_DENIED opening remote file \hello.txt

Writing the same directory locally as the same user succeeded with sudo -u gedion touch, which rules out layer 4. That leaves SELinux, and the denial is in the audit records the moment the upload fails. Search them for smbd’s process name:

sudo journalctl _TRANSPORT=audit --since "-20 min" --no-pager | grep -m1 smbd

The record names the denied operation (create), the domain doing it (smbd_t), the label it hit (var_t) and permissive=0, meaning SELinux enforced it. The client address appears in the process name, shown here as 10.0.1.51:

Oct 20 12:29:09 node-a audit[1657]: AVC avc:  denied  { create } for  pid=1657 comm="smbd[10.0.1.51]" name="hello.txt" scontext=system_u:system_r:smbd_t:s0 tcontext=system_u:object_r:var_t:s0 tclass=file permissive=0

The fix is a label, not a boolean. Register a file-context rule for the whole tree so the label survives a relabel, then apply it with restorecon:

sudo semanage fcontext -a -t samba_share_t "/srv/samba(/.*)?"
sudo restorecon -Rv /srv/samba

restorecon reports each relabeled path. Because the rule is now in the policy, a full filesystem relabel later sets the same type instead of reverting it to var_t:

Relabeled /srv/samba from unconfined_u:object_r:var_t:s0 to unconfined_u:object_r:samba_share_t:s0
Relabeled /srv/samba/shared from unconfined_u:object_r:var_t:s0 to unconfined_u:object_r:samba_share_t:s0

The same upload from the client now works, and on the server the new file shows each layer doing its job: the uploader as owner, smbshare as group from the setgid bit, mode 660 from the create mask, and the inherited samba_share_t label:

-rw-rw----. 1 gedion smbshare system_u:object_r:samba_share_t:s0 7 Oct 20 12:30 hello.txt

The whole fix, from the audit record to the relabeled file, fits on one screen of the server:

Samba smbd_t create denied on var_t and samba_share_t relabel on Fedora 45

You’ll also find the samba_export_all_rw boolean recommended for this error. It works by letting smbd write to almost every file on the system, which is a much bigger change than labeling one directory, so keep it for the rare case where the data has to stay under a label another service needs. The SELinux survival guide for Fedora covers semanage fcontext in more detail.

How the client mounts the share at boot

A permanent mount should keep the password out of /etc/fstab, which every user can read, and should not hold up boot when the server is unreachable. A root-only credentials file solves the first problem, and x-systemd.automount solves the second by mounting on first access instead of during boot. Create the credentials file on the client:

sudo vim /etc/samba-shared.cred

Put the Samba username and password in it, one per line. These are the Samba credentials from smbpasswd, not the Linux login, which is easy to mix up when they differ:

username=gedion
password=YourSambaPassword

Lock it down, create the mount point and add the fstab entry. The uid and gid options decide which local user owns the files on the client, because the CIFS client does not map server UIDs by default:

sudo chmod 600 /etc/samba-shared.cred
sudo mkdir -p /mnt/shared
echo "//10.0.1.50/shared  /mnt/shared  cifs  credentials=/etc/samba-shared.cred,uid=$(id -u),gid=$(id -g),_netdev,x-systemd.automount  0 0" | sudo tee -a /etc/fstab
sudo systemctl daemon-reload
sudo systemctl start mnt-shared.automount
ls -l /mnt/shared

We rebooted the client to test it (journalctl --list-boots showed the new boot), and findmnt showed only the autofs trigger until the first ls, then the CIFS mount stacked on top of it:

TARGET      SOURCE                 FSTYPE
/mnt/shared systemd-1              autofs
/mnt/shared //10.0.1.50/shared     cifs

The kernel client negotiated SMB 3.1.1 (vers=3.1.1 in the mount options) with no version pinned. Files on the mount appear as -rwxr-xr-x owned by the local user, even though the server stores them as -rw-rw----; the client synthesizes those modes from the mount options, and the server’s permissions are still what decides each write.

What a Mac sees on the same share

We mounted the share from macOS with mount_smbfs, wrote a file, and asked smbutil what had been negotiated. In Finder, the same connection is Go, Connect to Server and smb://10.0.1.50/shared:

mkdir -p ~/smbmnt
mount_smbfs "//[email protected]/shared" ~/smbmnt
smbutil statshares -m ~/smbmnt | grep -E "SMB_VERSION|SMB_ENCRYPT|SIGNING|SERVER_NAME"

The Mac also landed on SMB 3.1.1 and advertised all four AES ciphers, so it can meet whatever encryption level the server asks for:

                              SERVER_NAME                   10.0.1.50
                              SMB_VERSION                   SMB_3.1.1
                              SMB_ENCRYPT_ALGORITHMS        AES_128_CCM_ENABLED
                              SMB_ENCRYPT_ALGORITHMS        AES_128_GCM_ENABLED
                              SMB_ENCRYPT_ALGORITHMS        AES_256_CCM_ENABLED
                              SMB_ENCRYPT_ALGORITHMS        AES_256_GCM_ENABLED
                              SIGNING_SUPPORTED             TRUE

The file the Mac wrote arrived on the server as -rw-rw----. gedion smbshare, the same as the Linux client’s, because ownership and modes come from the server side of the checklist, not from the client.

Why encryption is off until you ask for it

Samba’s defaults on Fedora already refuse the oldest protocols and the weakest authentication, but they do not encrypt traffic. testparm -sv prints every effective value, so filter it to the settings that matter here:

testparm -sv 2>/dev/null | grep -E "^\s*(server min protocol|server max protocol|server smb encrypt|server signing|ntlm auth) "

On a share with no encryption setting yet, the values were:

	ntlm auth = ntlmv2-only
	server max protocol = SMB3
	server min protocol = SMB2_02
	server signing = default
	server smb encrypt = default

With default, encryption is negotiated only if the client asks, and our first smbstatus showed the Fedora client’s session signed but unencrypted. To make the server insist on it for this share, open the configuration again:

sudo vim /etc/samba/smb.conf

Add one line to the [shared] stanza; testparm reports it under its canonical name, server smb encrypt:

	smb encrypt = required

Reload smbd so new connections pick it up:

sudo smbcontrol smbd reload-config
sudo smbstatus -S

In our test the Fedora client’s session came back encrypted within seconds of the reload, with no action on the client, and it stayed that way after a later client reboot, when the automount reconnected with AES-128-GCM:

Service      pid     Machine       Connected at                     Encryption   Signing     
---------------------------------------------------------------------------------------------
IPC$         3641    10.0.1.51     Tue Oct 20 12:46:41 PM 2026 UTC  -            -           
shared       3641    10.0.1.51     Tue Oct 20 12:46:41 PM 2026 UTC  AES-128-GCM  AES-128-CMAC

Clients that can’t encrypt are refused on a required share, so check old printers, scanners and NAS backup jobs before you set it on a share they use. Both of our clients connected without any change on their side: the Fedora mount needed no new options, and the Mac reported SMB_CURR_ENCRYPT_ALGORITHM AES-128-GCM and ENCRYPTION_REQUIRED TRUE for the share.

Common misconceptions about Samba on Fedora

Most Samba problems on Fedora come from carrying over an assumption that was true somewhere else. These are the ones our lab disproved:

  • “My Linux password logs in to Samba.” It doesn’t; smbpasswd -a creates a separate password that you have to rotate separately.
  • “Access denied means wrong permissions.” On Fedora it is just as often the SELinux label, and the audit record names the exact operation and label that failed.
  • “chmod 777 will fix it.” It changes layer 4 only; a var_t directory stays unwritable to smbd at any mode.
  • “You need nmb running.” Clients that connect by DNS name or IP address only need smbd on 445; nmb serves NetBIOS names and browsing, and SMB1 is off anyway, which is why smbclient -L printed SMB1 disabled -- no workgroup available.
  • “Client file modes are the server’s modes.” A CIFS mount shows modes built from its mount options; the server still enforces its own.

If you hold on to one model from all this, make it the five checkpoints in order. When a share misbehaves, find the first checkpoint that fails instead of changing settings at random. The Fedora hardening guide covers the firewall and SELinux side of the server beyond Samba.

Keep reading

How to Upgrade Fedora 44 to Fedora 45 (GUI, CLI and Rollback) Fedora How to Upgrade Fedora 44 to Fedora 45 (GUI, CLI and Rollback) Enable RPM Fusion and Install Multimedia Codecs on Fedora 45 / 44 / 43 Fedora Enable RPM Fusion and Install Multimedia Codecs on Fedora 45 / 44 / 43 Harden Fedora 45 / 44 for Desktop and Server: Complete Guide Fedora Harden Fedora 45 / 44 for Desktop and Server: Complete Guide Switch Fedora From GRUB to systemd-boot With bootctl Fedora Switch Fedora From GRUB to systemd-boot With bootctl DNF5 Cheatsheet for Fedora 45 / 44: Tested Commands and Fixes Fedora DNF5 Cheatsheet for Fedora 45 / 44: Tested Commands and Fixes Install Java 21 LTS (OpenJDK) on RHEL 10 / Rocky Linux 10 / AlmaLinux 10 CentOS Install Java 21 LTS (OpenJDK) on RHEL 10 / Rocky Linux 10 / AlmaLinux 10

Leave a Comment

Press ESC to close