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 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 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:
shpkg 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:
shsysrc 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
%mmacro (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:
shmkdir -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:
inimap 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:
shpw 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:
shpw 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:
shchown 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 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.
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:
shpkg 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:
shell\\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:
cmdnet use Z: \\192.168.1.100\shared /user:alice /persistent:yes
macOS
In Finder, press Cmd+K and enter:
shellsmb://192.168.1.100/shared
Authenticate with your Samba username and password. The share mounts under /Volumes/shared.
For command-line mounting:
shmkdir /Volumes/shared mount_smbfs //alice@192.168.1.100/shared /Volumes/shared
Linux
Install cifs-utils and mount the share:
shmount -t cifs //192.168.1.100/shared /mnt/shared -o username=alice,vers=3.0
For persistent mounts, add to /etc/fstab:
shell//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:
shell//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):
shzfs 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:
shellkern.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:
shsysctl -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 to restrict SMB access to your LAN:
shell# /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:
shellpass in on $ext_if proto tcp from $lan_net to any port 445
Reload PF:
shpfctl -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:
shservice 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:
shtestparm /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:
shsmbstatus # 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:
shpkg 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, 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. To lock down network access to your Samba server, follow our PF firewall guide.