# How to Set Up Samba File Sharing on FreeBSD
Samba is the standard way to share files between FreeBSD servers and Windows or macOS clients. It implements the SMB/CIFS protocol natively, turning your FreeBSD machine into a file server that any desktop operating system can connect to without extra software. Whether you are building a [FreeBSD NAS](/blog/freebsd-nas-build/) for a home lab or deploying shared storage in an office, Samba is the tool for the job.
This guide covers a full Samba deployment on FreeBSD: installation, configuration, ZFS-backed shares, Time Machine support, client connections, performance tuning, Active Directory integration, security hardening, and troubleshooting.
Why Samba on FreeBSD
FreeBSD already supports NFS for Unix-to-Unix file sharing. But the moment Windows or macOS clients enter the picture, you need SMB. Here is what Samba gives you:
- **Windows compatibility.** Windows expects SMB shares. Samba speaks SMB2 and SMB3 natively, including encryption and signing.
- **macOS Finder integration.** Apple switched from AFP to SMB as its default network file protocol starting with OS X Mavericks. Samba handles macOS clients cleanly, including Time Machine backups.
- **Centralized storage.** Pair Samba with [ZFS](/blog/zfs-freebsd-guide/) and you get snapshots, compression, checksums, and quotas underneath your shared folders.
- **Active Directory support.** Samba can join a Windows domain, authenticating users against an existing AD controller. No duplicate user databases.
- **Battle-tested.** Samba has been in production for decades. The FreeBSD port is well-maintained and tracks upstream releases closely.
If you need cross-platform file sharing on FreeBSD, Samba is the only serious option.
Installation
Install Samba from the FreeBSD package repository. The current stable release in the ports tree is Samba 4.16:
sh
pkg install samba416
This pulls in all required dependencies including Heimdal Kerberos libraries, talloc, tdb, and ldb.
After installation, enable the Samba services in /etc/rc.conf:
sh
sysrc samba_server_enable="YES"
This enables both smbd (the file serving daemon) and nmbd (the NetBIOS name service daemon). If you only need SMB2/SMB3 and do not require NetBIOS name resolution, you can start smbd alone, but most environments benefit from running both.
Do not start the services yet. You need a working configuration file first.
Basic smb4.conf Configuration
Samba reads its configuration from /usr/local/etc/smb4.conf. The file does not exist by default. Create it from scratch.
Here is a minimal global section:
ini
[global]
workgroup = WORKGROUP
server string = FreeBSD Samba Server
server role = standalone server
security = user
# Protocol versions
server min protocol = SMB2_10
server max protocol = SMB3_11
# Logging
log file = /var/log/samba4/log.%m
max log size = 5000
log level = 1
# Disable printer sharing
load printers = no
printing = bsd
printcap name = /dev/null
disable spoolss = yes
# DNS proxy
dns proxy = no
# Character set
unix charset = UTF-8
Key settings explained:
- **workgroup**: Must match the workgroup or domain name of your Windows clients. The default on Windows is WORKGROUP.
- **security = user**: Every connecting client must authenticate with a username and password. This is the default and recommended mode.
- **server min protocol = SMB2_10**: Disables the ancient SMB1 protocol, which is a security liability. All modern clients support SMB2 or later.
- **log file**: Per-client log files using the %m macro (replaced with the client machine name).
- **Printer settings**: Disabled entirely. If you do not share printers, removing this overhead is good practice.
Create the log directory:
sh
mkdir -p /var/log/samba4
Creating File Shares
Add share definitions below the [global] section. Each share is a bracketed section with a name, a path, and access controls.
A Basic Read/Write Share
ini
[shared]
comment = General File Share
path = /data/shared
browseable = yes
read only = no
valid users = @staff
create mask = 0664
directory mask = 0775
force group = staff
This creates a share named shared at /data/shared. Only members of the staff group can connect. New files get 0664 permissions and new directories get 0775.
A Public Guest Share
ini
[public]
comment = Public Files (No Auth Required)
path = /data/public
browseable = yes
read only = yes
guest ok = yes
guest only = yes
Guest access requires an additional line in the [global] section:
ini
map to guest = Bad User
This maps unknown usernames to the guest account, allowing anonymous read access.
A Private Home Directory Share
ini
[homes]
comment = Home Directories
browseable = no
writable = yes
valid users = %S
create mask = 0600
directory mask = 0700
The special [homes] section automatically maps each authenticated user to their Unix home directory. %S expands to the connecting username.
User Management
Samba maintains its own password database, separate from the system /etc/passwd. You must add Samba passwords for each user who will connect.
Adding a Samba User
The Unix user must exist first:
sh
pw useradd -n alice -m -s /usr/sbin/nologin
smbpasswd -a alice
The -a flag adds the user to the Samba database. You will be prompted to set a password. The user does not need a shell login since -s /usr/sbin/nologin prevents SSH access.
Managing Users with pdbedit
For more detailed user management, use pdbedit:
sh
# List all Samba users
pdbedit -L
# Show detailed info for a user
pdbedit -Lv alice
# Delete a Samba user
pdbedit -x alice
# Set account flags (disable account)
pdbedit --modify --account-flags="[D]" alice
Group Management
Create a Unix group and add users to it:
sh
pw groupadd staff
pw groupmod staff -m alice,bob
Then reference the group in your share definition with valid users = @staff.
ZFS Dataset Per Share
If your FreeBSD server runs ZFS (and it should for any NAS workload), create a dedicated dataset for each Samba share. This gives you independent snapshots, compression settings, and quotas per share.
sh
# Create the parent pool dataset
zfs create tank/samba
# Create per-share datasets
zfs create tank/samba/shared
zfs create tank/samba/public
zfs create tank/samba/timemachine
# Set mount points
zfs set mountpoint=/data/shared tank/samba/shared
zfs set mountpoint=/data/public tank/samba/public
zfs set mountpoint=/data/timemachine tank/samba/timemachine
# Enable compression
zfs set compression=lz4 tank/samba
# Set quota on time machine share
zfs set quota=500G tank/samba/timemachine
Set ownership and permissions:
sh
chown root:staff /data/shared
chmod 0775 /data/shared
chown nobody:nogroup /data/public
chmod 0755 /data/public
chown alice:alice /data/timemachine
chmod 0700 /data/timemachine
For more granular access control, use NFSv4 ACLs on ZFS:
sh
# Enable ACL support on the dataset
zfs set aclmode=passthrough tank/samba/shared
zfs set aclinherit=passthrough tank/samba/shared
# Set ACLs
setfacl -m group:staff:rwxpDdaARWcCos:fd:allow /data/shared
Add the following to the share definition to enable Samba's VFS ACL support:
ini
[shared]
...
vfs objects = zfsacl
nfs4:mode = special
nfs4:acedup = merge
nfs4:chown = yes
See our [ZFS guide](/blog/zfs-freebsd-guide/) for a deeper dive on datasets, snapshots, and ACLs.
Time Machine Backup Share for macOS
Samba can serve as a Time Machine target for macOS clients. This is one of the most popular use cases for a [FreeBSD NAS build](/blog/freebsd-nas-build/).
Add this share definition:
ini
[timemachine]
comment = Time Machine Backups
path = /data/timemachine
browseable = yes
read only = no
valid users = alice
vfs objects = catia fruit streams_xattr zfsacl
fruit:time machine = yes
fruit:time machine max size = 500G
fruit:metadata = stream
fruit:encoding = native
fruit:veto_appledouble = no
fruit:posix_rename = yes
fruit:zero_file_id = yes
fruit:wipe_intentionally_left_blank_rfork = yes
fruit:delete_empty_adfiles = yes
create mask = 0600
directory mask = 0700
The fruit VFS module provides full Apple SMB compatibility. The fruit:time machine = yes directive advertises the share as a Time Machine target via Bonjour/mDNS.
For Bonjour advertisement to work, also install and enable Avahi:
sh
pkg install avahi
sysrc avahi_daemon_enable="YES"
sysrc dbus_enable="YES"
service dbus start
service avahi-daemon start
On the macOS client, the Time Machine share should now appear automatically in System Settings under Time Machine. If it does not, connect manually using Finder (Cmd+K, then smb://your-server/timemachine).
Connecting from Windows, macOS, and Linux Clients
Windows
Open File Explorer and type in the address bar:
\\192.168.1.100\shared
Replace 192.168.1.100 with your FreeBSD server's IP address. Windows will prompt for credentials. Enter the Samba username and password you created earlier. Check "Remember my credentials" to save them.
To map a permanent drive letter:
cmd
net use Z: \\192.168.1.100\shared /user:alice /persistent:yes
macOS
In Finder, press Cmd+K and enter:
smb://192.168.1.100/shared
Authenticate with your Samba username and password. The share mounts under /Volumes/shared.
For command-line mounting:
sh
mkdir /Volumes/shared
mount_smbfs //alice@192.168.1.100/shared /Volumes/shared
Linux
Install cifs-utils and mount the share:
sh
mount -t cifs //192.168.1.100/shared /mnt/shared -o username=alice,vers=3.0
For persistent mounts, add to /etc/fstab:
//192.168.1.100/shared /mnt/shared cifs username=alice,password=secret,vers=3.0 0 0
For better security, store credentials in a separate file with restricted permissions instead of putting the password in fstab:
//192.168.1.100/shared /mnt/shared cifs credentials=/root/.smbcredentials,vers=3.0 0 0
Performance Tuning
Default Samba settings work, but you can squeeze significantly more throughput out of your FreeBSD server with targeted tuning.
Samba Configuration Tuning
Add these to the [global] section:
ini
# Use sendfile for better throughput
use sendfile = yes
# Async I/O
aio read size = 1
aio write size = 1
# Disable strict locking for better performance
strict locking = no
# Socket options
socket options = TCP_NODELAY IPTOS_LOWDELAY SO_RCVBUF=131072 SO_SNDBUF=131072
# Deadtime - disconnect idle clients after 15 minutes
deadtime = 15
ZFS Tuning for SMB Workloads
Match the ZFS record size to your workload:
sh
# For large files (video, backups, ISOs)
zfs set recordsize=1M tank/samba/shared
# For small files (documents, code)
zfs set recordsize=16K tank/samba/shared
# For Time Machine (mixed, mostly large)
zfs set recordsize=1M tank/samba/timemachine
Enable sync=disabled only if you accept the risk of data loss on power failure (not recommended for production, acceptable for cache-like shares):
sh
zfs set sync=disabled tank/samba/public
A safer option is to use a SLOG (ZFS Intent Log) device on a fast SSD, keeping sync writes enabled but fast.
FreeBSD Network Tuning
Add to /etc/sysctl.conf:
kern.ipc.maxsockbuf=16777216
net.inet.tcp.sendbuf_max=16777216
net.inet.tcp.recvbuf_max=16777216
net.inet.tcp.sendbuf_auto=1
net.inet.tcp.recvbuf_auto=1
Apply immediately:
sh
sysctl -f /etc/sysctl.conf
With these settings, a 10GbE-connected FreeBSD Samba server can saturate the link for sequential reads and writes.
Active Directory Integration
Samba can join a Windows Active Directory domain, allowing users to authenticate with their domain credentials. This eliminates the need to maintain a separate Samba password database.
Prerequisites
Install Kerberos client tools (included with the Samba package) and ensure DNS resolution points to your AD domain controller:
sh
# /etc/resolv.conf
nameserver 192.168.1.10
search example.com
Configure Kerberos
Create /etc/krb5.conf:
ini
[libdefaults]
default_realm = EXAMPLE.COM
dns_lookup_realm = false
dns_lookup_kdc = true
[realms]
EXAMPLE.COM = {
kdc = dc01.example.com
admin_server = dc01.example.com
}
[domain_realm]
.example.com = EXAMPLE.COM
example.com = EXAMPLE.COM
Configure Samba for AD
Modify the [global] section of smb4.conf:
ini
[global]
workgroup = EXAMPLE
realm = EXAMPLE.COM
server role = member server
security = ads
# ID mapping
idmap config * : backend = tdb
idmap config * : range = 3000-7999
idmap config EXAMPLE : backend = rid
idmap config EXAMPLE : range = 10000-999999
# Winbind settings
winbind use default domain = yes
winbind enum users = yes
winbind enum groups = yes
winbind refresh tickets = yes
template shell = /usr/sbin/nologin
template homedir = /home/%U
Join the Domain
sh
# Get a Kerberos ticket
kinit administrator@EXAMPLE.COM
# Join the domain
net ads join -k
# Enable and start winbindd
sysrc winbindd_enable="YES"
service samba_server restart
# Verify the join
wbinfo -t
wbinfo -u
After joining, domain users can authenticate to Samba shares without local accounts. Use valid users = @"EXAMPLE\Domain Users" in share definitions to grant access based on AD group membership.
Security Hardening
A file server exposed on the network must be locked down. Here are the essential security steps.
Firewall Rules
Use [PF](/blog/pf-firewall-freebsd/) to restrict SMB access to your LAN:
# /etc/pf.conf
ext_if = "em0"
lan_net = "192.168.1.0/24"
# Block everything by default
block all
# Allow SMB from LAN only
pass in on $ext_if proto tcp from $lan_net to any port { 139, 445 }
pass in on $ext_if proto udp from $lan_net to any port { 137, 138 }
If you only use SMB2/SMB3, you can restrict to port 445 alone and block the NetBIOS ports 137-139 entirely:
pass in on $ext_if proto tcp from $lan_net to any port 445
Reload PF:
sh
pfctl -f /etc/pf.conf
SMB Encryption
Force encryption for all connections (requires SMB3-capable clients):
ini
[global]
server smb encrypt = required
For per-share encryption:
ini
[confidential]
path = /data/confidential
smb encrypt = required
Bind to Specific Interfaces
Prevent Samba from listening on public interfaces:
ini
[global]
interfaces = 192.168.1.100/24 lo0
bind interfaces only = yes
Audit Logging
Enable a full audit trail with the VFS audit module:
ini
[shared]
...
vfs objects = full_audit zfsacl
full_audit:prefix = %u|%I|%S
full_audit:success = connect disconnect open read write rename unlink mkdir rmdir
full_audit:failure = connect open read write
full_audit:facility = local5
full_audit:priority = notice
Add a syslog rule to capture audit logs separately:
sh
# /etc/syslog.conf
local5.notice /var/log/samba4/audit.log
Restart syslogd:
sh
service syslogd restart
Starting Samba
With configuration complete, validate the config and start the services:
sh
# Test the configuration file for errors
testparm
# Start Samba
service samba_server start
testparm parses smb4.conf and reports any syntax errors or deprecated options. Always run it after editing the config file.
Complete smb4.conf Example
Here is a full production-ready configuration combining everything covered above:
ini
[global]
workgroup = WORKGROUP
server string = FreeBSD Samba Server
server role = standalone server
security = user
server min protocol = SMB2_10
server max protocol = SMB3_11
server smb encrypt = desired
interfaces = 192.168.1.100/24 lo0
bind interfaces only = yes
log file = /var/log/samba4/log.%m
max log size = 5000
log level = 1
load printers = no
printing = bsd
printcap name = /dev/null
disable spoolss = yes
dns proxy = no
unix charset = UTF-8
map to guest = Bad User
use sendfile = yes
aio read size = 1
aio write size = 1
strict locking = no
socket options = TCP_NODELAY IPTOS_LOWDELAY SO_RCVBUF=131072 SO_SNDBUF=131072
deadtime = 15
[shared]
comment = General File Share
path = /data/shared
browseable = yes
read only = no
valid users = @staff
create mask = 0664
directory mask = 0775
force group = staff
vfs objects = zfsacl
nfs4:mode = special
nfs4:acedup = merge
nfs4:chown = yes
[public]
comment = Public Read-Only Files
path = /data/public
browseable = yes
read only = yes
guest ok = yes
guest only = yes
[timemachine]
comment = Time Machine Backups
path = /data/timemachine
browseable = yes
read only = no
valid users = alice
vfs objects = catia fruit streams_xattr zfsacl
fruit:time machine = yes
fruit:time machine max size = 500G
fruit:metadata = stream
fruit:encoding = native
fruit:veto_appledouble = no
fruit:posix_rename = yes
fruit:zero_file_id = yes
fruit:wipe_intentionally_left_blank_rfork = yes
fruit:delete_empty_adfiles = yes
create mask = 0600
directory mask = 0700
[homes]
comment = Home Directories
browseable = no
writable = yes
valid users = %S
create mask = 0600
directory mask = 0700
Troubleshooting
testparm
Always start here. Run testparm to check your configuration:
sh
testparm /usr/local/etc/smb4.conf
It reports deprecated options, typos, and conflicting settings. Fix everything it flags before investigating further.
smbstatus
See active connections and locked files:
sh
smbstatus
# Show only shares
smbstatus -S
# Show only locks
smbstatus -L
Log Files
Increase the log level temporarily for deeper debugging:
ini
[global]
log level = 3
Levels range from 0 (errors only) to 10 (extremely verbose). Level 3 is usually enough to diagnose authentication and permission issues. Check logs in /var/log/samba4/.
After debugging, set the log level back to 1 to avoid filling your disk.
Common Issues
**"NT_STATUS_ACCESS_DENIED" when connecting.**
The user probably does not have a Samba password. Run smbpasswd -a username to set one.
**Share not visible in Windows Network.**
Check that nmbd is running: service samba_server status. Ensure NetBIOS ports 137-138 (UDP) and 139 (TCP) are open in your firewall, or verify the client can resolve the server hostname via DNS.
**macOS Time Machine says "The network backup disk could not be found."**
Ensure the fruit VFS module is loaded, Avahi is running, and the share is correctly advertised. Check with avahi-browse -a | grep smb.
**Slow transfers.**
Verify your Samba protocol version with smbstatus. If clients are negotiating SMB2 instead of SMB3, check the server max protocol setting. Also verify network settings with ifconfig and ensure jumbo frames match on both ends if enabled.
**Permission denied writing files even though authenticated.**
Check Unix permissions on the share path. The connecting user (or force group) must have write permission at the filesystem level. Samba cannot grant more access than Unix permissions allow.
Frequently Asked Questions
Can I run Samba and NFS on the same FreeBSD server?
Yes. Many FreeBSD NAS setups run both. Use NFS for Unix/Linux clients and Samba for Windows/macOS clients, even sharing the same underlying ZFS datasets. Just be careful with file locking -- do not have both NFS and SMB clients writing to the same files simultaneously without a coordination strategy.
Which Samba version should I install on FreeBSD?
Install the latest stable version available in the FreeBSD package repository. As of this writing, samba416 is the current stable port. Check pkg search samba to see what is available. Avoid mixing major versions or compiling from source unless you have a specific reason.
How do I upgrade Samba on FreeBSD?
Standard package upgrade process:
sh
pkg update
pkg upgrade samba416
service samba_server restart
After a major version upgrade, run testparm to check for deprecated or removed configuration options.
Is SMB1 support needed?
Almost never. SMB1 is insecure and slow. The only scenario where you might need it is connecting very old devices (ancient printers, legacy embedded systems). If you must enable it, set server min protocol = NT1 but understand the security implications. All current versions of Windows, macOS, and Linux support SMB2 or SMB3.
How do I limit share size without ZFS quotas?
Samba has a built-in VFS module for this:
ini
[shared]
...
vfs objects = default_quota
dfree command = /usr/local/bin/dfree.sh
However, ZFS quotas are a much cleaner solution. Set zfs set quota=100G tank/samba/shared and Samba will automatically report the correct free space to clients.
Can Samba serve as an Active Directory Domain Controller on FreeBSD?
Technically yes, Samba supports the AD DC role. However, on FreeBSD this is considered experimental and not recommended for production. The Samba AD DC role works best on Linux where it has the most testing. For FreeBSD, the member server role (joining an existing domain) is fully supported and stable.
How do I back up Samba configuration and user database?
Back up these paths:
sh
/usr/local/etc/smb4.conf
/usr/local/etc/samba/
/var/db/samba4/
The /var/db/samba4/ directory contains the TDB databases including the user password database. For disaster recovery, also document your ZFS dataset layout and permissions.
Conclusion
Samba on FreeBSD is a production-grade file sharing solution. Paired with [ZFS](/blog/zfs-freebsd-guide/), you get a file server with snapshots, compression, and data integrity that speaks native SMB to every desktop OS. The setup is straightforward: install the package, write a smb4.conf, create your users, and start the service.
For a complete storage server build including hardware selection and ZFS pool design, see our [FreeBSD NAS build guide](/blog/freebsd-nas-build/). To lock down network access to your Samba server, follow our [PF firewall guide](/blog/pf-firewall-freebsd/).