One of the most important things to have on a home server is some kind of file server. I chose to replace macOS Server’s file server with Samba on Ubuntu. This ended up being one of the more difficult things to get correct.
This story is part of a series on migrating from macOS Server to Ubuntu Server.
You can find all of the other stories in the series here.
I have never had much luck with Samba. I could never get it working quite how I wanted. There were always permission issues, and sometimes it’d just go down randomly. Not only was my goal to make a stable, permission-issue-free Samba server, I also wanted it to work very closely to how the macOS Server file server works, namely that extended attribute files (the files that start with
._) would not cause a mess if I access shared folders from the terminal on my Mac.
Laying the Groundwork
First things first, we need to install Samba:
sudo apt install samba sudo ufw allow in "Samba"
After that, it might be a good time to set up all the folders you plan to have shared. In my instance, I created a
/media/Shares directory to hold all of my shared folders. I also created a group to easily manage users who can read & write to the shares. For the sake of this next code block,
server is the main user on the machine,
shares-access is a group that will have read/write permissions for shared folders, and
klanchman is a member of
shares-access. These commands should be adjusted to match your system and desired username for connecting to shared folders.
sudo adduser klanchman sudo smbpasswd -a klanchman sudo addgroup shares-access sudo usermod server -aG shares-access sudo usermod klanchman -aG shares-access # Create the shared paths, chown to server:shares-access, chmod 770 - example: # cd /media/Shares # sudo mkdir Plex\ Media # sudo mkdir Public # sudo chown server:shares-access Plex\ Media/ Public/ # sudo chmod 770 Plex\ Media/ Public/ # Create private paths # cd /media/Shares # sudo mkdir klanchman # sudo chown klanchman:klanchman klanchman # sudo chmod 770 klanchman
Notice that we’ll also be configuring some shared folders, like
klanchman, that only allow a specific user to access them, rather than anyone in the
Now it’s time to configure Samba itself. This is the part that caused the most headache for me.
It’s important to point out that I am accessing shared folders exclusively with macOS clients. I think Linux clients should behave fine too, but if you also want to use Windows clients you may need to tweak some of this configuration.
sudo EDITOR /etc/samba/smb.conf, replacing
EDITOR with your favorite editor. Near the top, set the following if it’s not already there:
[global] security = user
Then, comment printer-related stuff (assuming you don’t plan to share printers).
Then come the shares. I’ll dump the config first, then explain in the next section a couple of things that are here, and why they’re here.
### My Shares ### # Global options guest ok = no read only = no create mask = 0660 directory mask = 0770 map archive = no map hidden = no map system = no valid users = @shares-access ea support = yes vfs objects = fruit streams_xattr fruit:aapl = yes fruit:encoding = private fruit:resource = file # Prevent macOS from assigning its own permissions fruit:nfs_aces = no inherit acls = yes inherit permissions = yes acl group control = yes nt acl support = yes acl map full control = no [Public] comment = Public path = /media/Shares/Public [Plex Media] comment = Plex Media path = /media/Shares/Plex Media [klanchman] comment = klanchman path = /media/Shares/klanchman force user = klanchman force group = klanchman valid users = klanchman
Save the file, and then restart Samba:
sudo systemctl restart smbd.service nmbd.service
If you want to know why/how the above stuff works, read on. Otherwise, you can skip to the next section.
So what is all of this doing? Let’s look a little closer…
It’s important to note that everything up to
[Public] applies to all shares. This config makes some assumptions about how you want to use your file server, such as limiting who has access to the shares.
This block does most of the heavy lifting in preventing permissions issues:
create mask = 0660 directory mask = 0770 map archive = no map hidden = no map system = no
This says files should be created with
0660 permissions (i.e.
-rw-rw----), and directories
0770. A point of interest is the
map xxxx = no directives. If these were set to
yes, Samba would map the Windows archive/hidden/system bits to the execute bits on the Linux side. For instance, if you had a file with the archive bit enabled, the permissions on the Linux side would become
0760. But that also means that macOS will see them that way, which isn’t what we want!
The next block of config that helps with permissions issues says this:
inherit acls = yes inherit permissions = yes acl group control = yes nt acl support = yes acl map full control = no
Ultimately this will allow ACLs set on the Linux side to be respected by Samba. I use ACLs to some extent (I’ll explain more in upcoming posts), so I wanted to make sure they worked properly in shared folders.
Last, the block that does some Apple-specific stuff:
ea support = yes vfs objects = fruit streams_xattr fruit:aapl = yes fruit:encoding = private fruit:resource = file # Prevent macOS from assigning its own permissions fruit:nfs_aces = no
The first line is easy, it enables extended attribute support. But what is all this
fruit stuff? I’m glad you asked! The Samba doc for it is here. Basically it enabled enhanced support for Apple clients. So, a quick breakdown:
vfs objectsessentially loads the module
fruit:appl = yesturns it on the extension
fruit:encoding = privatestores characters as the macOS client sends them
fruit:resource = filekeeps AppleDouble files (the
._files) for extended attributes
fruit:nfs_aces = noprevents macOS from doing stuff to permissions (in my experience)
You might be asking, “Why are you using
fruit:resource = file if you don’t want the
._ files to show up?” Number 1: the other options weren’t going to work for me, namely
xattr, since I’m running Ubuntu and ext4, not Solaris and ZFS. Number 2: in my experience the files aren’t actually visible on the share, but the attributes stick around. Of particular interest, the files don’t even seem to show up on Linux inside the share. Where are they? I don’t actually know, but the attributes work so I don’t really care!
So that’s the gist of it. It doesn’t look like much at a glance, but getting this to work the way I expected took many hours spread over multiple days. Documentation for some of these options was a little scattered, and first-hand accounts of using them numbered few. It was…interesting getting this to work, but I’m quite happy with the result.
We’re almost done! We’ve got a slick new Samba server set up, but nothing on the network knows about it. That’s where Avahi comes in. Avahi is basically an implementation of Bonjour for Linux. It will broadcast the existence of our Samba shares to devices on the network.
Getting it set up is pretty easy:
sudo apt install avahi-daemon
Now we need to create a UFW rule.
sudo EDITOR /etc/ufw/applications.d/avahi
[Avahi] title=Avahi description=Avahi Zeroconf ports=5353/udp
sudo ufw allow avahi.
Now we need to set up a service for Avahi to broadcast.
sudo EDITOR /etc/avahi/services/smb.service
<?xml version="1.0" standalone='no'?> <!DOCTYPE service-group SYSTEM "avahi-service.dtd"> <service-group> <name replace-wildcards="yes">%h</name> <service> <type>_smb._tcp</type> <port>445</port> </service> <service> <type>_device-info._tcp</type> <port>0</port> <txt-record>model=RackMac</txt-record> </service> </service-group>
This tells Avahi we have a service running on port 445 called
_smb._tcp. You may also notice
<txt-record>model=RackMac</txt-record>. This tells Mac clients what to show as the icon for the server in Finder. I went with
RackMac, which looks like an Xserve server. You can find other names by looking through
/System/Library/CoreServices/CoreTypes.bundle/Contents/Info.plist on your Mac.
Lastly we just need to start Avahi:
sudo systemctl enable avahi-daemon sudo systemctl start avahi-daemon
If all went well, you should now see your Ubuntu server in your Finder sidebar as a file server. You should be able to connect using the credentials you created with
smbpasswd earlier. Next time we’ll take a look at how to do Time Machine backups to the server!