Introduction

Let’s set up a simple and rock-solid file server powered by FreeBSD, ZFS, and Samba.

It is assumed that you have installed FreeBSD on a suitable system already, and set up a ZFS zpool on appropriate storage.

An advantage of using FreeBSD, ZFS, and Samba as a file server is that you get native NFSv4 ACLs, as opposed to POSIX draft ACLs on Linux. Using NFSv4 ACLs gives greater compatibility with NTFS ACLs, and Samba works better with them.

Setting up the ZFS dataset

Create a suitable ZFS dataset for storing the data if not already done so. Ensure that the zpool itself was created using the appropriate ashift value, for example ashift=12 on a disk with 4K physical sectors. If the dataset is only going to be used for SMB connections from Windows clients, then you may want to set casesensitivity=mixed to more closely match Windows behavior and potentially allow for Samba to look up filenames faster, but this isn’t required and it is better to leave it default (sensitive) if other clients will access the dataset.

Set the following attributes on the dataset to used for Samba file sharing:

  • xattr=sa stores extended attributes in a more efficient way
  • dnodesize=auto allows for larger extended attributes
  • relatime=on less aggresive access time updates for increased performance
  • aclmode=restricted more closely match SMB behavior for ACLs
  • aclinherit=passthrough more closely match SMB behavior for ACLs

Example (replace tank/data with the actual zpool and dataset):

# zfs set xattr=sa dnodesize=auto relatime=on aclmode=restricted aclinherit=passthrough tank/data

Installing Samba

You can install Samba easily using FreeBSD’s pkg tool.

Check which Samba versions are available:

# pkg search samba

Which may give output similar to the following:

p5-Samba-LDAP-0.05_2           Manage a Samba PDC with an LDAP Backend
p5-Samba-SIDhelper-0.0.0_3     Create SIDs based on G/UIDs
samba-nsupdate-9.16.5_1        nsupdate utility with the GSS-TSIG support
samba416-4.16.11_4             Free SMB/CIFS and AD/DC server and client for Unix
samba419-4.19.5_1              Free SMB/CIFS and AD/DC server and client for Unix

Choose the version you want, usually the latest, and install it (in this example, samba419):

# pkg install samba419

Samba Configuration

Now we need to create the config file for Samba.

Create a new file at /usr/local/etc/smb4.conf and fill it with the following to start with:

[global]
   vfs objects = zfsacl fruit streams_xattr

   fruit:metadata = stream
   fruit:copyfile = yes
   fruit:veto_appledouble = no
   fruit:model = MacPro7,1@ECOLOR=226,226,224

   nfs4:chown = true
   disable netbios = yes
   strict sync = no 
   use sendfile = yes
   block size = 4096
   fstype = ZFS

   server smb encrypt = required

[Share]
   path = /tank/data
   read only = no

Let’s have a look at what some settings do so that you can tweak the configuration if necessary:

  • vfs objects = zfsacl fruit streams_xattr

    • Apple (macOS/iOS/iPadOS) clients greatly benefit from the fruit module. It can be removed if no such clients will be used.
    • streams_xattr provide support for Alternate Data Streams (ADS).
    • zfsacl provides full support for NFSv4 ACLs when using ZFS.
  • fruit:...

    • If not using Apple clients, these can be removed along with the fruit module in vfs objects.
    • Allows for better Finder/Files performance, server-side file copying, and showing a Mac Pro icon in the Network section in Finder.
  • nfs4:chown = true

    • This option allows the chown operation of the underlying filesystem. FreeBSD traditionally only allows the root user to change a file’s owner to someone else when handling files normally.
  • disable netbios = yes

    • Disables NetBIOS. The SMB share will not be automatically discoverable on some systems. If you desire this functionality, remove this option.
  • use sendfile = yes

    • Use sendfile(2) to potentially improve efficiency.
  • fstype = ZFS

    • Set the reported filesystem type to ZFS instead of the default NTFS.
    • Shouldn’t have any actual effect, mostly visual/informational.
    • Shows up in the Properties dialog in Windows, for example.
  • strict sync = no

    • If you are concerned about data loss in the event of a crash or power outage, then remove this option.
    • Apple clients seem to force a sync after writing each file when copying a batch of files, resulting in long pauses between copying files while waiting for the server to write the file. This option avoid these pauses.
    • This option may also be removed if your SMB client doesn’t request a sync after each file write.
    • If your zpool uses a SLOG device, this option might not improve performance and could probably be removed.
  • block size = 4096

    • Match this value to the sector size of the underlying storage and/or filesystem. I found that doing this slightly reduced CPU utilization during file transfers.
  • server smb encrypt = required

    • Requires SMB encryption, you should only remove this if you don’t care about data being visible in flight, if the network is fully trusted, or if you experience slow transfer speeds and would rather trade privacy/security for performance.
    • You could set this to desired instead to allow clients that don’t support encryption to still be able to connect.

Replace the [Share] definition with the appropriate values for your setup. You can add multiple definitions for multiple shares.

User Accounts and Groups

Create an appropriate user if one doesn’t already exist:

# adduser

Create an appropriate group if one doesn’t already exist:

# pw group add -n [groupname]

For example you may want a group media so that all users in the media group can work together on the same files.

Add the user(s) to the group:

# pw groupmod [groupname] -m [username]

Add the user(s) to the Samba user account database:

# pdbedit -a -u [username]

Permissions & ACLs

Now comes the fun part - UNIX permission modes and ACLs!

First, strip all NFSv4 ACLs (replace /tank/data with the appropriate path):

# setfacl -b -R /tank/data

Then, change the ownership recursively (replace values where appropriate):

# chown -R [username]:[groupname] /tank/data

Set the UNIX permission mode to 770 recursively (replace /tank/data with the appropriate path):

# chmod -R 770 /tank/data

Finally, let’s set some NFSv4 ACLs. These NFSv4 ACLs are based on the TrueNAS “RESTRICTED” preset of ACLs used in TrueNAS CORE (replace /tank/data with the appropriate path):

# setfacl -R -m owner@:full_set:fd:allow,group@:modify_set:fd:allow,everyone@::fd:allow /tank/data

Starting Services

Enable Samba:

# service samba_server enable

If you don’t use NetBIOS and don’t need related functionality, you can disable nmbd by adding nmbd_enable="NO" to /etc/rc.conf.

Now, let’s start Samba:

# service samba_server start

Conclusion

Connect from a client and enjoy your Samba file server powered by FreeBSD and ZFS!

If connecting from a Windows machine, NTFS-style ACLs should work great! Apple clients should work great as long as the fruit module is enabled and configured in Samba.

Note that certain clients, such as KDE Dolphin’s built-in SMB handling, don’t seem to support “streaming” or opening files directly off the share - they are first copied to the client and opened “offline” (as of writing this article). Sometimes apps can also fail to open files in this case.