TimeMachine Menu

Recently Samba and in turn FreeNAS have added support for a Samba share to act as a SMB based Time Machine Target for Apple devices. We had a need for allowing multiple users to backup to a Time Machine Target but didn’t want them to have to enable encryption with a password they may forget and not be able to recover. At the same time, we didn’t want users to be able to restore/browse someone else’s backups.

The solution we came up was to change the create file mask/umask to give effectively the equivalent of umask 077 or chmod 700 to all newly created files/folders on the share. Samba and ACLs means that attempting things like force create mode or force directory mode have no effect when using FreeNAS.

One requirement was that the backups be self-maintaining and non-conflicting of storage allocation. To accomplish this, we set per-client storage quotas in addition to any quotas for the total backup volume.

Another feature we wanted was the ability to backup when on a network that was routable to the backup target fileserver, but not in the same subnet/VLAN. We found that you do not need to rely on mDNS broadcasts and use an Avahi mDNS Reflector (which we tried at first, it does not work for Time Machine Backups). What you can do instead is use tmutil from the command line to manually specify a Time Machine Backup Disk. This is persistent across reboots and will allow backups even over a VPN.

TL;DR of the goals and solutions

  1. Time Machine over SMB, hosted on Samba/FreeNAS
  2. Multiple, concurrent users that cannot see each other’s backups.
  3. Per-Computer Time Machine quotas to prevent consuming the entire network share.
  4. Cross-subnet/VLAN backups so that the FreeNAS server does not need an interface in every VLAN.
  5. The option to use Time Machine over VPN, or to disable it.

Create a SMB Time Machine Target

  1. Create a Dataset for your Time Machine Backups

    Freenas Dataset

  2. Create a Windows SMB, Time Machine Enabled Share

    Windows SMB, Time Machine Enabled Share

  3. Change the default permissions for the dataset:

    Note: If you already have permissions how you want them and only need to inherit permissions without changing the permissions of the root share. Modify the existing group/everyone ACLs and remove fd (inherit for files, inherit for directories). Then apply the second setfacl statement from below to remove all group/owner permissions for newly created files (umask of 077).

    1
    2
    3
    4
    5
    
    chown nobody:employees /mnt/tank/TimeMachine
    getfacl /mnt/tank/TimeMachine
    
    setfacl -m owner@:rwxpDdaARWcCos:fd:allow,group@:rwxpDdaARWcCos::allow,everyone@:::allow /mnt/tank/TimeMachine
    setfacl -a 0 group@::fdi:allow,everyone@::fdi:allow /mnt/tank/TimeMachine
    

    If you followed the above script, your result should look like this:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    [root@FreeNAS ~]# getfacl /mnt/tank/TimeMachine
    # file: /mnt/tank/TimeMachine
    # owner: nobody
    # group: employees
               group@:--------------:fdi----:allow
            everyone@:--------------:fdi----:allow
               owner@:rwxpDdaARWcCos:fd-----:allow
               group@:rwxpDdaARWcCos:-------:allow
            everyone@:--------------:-------:allow
    
  4. Set Per-Client Time Machine Quota

    Add the files to notify connecting Macs that this volume is Time Machine capable:

    1
    
    touch /mnt/tank/TimeMachine/.com.apple.timemachine.supported
    

    Set a 600GB quota for each machine:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    cat <<'EOF' >> /mnt/tank/TimeMachine/.com.apple.TimeMachine.quota.plist
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
        <dict>
            <key>GlobalQuota</key>
            <integer>600000000000</integer>
        </dict>
    </plist>
    EOF
    

    Ensure that everyone can read the Time Machine configuration files:

    1
    
    chmod 644 /mnt/tank/TimeMachine/.com.apple.*
    

    Set immutable bit on .com.apple.* to ensure they cannot be deleted or modified:

    1
    
    chflags schg /mnt/tank/TimeMachine/.com.apple.*
    

Connect to a SMB Time Machine Target on a different network

If your Time Machine Target and Client Machines will not always be on the same subnet, you can use tmutil to manually set a target. Then, as long as your Client has a route to the Target, your automatic backups will function. They will also function over VPN, which could be a good thing or a problem. For our organization, we added an Alias IP to the FreeNAS server and created a separate A-Record to point to it. This way, the same server can act as a fileserver to serve files to VPN clients as well as be a Time Machine Target. We did not want to consume our end-user’s home/mobile upload bandwidth, so we blocked the Target’s Alias IP at the firewall to prevent Time Machine from working over VPN.

  1. Disconnect Time Machine Drives (Also useful if a user’s password has been changed)

    1
    
    DemoMac01:~ $ sudo tmutil removedestination `tmutil destinationinfo | grep -E '^ID' | head -n1 | awk -F' : ' '{print $2}'`
    
  2. Map the Time Machine Service to the Share (Password will be saved across reboots)

    1
    
    DemoMac01:~ $ sudo tmutil setdestination -a smb://username:[email protected]/TimeMachine
    
  3. Enable Automatic Backups

    1
    
    DemoMac01:~ $ sudo tmutil enable
    

End Result

  • DemoMac01 (172.30.90/23) backing up to TimeMachine.Contoso.com (10.50.0.29/24):

    DemoMac01 backing up to TimeMachine.Contoso.com

  • Resulting File Permissions:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    root@FreeNAS:/mnt/tank/TimeMachine # ls -laho
    total 93
    drwxrwx---+  3 nobody    employees  uarch         7B May 14 22:09 .
    drwxrwxr-x+ 17 nobody    employees  uarch        18B May 14 17:54 ..
    -rwxrwxr-x+  1 root      wheel      uarch         0B May 14 17:54 .apple
    -r--r--r--   1 root      employees  schg,uarch  228B May 14 18:11 .com.apple.TimeMachine.quota.plist
    -r--r--r--   1 root      employees  schg,uarch    0B May 14 22:09 .com.apple.timemachine.supported
    -rwxrwxr-x+  1 root      wheel      uarch         0B May 14 17:55 .windows
    drwx------+  3 username  employees  uarch         9B May 14 22:12 DemoMac01.sparsebundle
    

Additional Resources and References

Notes for Linux Users with manual Samba Configs

Samba Config

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
[TimeMachine]
        aio write size = 0
        browseable = No
        path = "/mnt/tank/TimeMachine"
        read only = No
        veto files = /.snapshot/.windows/.mac/.zfs/
        vfs objects = zfs_space zfsacl fruit streams_xattr
        zfsacl:acesort = dontcare
        nfs4:chown = true
        nfs4:acedup = merge
        nfs4:mode = special
        fruit:volume_uuid = 4ac1e8c1-a7a2-4298-a06a-0fcdcac32100
        fruit:time machine = yes
        fruit:resource = stream
        fruit:metadata = stream