smbd -F | testparm | smbclient //server/share -U user
sudo systemctl status smbd
Samba is the Linux implementation of the SMB/CIFS protocol: the file and printer sharing that Windows uses ("\\server\share"). With Samba a
Linux server can share folders with Windows, macOS and Linux clients, act as a member of an Active Directory domain, or (advanced) even run
its own AD domain controller. This sheet covers file sharing: install, the smb.conf file, users, permissions, clients, joining AD, security and
troubleshooting. This is written for Samba 4.x, and file and service names differ a little between distributions (noted below).
Never expose SMB (port 445) to the internet. Keep it on trusted networks or behind a VPN, and keep Samba updated.
How it works (short)
smbd The main daemon: file and printer sharing (port 445/tcp, and 139/tcp for older NetBIOS clients)
nmbd NetBIOS name service and browsing (137/138/udp). Optional for modern networks. Often not needed if clients use names via DNS
winbindd Talks to Active Directory and maps domain users and groups to Linux IDs (needed for domain-member servers that use winbind)
smb.conf The single configuration file: /etc/samba/smb.conf
Samba passwords are separate from Linux passwords. A Samba user must ALSO exist as a Linux (system) account, but can have no shell.
The client asks for \\server\share, authenticates, and then gets access according to BOTH the share settings in smb.conf AND the ordinary Linux file permissions (or ACLs).
The effective access is the STRICTER of the two.
Install
sudo apt install samba smbclient cifs-utils # Debian/Ubuntu (add winbind libnss-winbind libpam-winbind for AD membership with winbind)
sudo dnf install samba samba-client cifs-utils # Fedora/RHEL family (add samba-winbind samba-winbind-clients for winbind)
smbd --version # version (also: samba --version)
Service names: Debian/Ubuntu smbd, nmbd RHEL family smb, nmb winbind on both
sudo systemctl enable --now smbd nmbd # RHEL: smb nmb
sudo systemctl status smbd
sudo systemctl reload smbd # re-read smb.conf (existing connections keep working) restart drops all connections
smbcontrol all reload-config # another way to reload after editing smb.conf
Back up the original file before you edit: sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.orig
Firewall and SELinux
sudo ufw allow samba # Ubuntu (opens 137,138 udp and 139,445 tcp) sudo ufw allow from 192.168.1.0/24 to any app Samba # only the LAN
sudo firewall-cmd --permanent --add-service=samba && sudo firewall-cmd --reload # RHEL family (firewalld)
Ports: 445/tcp is all that modern SMB2/3 clients need. 139/tcp and 137/138/udp are for NetBIOS (older Windows and network browsing).
SELinux (RHEL family): label the shared folders and allow the features you use
sudo semanage fcontext -a -t samba_share_t "/srv/samba(/.*)?"
sudo restorecon -Rv /srv/samba
sudo setsebool -P samba_enable_home_dirs on # share home directories through [homes]
sudo setsebool -P samba_export_all_rw on # BROAD: let Samba write anywhere. Prefer labeling specific folders instead
getsebool -a | grep samba # see all the Samba booleans
sudo ausearch -m avc -ts recent | grep smbd # SELinux denials (if a share "works on the console but not from Windows")
AppArmor on Ubuntu normally needs no change for standard paths.
smb.conf structure
[global] Settings for the whole server (identity, security, logging, protocol versions)
[share-name] One section per shared folder. The section name is what clients see: \\server\share-name
[homes] A special share: each user's own home directory
[printers] A special share for printing
Lines are key = value . A comment starts with # or ; Values with spaces need no quotes. Variables: %U user, %G primary group, %S current share name, %m client name, %h server name, %H home dir
Always check your syntax after editing, then reload:
testparm # checks smb.conf and prints warnings (press Enter to see the result)
testparm -s # print just the effective settings, no prompt
testparm -sv | grep -i "min protocol" # include defaults (-v), and search them
sudo systemctl reload smbd
A good starting configuration (standalone file server)
[global]
workgroup = WORKGROUP
server string = File Server
server role = standalone server
security = user
map to guest = Bad User # a wrong user name is treated as guest (only matters if you allow guest shares)
server min protocol = SMB2_10 # refuse the old, insecure SMB1 protocol
server signing = auto # use "mandatory" if all your clients support it
restrict anonymous = 2 # no anonymous listing of users and shares
hosts allow = 127.0.0.1 192.168.1. # only these networks (note the trailing dot)
hosts deny = 0.0.0.0/0
interfaces = lo eth0 # listen only on these
bind interfaces only = yes
log file = /var/log/samba/log.%m
max log size = 1000
logging = file
load printers = no
disable spoolss = yes # no printing
[public]
comment = Read-only public files
path = /srv/samba/public
guest ok = yes
read only = yes
[team]
comment = Team files
path = /srv/samba/team
valid users = @staff # only members of the Linux group "staff"
read only = no
browseable = yes
force group = staff # new files belong to this group
create mask = 0660 # permissions for new files
directory mask = 0770 # permissions for new folders
Share options you will use most
path = /srv/samba/team Folder on the server (must exist, with sensible Linux permissions)
comment = Text A description shown to clients
browseable = yes|no Show it in lists (no = hidden, but still reachable by name)
read only = yes|no yes is the default. Set no to allow writing (writable = yes / writeable = yes mean the same as read only = no)
guest ok = yes|no Allow access with no password (use rarely) public = yes is the same
valid users = alice @staff Only these users or groups (group names start with @). Others cannot connect
invalid users = bob Always denied
read list = @auditors Users who get read-only access even if the share is writable
write list = @editors Users who get write access even if the share is read only
admin users = alice Act as root inside the share (powerful. Use sparingly)
force user = fileowner Everyone acts as this Linux user in the share (simple, but shared identity)
force group = staff Everyone acts with this group (a good way to share with a team)
create mask = 0660 Permission BITS allowed for new files (a mask, not exact) force create mode = 0660 bits always set
directory mask = 0770 Same for new folders force directory mode = 2770
inherit permissions = yes New files copy their folder's permissions (overrides the masks above)
hide dot files = yes Hide names beginning with a dot veto files = /.DS_Store/Thumbs.db/ Never show these
hosts allow = 192.168.1. Limit one share to certain hosts
follow symlinks = yes wide links = no is the safe default. Do not enable wide links on shares users can write to
ea support = yes Extended attributes
Access needs BOTH: the user passes the share rules (valid users, read only, etc.) AND has the right Linux permissions on the folder.
Users and passwords
A Samba user must exist as a system user first. It does not need a shell or a home directory:
sudo useradd -M -s /usr/sbin/nologin alice # a Linux account with no login and no home (skip if the user already exists)
sudo smbpasswd -a alice # create the SAMBA password (prompts twice). It is separate from the Linux password
sudo smbpasswd -e alice # enable smbpasswd -d alice disable smbpasswd -x alice delete the Samba user
sudo smbpasswd alice # change the password (as root). A user can change theirs with: smbpasswd
sudo pdbedit -L # list Samba users pdbedit -L -v with details pdbedit -Lw show password hashes (careful)
sudo pdbedit -a -u alice # add pdbedit -x -u alice remove
Groups and folders:
sudo groupadd staff
sudo usermod -aG staff alice # log out and back in (or restart the Samba connection) for the new group to apply
sudo mkdir -p /srv/samba/team
sudo chgrp staff /srv/samba/team
sudo chmod 2770 /srv/samba/team # 2 = setgid: new files inherit the group "staff" 770 = owner and group only
ls -ld /srv/samba/team
A user gets in only if they are in a group listed in valid users AND the folder allows that group.
After adding someone to a group, existing SMB connections keep the old group list until they reconnect (or run: smbcontrol smbd close-share team).
Home directories
[homes]
comment = Home Directories
browseable = no
read only = no
valid users = %S # only the owner of the home
create mask = 0700
directory mask = 0700
Users connect to \\server\alice (the share name is their own user name). On SELinux: setsebool -P samba_enable_home_dirs on
Permissions, ACLs and Windows features
Simple shares work with normal Unix permissions and the masks above. To use Windows-style ACLs (the Security tab in Explorer), use these in [global] or the share:
vfs objects = acl_xattr
map acl inherit = yes
store dos attributes = yes
inherit acls = yes
The filesystem must support extended attributes and POSIX ACLs (ext4 and XFS do by default). Manage ACLs from Linux with getfacl and setfacl:
getfacl /srv/samba/team
sudo setfacl -R -m g:staff:rwx /srv/samba/team
sudo setfacl -R -d -m g:staff:rwx /srv/samba/team # default ACL: new files inherit it
smbcacls //server/team / -U alice # view a share's Windows ACLs from Linux (also --add / --modify / --delete with -a, -M, -D)
Windows Previous Versions (shadow copies) from LVM, ZFS or btrfs snapshots: vfs objects = shadow_copy2 (see man vfs_shadow_copy2)
A recycle bin for a share (a safety net for accidental deletes)
[team]
vfs objects = recycle
recycle:repository = .recycle/%U
recycle:keeptree = yes
recycle:versions = yes
recycle:touch = yes
recycle:exclude = *.tmp, ~$*
Deleted files move to .recycle inside the share instead of vanishing. Clean it out with a cron job so it does not grow forever.
macOS clients and Time Machine
[global]
vfs objects = fruit streams_xattr
fruit:metadata = stream
fruit:model = MacSamba
fruit:posix_rename = yes
fruit:veto_appledouble = no
fruit:nfs_aces = no
fruit:wipe_intentionally_left_blank_rfork = yes
fruit:delete_empty_adfiles = yes
[timemachine]
path = /srv/samba/timemachine
valid users = alice
read only = no
fruit:time_machine = yes
fruit:time_machine_max_size = 500G
Connect from a Mac: Finder > Go > Connect to Server (Cmd+K) > smb://server/team. Keep Samba updated: bugs in vfs_fruit have caused serious security fixes in the past.
Client tools on Linux
smbclient -L //server -U alice # list the shares the server offers (asks for the Samba password)
smbclient -L //server -N # no password (guest)
smbclient //server/team -U alice # an interactive FTP-like session:
ls cd folder lcd /tmp get file put file mget *.txt mput *.txt mkdir dir rm file del file rmdir dir pwd help quit
recurse ON prompt OFF then mget * download a whole tree
smbclient //server/team -U alice -c 'ls; get report.pdf' # run commands and exit
smbclient //server/team -U alice%'password' -c 'put file' # password on the command line is VISIBLE to other users: avoid
smbclient //server/team -U 'CORP\alice' -m SMB3 # a domain user, and force SMB3 smbclient -k use Kerberos (after kinit)
smbclient //server/team -A ~/.smbcredentials # credentials from a protected file
nmblookup -A 192.168.1.10 # NetBIOS names of a host nmblookup WORKGROUP find hosts in a workgroup
smbtree -N # browse the network (needs NetBIOS browsing)
rpcclient -U alice //server -c 'enumdomusers' # low-level RPC queries (-c 'srvinfo', 'netshareenum')
smbstatus # on the SERVER: who is connected and which files are open
Windows client: \\server\team in File Explorer or net use Z: \\server\team /user:alice net use * /delete /y net view \\server
macOS: smb://server/team. Linux GUI file managers: smb://server/team (or "Other Locations").
Mount a share on Linux (CIFS)
sudo mkdir -p /mnt/team
sudo mount -t cifs //server/team /mnt/team -o username=alice,uid=1000,gid=1000,vers=3.0
(asks for the password. uid and gid make the files appear as owned by your local user.)
A protected credentials file (do not put passwords in /etc/fstab):
sudo nano /root/.smbcredentials
username=alice
password=SecretHere
domain=WORKGROUP
sudo chmod 600 /root/.smbcredentials
/etc/fstab entry (mounts at boot, without hanging the boot if the server is down):
//server/team /mnt/team cifs credentials=/root/.smbcredentials,uid=1000,gid=1000,file_mode=0660,dir_mode=0770,vers=3.0,_netdev,nofail,x-systemd.automount 0 0
sudo mount -a # test the fstab line sudo umount /mnt/team unmount
Useful mount options:
vers=3.0|3.1.1|2.1 SMB protocol version (avoid vers=1.0) sec=ntlmssp (default) | krb5 | krb5i seal encrypt the connection (SMB3)
uid=, gid=, file_mode=, dir_mode= ownership and permissions as seen on the client iocharset=utf8 file name encoding
noperm do not check permissions on the client (the server still does) soft / hard what to do when the server does not respond
nofail, _netdev, x-systemd.automount, x-systemd.idle-timeout=60 Do not block boot, and mount on first use
For Kerberos (domain) mounts: sudo mount -t cifs //fs.corp.example.com/team /mnt/team -o sec=krb5,cruid=$(id -u),vers=3.0
Install cifs-utils for mount.cifs. Also see the automounter (autofs) for on-demand mounts of many shares.
Discovery and name resolution (why "Network" looks empty)
Modern Windows no longer uses NetBIOS/SMB1 browsing. To make a Linux server appear in Windows "Network", run wsdd (Web Service Discovery):
sudo apt install wsdd # (package name varies: wsdd or wsdd2) sudo systemctl enable --now wsdd
For macOS and Linux Bonjour discovery, use avahi with a service definition (avahi-daemon).
Connecting by name needs DNS (or a hosts entry). \\192.168.1.10\team also works by IP address.
NetBIOS browsing (nmbd) still works on older networks: [global] with netbios name = FILESERVER and local master = no (do not fight for master browser).
Joining an Active Directory domain (Samba as a domain member)
Two common designs:
1. SSSD for logins and Samba only for the file sharing service (see the "Active Directory Login with SSSD" tutorial)
2. winbind for both identity mapping and Samba (below). Winbind is the traditional method for a Samba file server that must map AD users to file ownership
[global]
security = ads
workgroup = CORP # the short NetBIOS domain name
realm = CORP.EXAMPLE.COM
kerberos method = secrets and keytab
idmap config * : backend = tdb
idmap config * : range = 3000-7999
idmap config CORP : backend = rid # stable IDs computed from the SID (the same on every winbind server)
idmap config CORP : range = 10000-999999
template shell = /bin/bash
template homedir = /home/%U
winbind use default domain = yes # use "alice" instead of "CORP\alice"
winbind refresh tickets = yes
vfs objects = acl_xattr
map acl inherit = yes
store dos attributes = yes
Prepare: DNS points at AD, clocks synced (max 5 minutes apart), correct hostname, /etc/krb5.conf sane. Then:
sudo net ads join -U Administrator # join (prompts for the password). A delegated join account is safer
sudo net ads testjoin # verify the machine account net ads info show domain details net ads leave -U Administrator
sudo systemctl restart winbind smbd nmbd
sudo nano /etc/nsswitch.conf # add "winbind" to these two lines (keep a backup first): passwd: files systemd winbind group: files systemd winbind
wbinfo -t # check the trust secret (machine password) wbinfo -u list AD users wbinfo -g list AD groups
wbinfo -a 'alice%password' # test an authentication (password visible: use only in a lab)
getent passwd alice getent group "domain users" id alice
Then share with AD groups: valid users = @"CORP\Domain Users" or (with winbind use default domain) valid users = "@Domain Users" force group = "Domain Users"
Set folder ownership and ACLs with AD groups: sudo chgrp "Domain Users" /srv/samba/dept or manage the ACLs from Windows (right-click > Properties > Security) when acl_xattr is enabled.
Common winbind trouble: "Failed to join domain: failed to precreate account in ou" (permissions), "NT_STATUS_TIME_DIFFERENCE" or Kerberos clock skew (time), wbinfo -t fails (rejoin or fix DNS).
Printing (short)
[global] printing = cups printcap name = cups load printers = yes (remove the "disable spoolss" lines shown earlier)
[printers]
path = /var/spool/samba
printable = yes
guest ok = no
[print$] # driver share for Windows clients (optional)
path = /var/lib/samba/printers
write list = @printadmin
Manage printers with CUPS (http://localhost:631, or lpadmin). Most modern setups print directly over IPP and do not need Samba for printing.
Logging and debugging
[global] log level = 1 auth:3 smb2:3 # per-area levels (0 to 10; 3 is detailed, 10 is enormous) log file = /var/log/samba/log.%m
sudo smbcontrol smbd debug 3 # raise the level of the running daemon without a restart smbcontrol smbd debug 1 lower it again
sudo tail -f /var/log/samba/log.smbd # the main log log.<client-name> one file per client machine (from log file = ...%m)
sudo journalctl -u smbd -f # service messages (RHEL: -u smb)
sudo smbstatus -b # brief list of connections smbstatus -S shares smbstatus -L locked files smbstatus -p processes
sudo smbcontrol smbd close-share team # disconnect everyone from a share (after group changes) smbcontrol smbd kill-client-ip 192.168.1.50
sudo smbd -b | head -30 # build options and paths smbd -b | grep -i CONFIGFILE
sudo testparm -s | less # what Samba really uses
sudo tcpdump -i eth0 port 445 -w smb.pcap # a packet capture to open in Wireshark (see the Wireshark sheet)
sudo ss -tlnp | grep -E ':(139|445)' # is smbd listening?
Test locally on the server: smbclient -L localhost -U alice then smbclient //localhost/team -U alice
Practical recipes
# A private team share, from scratch
sudo groupadd team ; sudo useradd -M -s /usr/sbin/nologin alice ; sudo usermod -aG team alice ; sudo smbpasswd -a alice
sudo mkdir -p /srv/samba/team ; sudo chgrp team /srv/samba/team ; sudo chmod 2770 /srv/samba/team
# add the [team] section to smb.conf (valid users = @team, read only = no, force group = team), then:
testparm -s && sudo systemctl reload smbd
# A read-only share for everyone on the LAN, no password
[media]
path = /srv/media
guest ok = yes
read only = yes
hosts allow = 192.168.1.
# Hide a share but keep it reachable by name
[secret] browseable = no
# Encrypt one share's traffic (SMB3 clients only)
[finance]
path = /srv/finance
valid users = @finance
read only = no
server smb encrypt = required (in [global] this applies to everything, and options are: off, desired, required)
# Limit a share to certain IP addresses
[dept] hosts allow = 192.168.10. hosts deny = 0.0.0.0/0
# Share a USB drive for the evening (a quick read-only share without editing smb.conf)
net usershare add usb /media/usb "USB drive" Everyone:R guest_ok=n # needs "usershare path" enabled and the user in the sambashare group
# Back up the Samba configuration and user database
sudo tar czf samba-backup-$(date +%F).tgz /etc/samba /var/lib/samba/private # passdb.tdb, secrets.tdb (keep it safe: it holds password hashes and machine secrets)
sudo pdbedit -L -w > samba-users.txt # a text export of the users
# Which files does this user have open?
sudo smbstatus -L | grep alice
# Check the SMB protocol version a client used
sudo smbstatus | head -20 # the "Protocol Version" column
# Test connectivity from a Linux client, step by step
ping -c2 server ; nc -zv server 445 ; smbclient -L //server -U alice ; smbclient //server/team -U alice -c ls
Security checklist
[ ] SMB1 is disabled: server min protocol = SMB2_10 (and client min protocol = SMB2_10)
[ ] Port 445 is NOT reachable from the internet. Firewall it to trusted networks (hosts allow, ufw/firewalld rules), or use a VPN
[ ] No guest shares for anything sensitive. Set map to guest = Never for a server that needs no guest access at all
[ ] Signing and encryption: server signing = mandatory (when clients support it) and server smb encrypt = desired or required for sensitive shares
[ ] Access limited with valid users, groups (@team), hosts allow, and correct Linux permissions (no chmod 777, no "force user = root")
[ ] Samba is patched regularly. Serious vulnerabilities have been found in Samba over the years (for example the "SambaCry" bug in 2017 and a vfs_fruit bug in 2021). Subscribe to security announcements
[ ] Strong passwords, and disable or remove old Samba accounts (smbpasswd -d / -x). Consider AD or LDAP authentication and MFA for the underlying systems
[ ] restrict anonymous = 2, and disable NetBIOS/nmbd if you do not need it (also stops name broadcasts)
[ ] Do not enable "wide links" or "unix extensions" together on writable shares (this can let clients follow symlinks outside the share). Leave the safe defaults
[ ] Log and review: watch /var/log/samba for repeated failures, and consider fail2ban rules for SMB
[ ] Keep a tested backup of the shared data (Samba is not a backup) and of /etc/samba
Common problems
"NT_STATUS_LOGON_FAILURE" Wrong user or password. Remember the SMB password is separate: run smbpasswd -a. Make sure the account is enabled (pdbedit -L -v)
"NT_STATUS_ACCESS_DENIED" / "Access is denied" The Linux permissions or valid users block the user. Check ls -ld on the folder, group membership (id alice), and testparm. Try the same path on the server as that user
"NT_STATUS_BAD_NETWORK_NAME" The share name is wrong or the [share] section is missing, or you forgot to reload: check testparm -s and smbclient -L
"NT_STATUS_CONNECTION_REFUSED" / connection timed out smbd is not running, or the firewall blocks 445: systemctl status smbd, ss -tlnp, ufw/firewall-cmd
"protocol negotiation failed: NT_STATUS_INVALID_NETWORK_RESPONSE" or "NT_STATUS_CONNECTION_DISCONNECTED" A protocol version mismatch. Old clients need SMB1 (avoid: upgrade or re-configure them). Or set the client to vers=2.1/3.0
Windows: "You can't access this shared folder because your organization's security policies block unauthenticated guest access" Windows blocks guest logons by default. Use a real user, or (only on a trusted network) enable "Enable insecure guest logons" in policy
Windows keeps asking for the password Wrong domain prefix (try SERVER\alice or .\alice ), a cached bad credential (Credential Manager), or the user is not valid. Clear with: net use * /delete
The share works but I cannot write read only = yes (default), or the user is not in write list, or the Linux folder is not writable by that user or group
New files have the wrong group or permissions Use force group, create mask, directory mask and the setgid bit (chmod 2770), or inherit permissions
Changes to the group do not apply The user must disconnect and reconnect (net use * /delete, or smbcontrol smbd close-share NAME)
"Server does not appear in Windows Network" Windows no longer uses SMB1 browsing. Run wsdd, or connect with \\server directly
mount error(13): Permission denied Wrong credentials, vers= mismatch, or the user is blocked by valid users. Try vers=3.0 and sec=ntlmssp
mount error(112): Host is down / (115) operation now in progress Server unreachable, DNS or firewall. Test ping and nc -zv server 445
mount error(95): Operation not supported The client and server share no protocol version or feature: set vers= explicitly
"cifs_mount failed w/return code = -22" or "unknown mount option" Missing cifs-utils, or a typo in the mount options
Files with odd characters or names Use iocharset=utf8 on Linux clients, and keep server file names in UTF-8
Everything works locally but not from Windows on RHEL SELinux: label the folder samba_share_t, set the samba_* booleans, and read ausearch -m avc
Slow transfers Check the network (duplex, MTU, iperf3), SMB version (avoid SMB1), antivirus or indexing on the client, and disk speed. Try use sendfile = yes
"smbpasswd: Failed to find entry for user" / "Unix user doesn't exist" Create the Linux user first (useradd), then smbpasswd -a
Domain join errors See the winbind section: DNS, time, and the join account's rights. Check testjoin and wbinfo -t
"Unable to initialize messaging context" / smbstatus fails smbd is not running, or you are not root. Use sudo
Weird warnings from testparm Read them: often an obsolete option (like "socket options" or SMB1 settings). Remove or update them
Tips
Run testparm after every edit, then reload with systemctl reload smbd. It catches most typos before users notice.
Remember the two layers: smb.conf share rules AND Linux permissions. Use groups plus force group, chmod 2770 and the masks for team shares.
Samba needs the Linux user first, then smbpasswd -a. The Samba password is separate from the Linux password.
Disable SMB1 (server min protocol = SMB2_10), limit access with hosts allow, and never expose port 445 to the internet.
Prefer valid users with groups (@team) over guest shares, and use encryption and signing for sensitive data.
Mount with a credentials file (chmod 600) and _netdev,nofail in fstab so a missing server does not block boot.
Add a recycle bin or filesystem snapshots (shadow_copy2) so accidental deletes can be undone, and keep real backups.
For Active Directory, use SSSD for logins (see the SSSD tutorial) and winbind plus the idmap settings when Samba must map domain users to file ownership.
Use smbstatus, log level 3 (temporarily) and a packet capture to see what is really happening.
Keep Samba updated and read its security announcements. File servers are attractive targets.