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 case-sensitivity behavior, but this isn’t required and it is better to leave it default 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          nsupdate utility with the GSS-TSIG support
samba413-4.13.17_5             Free SMB/CIFS and AD/DC server and client for Unix
samba416-4.16.11               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, samba416):

# pkg install samba416

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

   strict sync = no
   use sendfile = yes
   block size = 4096

   server smb encrypt = desired

[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

    • macOS 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 macOS clients, these can be removed along with the fruit module in vfs objects.
    • Allows for better Finder performance, server-side file copying, and showing a Mac Pro icon in the Network section in Finder.
  • strict sync = no

    • Avoids slow write performance over SMB, if concerned about data loss in the event of a crash or power outage, then remove this option.
  • block size = 4096

    • Match this value to the physical sector size of the underlying storage. I found that doing this slightly reduced CPU utilization during file transfers.
  • server smb encrypt = desired

    • Desires 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.

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:fdI:allow,group@:modify_set:fdI:allow,everyone@::fdI:allow /tank/data
# setfacl -m owner@:full_set:fd:allow,group@:modify_set:fd:allow,everyone@::fd:allow /tank/data

Since the first command also sets the Inherited bit on the top directory, we issue a second command to remove that bit from the top directory since it didn’t actually inherit anything.

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 ACLs should work great! macOS 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.