Apple Software Update Server Notes

I installed the software update service (or short: SUS; ‘Content Caching’ in High Sierra) on a box. But does it work?! Well, took some time investigate this feature. Below a brain dump of things I found out while looking into it. I need to remotely managed the thing so my focus is on the command line.

Previously this service was part of Server.app, but this has been moved into the base macOS High Sierra install.

Enable Content Caching through System Preferences -> Sharing -> Content Caching. If you press Alt while in that screen you will notice the ‘Options’ button change to ‘Advanced options’ for things like multi-WAN link support, etc.

It goes by several names:

  • Content Caching
  • Software Update Server, or SUS
  • Update Cache
  • AssetCache

SUS Server

AssetCacheManagerUtil

This tool allows controlling and checking the Asset Cache. It provides you information on the amount of data for example:

AssetCacheManagerUtil

which will produce output like:

... Built-in caching server status: {
 Activated = 1;
 Active = 1;
 CacheDetails = {
  iCloud = 17514000;
  "iOS Software" = 4376897000;
 };
 CacheFree = 1092067810304;
 CacheLimit = 0;
 CacheStatus = OK;
 CacheUsed = 4394411000;
 Parents = (
 );
 Peers = (
 );
 PersonalCacheFree = 1092067810304;
 PersonalCacheLimit = 0;
 PersonalCacheUsed = 17514000;
 Port = 49304;
 PrivateAddresses = (
  "192.168.178.107"
 );
 PublicAddress = "80.101.62.145";
 RegistrationStatus = 1;
 RestrictedMedia = 0;
 ServerGUID = "043694F8-BCB8-4F4A-81EF-6DBA9CAA5DAF";
 StartupStatus = OK;
 TotalBytesDropped = 0;
 TotalBytesImported = 17514000;
 TotalBytesReturnedToChildren = 0;
 TotalBytesReturnedToClients = 3537583328;
 TotalBytesReturnedToPeers = 0;
 TotalBytesStoredFromOrigin = 2927451538;
 TotalBytesStoredFromParents = 0;
 TotalBytesStoredFromPeers = 0;
}

Logging

To show logging for this service:

log show --predicate 'subsystem == "com.apple.AssetCache"' | less

If you replace show with stream it will report the logging live. It contains the much needed information on wether it actually works, for example lines like these (prefix replaced with ‘…’):

... Registering with local address: 192.168.178.107 (150 Mbit/sec wireless); port 49
304; local subnet range only: 192.168.178.0-192.168.178.255; version: 196; on AC power: yes; cache size: ~1 TB; capabilities: im,ns,pc,qp,sc,ur; portable: no
... Cleanup succeeded.
... Request for registration from https://lcdn-registration.apple.com/lcdn/register
succeeded
... Got back public IP 80.101.62.145
... This server knows about 0 other caching servers.
... Since server start: 0 bytes returned to clients, 0 bytes to peers, 0 bytes to children; 0 bytes stored from Internet, 0 bytes from peers, 0 bytes from parents; 7.6 MB imported.
... #pOi5EbtX2lWK Received PUT request by "cloudd/719" to store /abcdefghijklmnopqrst [icloud:abcdefghijklmnopqrst]

To see the effectiveness of the cache you check out these lines:

... Since server start: 2.89 GB returned to clients, 0 bytes to peers, 0 bytes to children; 2.28 GB stored from Internet, 0 bytes from peers, 0 bytes from parents; 17.5 MB imported.

Cached content

To see the cached content check out the sqlite database with commands on this page:

## Log onto SQL-Lite DB
# For High Sierra:
sudo sqlite3 '/Library/Application Support/Apple/AssetCache/Data/AssetInfo.db'
# For earlier versions:
sudo sqlite3 /Library/Server/Caching/Data/AssetInfo.db
 
## Then paste the following commands to see updates
.mode column
.headers on
select ZTOTALBYTES, datetime(ZCREATIONDATE+978307200,'unixepoch','localtime') as ZCREATIONDATE, datetime(ZLASTACCESSED+978307200,'unixepoch','localtime') as ZLASTACCESSED, ZLASTMODIFIEDSTRING, ZURI from ZASSET order by ZCREATIONDATE;

Other stuff

AssetCache configuration information can be found in:

 less /Library/Preferences/com.apple.AssetCache.plist

Information on these settings can be found in this Apple support page.

To see the actual space used by the cache (the directory can be found in the .plist file mentioned above, or in the output of AssetCacheManagerUtil settings):

 sudo du -sh '/Library/Application Support/Apple/AssetCache/Data'

You can change the location of the cache, but this is restricted. See the AssetCacheManagerUtil man page.

Configuring WAN IP address(es)

If you use a setup with multiple WAN links you need to provide discovery information for these WAN IP addresses through DNS. You need to add an entry like (example for bind):

_aaplcache._tcp 259200 IN TXT "prs=1.2.3.4,1.2.3.5"

This specifies that the name _aaplcache._tcp, in the domain this entry is added to, provides a TXT record in class IN Internet with an expiry of 259200s (3 days) with the value prs=1.2.3.4,1.2.3.5. That’s it. You can find this info after setting My local networks to use custom IP addresses in Sharing -> Content Caching -> Advanced Options -> Clients -> DNS Configuration.

Now, the domain this should be in: This should be the local domain the clients use for resolving. So, say your client requests an IP address through DHCP and is returned a DNS search domain of fritz.box, then the _aaplcache._tcp needs to be in that domain. `_aaplcache._tcp.fritz.box. . The trailing dot is important, as it indicates that that’s it, no more adding of search domains. On your MacBook you can find this search domain in System Preferences -> Network -> Wi-Fi -> Advanced… -> DNS -> Search Domains. In Windows you can for retrieve that search domain from the ipconfig command in a cmd window. On any UNIX you can find it in /etc/resolv.conf .

unbound

In unbound you can add this DNS record through a local-data statement in the server section of the unbound.conf file:

  local-data: '_aaplcache._tcp.fritz.box. 14400 TXT "prs=1.2.3.4,1.2.3.5"'

Note that I left out the IN class as it is the default. I also changed the expiry to 4h.

With unbound this can even be submitted into a running DNS service using the following commands (you need to remove any old data first to avoid duplicate entries; it doesn’t overwrite):

unbound-control local_data_remove _aaplcache._tcp.fritz.box.
unbound-control local_data \
    _aaplcache._tcp.fritz.box. 14400 TXT prs=1.2.3.4,1.2.3.5

If you change it frequently, use an even lower expiry, like 1800s (30 min.) (the second line is split over two lines, and can be either cut&pasted as is with the \ at the end, or combined into one line).

Testing

To test whether the cache is actually working, start off with running

AssetCacheLocatorUtil

on the content cache itself to see whether the cache machine can use itself as a cache. Then try the same command on a client. Check in both to see whether it can reach (at least one of) the content cache(s).

SUS clients

To see whether or  not a host sees the content cache, for example on the SUS itself, run:

AssetCacheLocatorUtil

It will for example show you a line like

2017-11-06 12:54:51.814 AssetCacheLocatorUtil[44819:911557] localhost:49304, rank 0, guid 043694F8-BCB8-4F4A-81EF-6DBA9CAA5DAF, valid until 2017-11-06 13:14:51; supports personal caching: yes, and import: yes, shared caching: yes

showing you for example the IP address and port the asset cache is running on. It will write out a file diskcache.plist which you should be able to dump with plutil (as root):

ls -l /var/folders/*/*/C/com.apple.AssetCacheLocatorService/diskCache.plist

sudo plutil -p /var/folders/*/*/C/com.appleAssetCacheLocatorService/diskCache.plist

See the man page for more information on how to use this utility:

man AssetCacheLocatorUtil

 

Leave a Reply

Your email address will not be published. Required fields are marked *