Setting Up a Secure Samba Server on Linux: Hardening and Configuration Guide
A comprehensive guide on setting up and hardening a Samba server on Linux. Learn how to configure robust SMB file sharing, disable insecure SMBv1 protocols, enforce SMB3 transport encryption, implement host-based access controls, and configure auditing with VFS modules to prevent unauthorized network access.
Bridging Compatibility and Security with Samba
In May 2017, WannaCry spread across an estimated 200,000 machines in about four days without anyone clicking anything. Its propagation mechanism was EternalBlue, an exploit against a flaw in SMBv1 — a protocol that had been obsolete for the better part of a decade and was still enabled by default nearly everywhere, because nothing had forced anyone to turn it off. NotPetya followed the same route six weeks later and did considerably more damage.
That is the protocol Samba speaks. It is also, unavoidably, the protocol you need if Linux servers have to share files with Windows clients, and Samba remains the best implementation of it outside Windows itself — a Linux share appears in Explorer as an ordinary network drive, with no client software to install.
The problem is not Samba. The problem is that the default configuration is written for compatibility, which is the opposite goal from security: it accepts old dialects, it permits unencrypted transport, and it will happily answer anyone who can route a packet to port 445. Every setting in this guide is a decision to break compatibility with something in exchange for closing an exposure, and it is worth knowing which is which before you paste a config file onto a production server.
What follows is a layered build: modern dialects only, enforced transport encryption, group-based directory permissions, host-level access control, and file-operation auditing.
How SMB Negotiates a Secure Connection
The security of an SMB session is decided in its first two packets. The client offers a list of dialects it supports; the server picks one. A server that still accepts SMB1 will use it whenever a client offers nothing better — and an attacker on the network is free to be exactly that client. This is why “we’ve upgraded all our workstations” is not the same as having disabled SMB1: the control has to live on the server, because the server is the only party you control.
SMB 3.x adds two things that matter here — signing, which detects tampering and defeats the classic relay attacks, and encryption, which stops the file contents from being readable on the wire. The sequence below shows a hardened negotiation, where the server refuses the old dialect and then requires encryption before any data moves.
1. Installing Samba
Package names differ slightly between distributions; nothing here is complicated. What matters is what happens in the thirty seconds after the install finishes.
For Debian and Ubuntu-based systems:
sudo apt update
sudo apt install samba samba-common-bin -y
For RHEL, Rocky Linux, or AlmaLinux:
sudo dnf install samba samba-common -y
Once installed, check that the service is running:
systemctl status smbd
[!WARNING] On Debian and Ubuntu the package starts
smbdas soon as it is unpacked, with the stock configuration and no access controls. If the machine has a public interface, you now have a file server listening on port 445 that you have not configured yet — and port 445 is among the most heavily scanned on the internet, for the reasons described above. Stop the service before you edit anything, and confirm the firewall is blocking 445 from outside your LAN:sudo systemctl stop smbd
2. Creating a Secure Shared Directory
Search for a Samba tutorial and roughly half of them will tell you to chmod 777 the share directory. It does make the permission errors stop. It does so by granting every local account on the box — including the web server’s unprivileged user, including whatever a compromised service is running as — full read and write access to everything in the share. Samba’s own valid users restriction does nothing about this, because that control governs SMB clients and the local filesystem is a separate path to the same files.
The fix is a dedicated group, ownership by that group, and no permissions at all for anyone else.
Create a dedicated group for Samba users:
sudo groupadd smbshares
Create the shared directory outside user home folders:
sudo mkdir -p /srv/samba/secure_share
Set ownership and permissions with the SetGID bit:
sudo chown -R root:smbshares /srv/samba/secure_share
sudo chmod -R 2770 /srv/samba/secure_share
2770 is doing three separate jobs. The 770 gives root and the smbshares group full access and everyone else precisely nothing. The leading 2 sets SetGID on the directory, so files created inside it inherit the smbshares group rather than the creating user’s primary group — without it, every user’s files end up owned by a different group and colleagues start reporting that they can see a file but cannot open it. And because the directory sits under /srv rather than inside someone’s home, it survives that user being deleted.
Put the share on its own filesystem or set a quota if you can. A share with no size limit is a share where one user’s runaway sync client fills the root partition and stops the server logging, which is a worse outage than the one you were worried about.
Create a Samba-only system user with no shell access:
sudo useradd -M -s /usr/sbin/nologin -g smbshares smbuser
Register the user in Samba’s password database:
sudo smbpasswd -a smbuser
Two details in that useradd line are doing security work. -s /usr/sbin/nologin means the account cannot be used to obtain a shell, so a stolen Samba password does not become SSH access. -M skips creating a home directory the account has no use for.
Note also that Samba keeps its own password database, separate from /etc/shadow — which is why smbpasswd exists and why disabling a user in Linux does not disable their SMB access. Use smbpasswd -x when someone leaves, or you will have an account you believe is gone.
Choose a genuinely strong password here. NTLMv2 is a challenge-response scheme, and a captured exchange can be attacked offline at whatever rate the attacker’s hardware allows, with no lockout and no log entry on your server. Transport encryption protects the file contents; it does not make a nine-character password safe.
3. Hardening the Samba Configuration
Everything security-critical lives in /etc/samba/smb.conf. Back up the original before you touch it — not out of ritual, but because the shipped file is heavily commented and those comments are the fastest reference you have for the options this guide does not cover:
sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.bak
Open the file for editing:
sudo nano /etc/samba/smb.conf
Replace the contents with the configuration below. Read the annotations after it before deploying — two of these directives will lock out clients, and it is better to know which ones in advance than to discover it from a helpdesk queue:
[global]
workgroup = WORKGROUP
server string = Hardened File Server
log file = /var/log/samba/log.%m
max log size = 1000
logging = file
# ================= Security Hardening =================
# Enforce modern SMB protocols (Disable SMBv1)
server min protocol = SMB2_10
client min protocol = SMB2_10
# Enforce SMB3 transport encryption (Protects against eavesdropping)
smb encrypt = required
# Disable guest/anonymous access entirely
guest ok = no
map to guest = Never
restrict anonymous = 2
# Network Isolation: Bind to internal interfaces only
bind interfaces only = yes
interfaces = lo eth0 192.168.1.0/24
# IP-based Access Control List (ACL)
hosts allow = 127. 192.168.1.
hosts deny = 0.0.0.0/0
# Disable printer sharing unless explicitly needed (Reduces attack surface)
load printers = no
printing = bsd
printcap name = /dev/null
disable spoolss = yes
# ================= Shared Directories =================
[SecureShare]
comment = Secure Collaborative Share
path = /srv/samba/secure_share
valid users = @smbshares
force group = smbshares
writable = yes
browseable = yes
guest ok = no
# Secure File Creation Masks (Files: 660, Directories: 770)
create mask = 0660
directory mask = 0770
force create mode = 0660
force directory mode = 0770
What the key directives do, and what each one costs:
server min protocol = SMB2_10— Refuses SMB1 outright, which is the single most valuable line in the file. Anything from Windows 10 onwards, current macOS, or a recent Linux client negotiates SMB3 without noticing. SettingSMB3instead is stricter and better where you can; the casualties are old NAS boxes, scanners and multifunction printers that scan-to-share, and embedded devices whose firmware stopped being updated in 2014. Those will fail with an unhelpful “network path not found”, so inventory them before you tighten this.smb encrypt = required— Refuses any session that will not encrypt. Encryption costs CPU on both ends and will reduce throughput on large transfers, noticeably so on low-powered hardware without AES acceleration. On a LAN moving documents this is irrelevant; if you are pushing video files through an Atom-class NAS, measure before committing.desirednegotiates encryption where possible and silently accepts plaintext where not — which is a reasonable transition setting and a poor final one, because “silently accepts plaintext” is not a state you will notice you are in.restrict anonymous = 2— Blocks unauthenticated session setup, so an attacker cannot enumerate your share names and user list before authenticating. Null-session enumeration is a standard first move on any internal engagement; this closes it.hosts allow/hosts deny— Access control inside Samba, independent of the firewall, so a firewall rule added in error does not immediately expose the service. It is IP-based, which means it stops opportunistic scanning and does not stop anyone already on your LAN who can set their own address. Defence in depth, not a perimeter.bind interfaces only = yes— Constrains which interfacessmbdlistens on. Get the interface list wrong and the daemon starts cleanly while being unreachable, which presents as a client-side problem and wastes an afternoon.create mask = 0660andforce create mode— Together these guarantee that files arriving over SMB land with group-only permissions regardless of what the client requested. Withoutforce create mode, a Windows client can create a file whose mode is more permissive than you intended.
4. Auditing with VFS Modules
Access controls tell you what should have happened. Audit logs tell you what did. The difference matters most during a ransomware incident, where the question is not whether files were encrypted but which account did it, from which workstation, starting when — and a share with no audit trail can answer none of that.
Samba’s VFS layer provides full_audit, which logs file operations to syslog as they happen.
The cost is volume. Logging open and pwrite on a busy share generates a lot of lines, and left unbounded it will fill a partition; the list below deliberately favours the operations that reconstruct an incident — creation, renaming, deletion — over those that merely prove someone read a document. Decide which you need, then size the disk and set up rotation before you enable it, not after.
Add the following to your share definition:
[SecureShare]
...
# Enable VFS auditing module
vfs objects = full_audit
# Logging Prefix: Username|IP Address|Machine Name|Share Name
full_audit:prefix = %u|%I|%m|%S
# Operations to log (Focus on write, delete, and connection activities)
full_audit:success = mkdir rename unlink rmdir open pwrite write
full_audit:failure = connect open
# Log configuration
full_audit:facility = local7
full_audit:priority = NOTICE
Route audit logs to a dedicated file by creating /etc/rsyslog.d/samba-audit.conf:
local7.notice /var/log/samba/audit.log
& stop
Then restart both services:
sudo systemctl restart rsyslog
sudo systemctl restart smbd
From here every creation, rename, deletion and failed connection is timestamped against a username and a source IP.
One more step turns this from a log into evidence: forward it off the host. An attacker who reaches root on this server can rewrite /var/log/samba/audit.log at leisure, and the copy that matters is the one they cannot reach. Ship it to your syslog collector or SIEM on the same day you enable it — audit logging that only exists on the machine being attacked tends to be complete right up until the point it becomes interesting.
A useful detection to build on top of it: a single account renaming or writing hundreds of files a minute is not a person working. That pattern is ransomware, and it is visible in this log stream several minutes before anyone rings the helpdesk.
5. Testing and Connecting to the Share
Run testparm before every restart. It parses the file, reports syntax errors, and — more usefully — prints the configuration as Samba actually understands it, including defaults you did not set and directives it ignored because you misspelled them. A typo’d option name is not an error in smb.conf; it is a silently absent control, and testparm is how you catch that the hardening line you added is not in effect:
testparm
If the output looks clean, restart the daemon:
sudo systemctl restart smbd
From Windows: Open File Explorer and type the UNC path in the address bar:
\\<server_ip>\SecureShare
Enter the smbuser credentials when prompted. With smb encrypt = required in force, Windows negotiates an encrypted session using AES-CCM or AES-GCM without any client-side configuration. If instead you get a bare failure with no credential prompt, the negotiation was refused before authentication — an old client, or a dialect mismatch, rather than a wrong password.
From Linux using smbclient:
smbclient //<server_ip>/SecureShare -U smbuser -e
The -e flag explicitly requests encryption. If the client can’t support it, the server drops the connection — by design.
Permanent mount via /etc/fstab:
//<server_ip>/SecureShare /mnt/share cifs credentials=/etc/samba/auth.cred,iocharset=utf8,seal 0 0
The seal option is the mount-side equivalent of requiring encryption; without it a persistent mount may negotiate down. Note what this file is: a plaintext password on disk, readable by root, mounted automatically at boot. That is the trade you are making for an unattended mount, and the mitigation is to keep the credentials to a low-privilege account that can reach this share and nothing else. Create /etc/samba/auth.cred, then restrict it:
sudo chmod 600 /etc/samba/auth.cred
6. Ongoing Monitoring
Check active connections and encryption status:
sudo smbstatus
Check the encryption column on every live session — AES-128-GCM or AES-256-GCM is what you want. An Unencrypted session on a server configured with smb encrypt = required means the requirement is not actually in force, which almost always traces back to a per-share setting overriding the global one, or a testparm warning nobody read. Verify this after every configuration change rather than trusting the config file, because the config file is a statement of intent and smbstatus is a statement of fact.
Hunt for authentication brute-force attempts:
sudo grep -i "auth" /var/log/samba/log.smbd
A run of failures from one address is password spraying or credential stuffing; a run of failures spread across many accounts from one address is the same thing being done carefully. Fail2ban will ban the source after a threshold, which is worth having, with two caveats. It only sees what reaches this log, so an attacker who cracks a captured hash offline never appears in it at all. And a ban rule that triggers on a shared NAT address locks out an entire office along with the attacker — set the threshold and the ban duration with that outcome in mind.
Hardening Checklist
Work through this before the server carries anything you care about. Verify each item against the running service — testparm and smbstatus — rather than against your memory of having edited the file:
| Security Control | Why It Matters | Status |
|---|---|---|
| Disable SMBv1 | Prevents exploitation of deprecated protocols (WannaCry, EternalBlue) | [ ] |
| Enforce Encryption | Protects data in transit from eavesdropping and MITM attacks | [ ] |
| Disable Guest Access | Prevents anonymous reconnaissance and unauthenticated file access | [ ] |
| IP Access Controls | Restricts connections to approved subnets only | [ ] |
| No Shell for Samba Users | Samba accounts cannot be used to log into the system | [ ] |
| Secure File Masks | New files respect strict group permissions automatically | [ ] |
| VFS Audit Logging | All file-level operations are logged for forensic review | [ ] |
Configured this way, Samba gives you dependable cross-platform file sharing that is not the softest target on the segment — and on an internal network, being the softest target is what actually gets you compromised.
Two things this guide does not solve, so that you know where the edges are. None of it protects against a legitimate user whose workstation has been taken over: their credentials are valid, their session is encrypted, and the audit log will faithfully record them destroying the share. That is what versioned, offline backups are for, and a file server without them is a single successful phishing email away from total loss. And a standalone Samba server means passwords managed per-machine; once you are past a handful of users, joining it to a domain and letting Kerberos handle authentication is less work than the account sprawl you are otherwise signing up for.