Time Machine, AppleScript, and Samba

I have a small HP MicroServer running CentOS Linux I use mostly as a file server. I recently slapped on a MediaSonic ProBox I picked up so I could make use of some older matched drives (from an old ReadyNAS box and an earlier MicroServer) for less critical stuff, like a Time Machine backup. (I’m also already mirroring critical directories using SyncThing, and have off-site encrypted backups of that, too.) Some of this stuff was a nightmare to figure out, so, the steps I took are presented here, in hopes it helps someone else...

Configuring Samba

I’m connecting my Mac OS X computers (El Capitan 10.11.x (“Air-Core-i5”; Mavericks 10.9.x; one old Core 2 Duo MacBook running Lion 10.7.x) to a CentOS 6.9 server using Samba (“Gen8NAS” with IP address 192.168.66.10).

Install Samba

$ sudo yum -y install samba samba-client

Configure Samba

The only real “gotcha” here was the ‘msdfs root = yes’ entry, which eliminated an error I was getting on OS X, “the share does not exist on the server.”

$ sudo vi /etc/samba/smb.conf    # Only the critical configuration lines are shown:
[global]
workgroup = mooneynet
server string = Samba Server Version %v
netbios name = NAS
hosts allow = 127. 192.168.
log file = /var/log/samba/log.%m
max log size = 50
security = user
passdb backend = tdbsam
[homes]
comment = Home Directories
browseable = no
writable = yes
valid users = %S
create mask = 0700
directory mask = 0700
[nas]
comment = Exports
path = /nas
valid users = @files ; any user in UNIX group 'files'
public = yes
writable = yes
printable = no
create mask = 0775
msdfs root = yes

Start the service and make sure it starts when the system boots:

$ sudo service smb restart
$ sudo chkconfig on smb

Create a Samba user/password entry for the user 'm20pilot':

$ sudo smbpasswd -a m20pilot

Create a UNIX group 'files' (if it doesn't already exist) and add the user 'm20pilot' to that group:

$ sudo groupadd files
$ sudo usermod --append --groups files m20pilot

Verify the server is running and the expected shares are online:

$ smbclient -L //localhost/ -U m20pilot

Enter m20pilot's password: 
Domain=[mooneynet] OS=[Unix] Server=[Samba 3.6.23-44.el6_9]

Sharename       Type      Comment
---------       ----      -------
IPC$            IPC       IPC Service (Samba Server Version 3.6.23-44.el6_9)
nas         Disk      Exports
m20pilot        Disk      Home Directories
Domain=[mooneynet] OS=[Unix] Server=[Samba 3.6.23-44.el6_9]

Server               Comment
---------            -------

Workgroup            Master
---------            -------

From the Mac, verify everything looks good:

MacBook-Air-Core-i5:~ m20pilot$ smbutil view //m20pilot:MyPassw0rd@192.168.66.10
Share                                           Type    Comments
-------------------------------
IPC$                                            Pipe    IPC Service (Samba Server Version 3.6.23-44.el6_9)
nas                                             Disk    Exports
m20pilot                                        Disk    Home Directories

3 shares listed


Use the Finder’s Command-K keystroke (or the Go menu’s Connect to Server... option) to mount: smb://192.168.66.10/nas

Note: You might need to setup firewall rules (the examples below open Samba to localhost and to the network 192.168.66.0/24), and SELinux (which I don’t use, so don’t discuss here):

# vi /etc/sysconfig/iptables
-A RH-Firewall-1-INPUT -s 192.168.66.0/24 -p tcp -m state --state NEW -m tcp --dport 137 -j ACCEPT
-A RH-Firewall-1-INPUT -s 192.168.66.0/24 -p tcp -m state --state NEW -m tcp --dport 138 -j ACCEPT
-A RH-Firewall-1-INPUT -s 192.168.66.0/24 -p tcp -m state --state NEW -m tcp --dport 139 -j ACCEPT
-A RH-Firewall-1-INPUT -s 192.168.66.0/24 -p tcp -m state --state NEW -m tcp --dport 445 -j ACCEPT
-A RH-Firewall-1-INPUT -s 127.0.0.0/8 -p tcp -m state --state NEW -m tcp --dport 137 -j ACCEPT
-A RH-Firewall-1-INPUT -s 127.0.0.0/8 -p tcp -m state --state NEW -m tcp --dport 138 -j ACCEPT
-A RH-Firewall-1-INPUT -s 127.0.0.0/8 -p tcp -m state --state NEW -m tcp --dport 139 -j ACCEPT
-A RH-Firewall-1-INPUT -s 127.0.0.0/8 -p tcp -m state --state NEW -m tcp --dport 445 -j ACCEPT
# service iptables restart

Time Machine on a Network Volume

Create a SparseBundle for Time Machine backups and “bless” it as a Time Machine volume

Recommend creating it locally and then moving it to the network attached storage.

hdiutil create -size 250g -type SPARSEBUNDLE -fs "HFS+J" Corei5Air.sparsebundle
$ hdiutil attach -mountpoint /Volumes/Corei5Air-TM/ /path/to/Corei5Air.sparsebundle
$ sudo tmutil setdestination /Volumes/Corei5Air-TM/

Time Machine should now see the drive and, if Time Machine is turned on, back up to it. If not, System Preferences -> Time Machine.

Mounting on Login / Wake from Sleep

I used Scenario to trigger AppleScript scripts automatically when I log into the Mac, or it wakes from sleep, by installing the following script (ConnectTimeMachine.scpt/Users/m20pilot/Library/Scenario/Wake Scripts/ into and /Users/m20pilot/Library/Scenario/Login Scripts/

I added the m20pilot account to the Mac’s UNIX “wheel” group and configured sudo to not require a password for ‘wheel’ users (this may be a security concern for you and you should know what you’re doing before setting things up this way):

$ sudo visudo
# Uncomment this line:
%wheel ALL=(ALL) NOPASSWD: ALL
$ sudo dseditgroup -o edit -a m20pilot -t user wheel 

The script has a built-in delay to allow the WiFi connection time to get established before it tries to mount the Samba NAS export, and also attempts to ping the server. If the server isn't accessible (i.e., the Mac is being used somewhere other than on its home network), the script won't try to mount the Samba share or the SparseBundle stored on it (to eliminate unnecessary pop-up error message alerts):

set delaySeconds to 3
set endTime to (current date) + delaySeconds
-- display alert "Delaying for " & delaySeconds & " second(s)..."
repeat while (current date) is less than endTime
-- delay delaySeconds *should* work but occasionally (Yosemite) doesn't work as expected; this should be resilient
delay 1
end repeat

-- Double check what user is being seen by sudo:
-- set script_cmd to "whoami"
-- set script_result to do shell script script_cmd
-- display dialog script_result

set IP_address to "192.168.66.10"
try
set ping to (do shell script "ping -c 2 " & IP_address)
-- display dialog "Connection Successful." buttons {"OK"} default button 1
on error
-- display dialog "Conection failed. Host is down" buttons {"Darn"} default button 1
-- if 192.168.66.10 is unreachable, we're probably not on the home network; exit quietly
return
end try

try
mount volume "smb://192.168.66.10/nas"
on error
return
end try


do shell script "sudo -S hdiutil attach -mountpoint /Volumes/Corei5Air-TM/ /Volumes/nas/ext/TimeMachine/Corei5Air.sparsebundle"






Comments