Tuesday, November 12, 2013

Same Samba share for linux and macos

I have a shared data drive that I want to use as a file server on the local network. But as I have a dual boot, I want the same share to be available on both linux and macOS, and I want it to be an open share without a password. First, to mount it under both, see my computer setup post.

1) Under linux, it's pretty straightforward. Make sure that the data disk is mounted, and you have the samba3 package.

Then create a samba user and group:
sudo groupadd smbusers 
sudo useradd -g smbusers -d /dev/null -s /bin/false smbguest

add primary user(s) to smbusers group (just in case):
sudo usermod -a username -G smbusers

and make smbusers the default gid for the mount (within /etc/fstab; I use ufsd, otherwise replace with ntfs):

/dev/sda1    /data        ufsd    uid=briggsjt,gid=smbusers,noatime,umask=
0002    0    1

Then edit /etc/smb.conf, adding:

guest account = smbguest
force user = smbguest
null passwords = yes

and add an entry for the share:

[data]
        comment = data
        path = /data
        writeable = yes
        browseable = yes
        guest ok = yes
        read only = no
        create mask = 666  
        directory mask = 777

I recommend the following for best performance:

socket options = TCP_NODELAY IPTOS_LOWDELAY
strict allocate = yes

The latter mainly helps for ext4/xfs/btrfs drives, but hey. 

Many people recommend setting SO_RCVBUF=8192 and SO_SNDBUF=8192. Here in 2013, I found these to be much slower than the linux defaults (which are 87380 and 16384 respectively (from /proc/sys/net/ipv4/tcp_[rw]mem)). Setting them slightly higher didn't seem to help either. I played with a lot of other things but nothing else much improved over defaults. I was surprised to see how much slower my wireless network was than wired. (Wired I get 40-45MB/s sustained write to the NTFS drive, wireless it's more like 4-10, with 802.11n dual band and no obstructions).

To test changes to smbd:
sudo service smbd restart

We can also optionally have our samba service advertise itself via bonjour over the network using avahi-daemon (so it will appear in Finder on Macs, etc): Simply create a file /etc/avahi/services/smb.service with the following contents:

<?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>

And run sudo service avahi-daemon restart


2) Under MacOS:

There is a version of smbd on macos, however since 10.7 or so, it's an apple implementation and it does not allow guest access without a username. This means there's no simple way to use the same authentication as linux so it will be available no matter which OS I'm in. So instead I installed samba via macports. [Be sure to disable System Preferences->Sharing->File Sharing to avoid conflicts].

First ensure macports is installed: Install Xcode from the appstore. Install Xcode command-line tools: xcode-select --install. Download the macports .pkg installer from macports.org, and run.

Then install samba:
sudo port selfupdate
sudo port install samba3

Grab a drink and when you come back it's there.
In /opt/local/etc/samba3 there's a sample config file. Rename it to smb.conf and edit, adding a share like before:
[data]
   path = /Volumes/data
   public = yes
   browseable = yes   
   guest ok = yes     
   writable = yes     
   create mask = 666  
   directory mask = 777

Files will be written/read as the default user, and the drive must be accessible to him (you) locally.

To test it out, run:
sudo /opt/sbin/smbd -D && sudo /opt/sbin/nmbd -D

Then to launch automatically at startup, make a file /Library/LaunchDaemons/org.samba3.smbd.plist with these contents:

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>org.samba3.smbd</string>
  <key>ProgramArguments</key>
  <array>
    <string>/opt/local/sbin/smbd</string>
    <string>-D</string>
  </array>
  <key>RunAtLoad</key>
  <true/>
</dict>
</plist>

Make another identical file named /Library/LaunchDaemons/org.samba3.nmbd.plist, replacing the two 'smbd' occurrences with 'nmbd'.

Then, disable the existing macos smbd:

sudo launchctl stop com.apple.netbiosd
sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.netbiosd.plist

And run yours:

sudo launchctl load /Library/LaunchDaemons/org.samba3.smbd.plist
sudo launchctl load /Library/LaunchDaemons/org.samba3.nmbd.plist
sudo launchctl start org.samba3.smbd
sudo launchctl start org.samba3.nmbd

Finally be sure to set DHCP in your router to always assign the mac address of your computer to the same IP address (you could alternatively set the same static IP in both OSes). Then simply connect to the data samba share (eg: \\192.168.1.10\data or smb://192.168.1.10/data) and it will work no matter which OS you're running! 

As a finishing touch, you can optionally set up the computer to advertise smbd as a Bonjour service. On the Mac side, this will not only make it easy to find, but more importantly to me anyway, it will enable Wake On Demand. This is a pretty cool feature that ensures that when the mac is in sleep mode, because it's not actively being used, the drive shares will still remain available whenever anyone on the network needs them, because the computer will be notified to start back up and respond to any requests that could come. In a use scenario like mine, in a home, this can save a ton of power by often being on standby, without sacrificing convenience. To work, it requires another device on the network that is always "on" and that acts as a sleep proxy. An AirPort Base Station, Time Capsule, or Apple TV will automatically perform this function, and other devices can be set up to.

Anyway, setting it up is actually a pretty simple matter of running the dns-sd command, and leaving it running while the computer is up (this assumes that samba has the same lifetime, which it should if you did as above). It can be done by creating a file /Library/LaunchDaemons/org.samba3.smbd.servicepublisher.plist with the following content:

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>org.samba3.smbd.servicepublisher</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/dns-sd</string>
<string>-R</string>
<string>samba</string>
<string>_smb._tcp</string>
<string>.</string>
<string>445</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>

Note that even if you used the default mac samba implementation, it appears that macs don't advertise the samba service. Adding this file will do that and so enable Wake on Demand for it. You can run dns-sd -B _services._dns-sd._udp to see all the available services on the network, which should now include smb, once you reboot.

P.S. I had to use my second ethernet port (the atheros one) in order for this to work -- it appears the MacOS intel ethernet driver won't handle Wake On LAN properly. Details are here.

1 comment:

  1. Cool. I'll play with this and see what I run into.

    ReplyDelete