Munki Distribution Points
A distribution point is a local cache for Munki package installers. The server redirects matching package requests to the cache's configured HTTPS URL. The Munki client then downloads the installer from the cache.
How client matching works
The server selects a distribution point using the client IP derived from the current package request. It evaluates the address on every request rather than using an interface address reported by osquery. Request-time matching follows a client as it changes networks and avoids routing from stale inventory.
The address depends on how the client reaches the server:
| Request path | Address the client CIDR must match |
|---|---|
| Directly over the same private network | The client's private source address, such as 10.20.0.0/16 |
| Directly over the internet | The public egress address after NAT, such as 203.0.113.42/32 |
| Through a correctly configured reverse proxy | The client address selected from a trusted forwarded header, commonly the client's public egress address |
| Through a proxy without client-IP configuration | The proxy's connection address; unrelated clients can appear to come from the same source and match the wrong location |
If clients can reach the server over both IPv4 and IPv6, assign the relevant ranges for both protocols.
The default remote_addr source reads the peer connected directly to the server. Before assigning client CIDRs behind a proxy, configure Client IP so the server trusts only the proxy's sanitized forwarded address. Otherwise, the CIDRs describe the proxy network rather than the Munki clients.
Example: internet-hosted server with an on-premises cache
Suppose a campus has the public egress address 203.0.113.42, the server sits behind Cloudflare, and mdp.example.com is reachable only from the campus:
- Restrict the server origin to the Cloudflare path. Cloudflare supplies the connecting client address in
CF-Connecting-IP. - Configure
WOODSTAR_HTTP_CLIENT_IP_SOURCE=headerandWOODSTAR_HTTP_CLIENT_IP_HEADER=CF-Connecting-IP. - Assign
203.0.113.42/32to the distribution point. - Ensure campus clients can resolve and reach
https://mdp.example.com.
Campus requests match the cache using their current public egress address. Off-campus requests do not match and the server serves those packages from primary storage. If clients instead reach it directly over the campus network, keep the default client-IP source and assign the relevant private subnet.
Create a distribution point
Under Munki > Distribution Points:
- Create a point with an HTTPS URL that its Munki clients can resolve and reach.
- Add the client CIDRs that should use the cache.
- Copy the key shown after creation.
- Start
woodstar mdpon the machine that will hold the cached installers.
Points are evaluated in their displayed order. A package is redirected only when the point is enabled, the worker is connected, the derived client IP matches one of the configured CIDRs, and the cached package is current.
The server cannot test whether a Munki client can reach the cache URL. It knows that the worker is connected and has the package, but cannot see DNS, routing, firewall, or TLS failures between the client and the cache. If that connection fails after the redirect, the package download fails and the same request cannot fall back to primary storage.
Only assign client CIDRs that can resolve and connect to the configured URL over HTTPS.
Run the worker
Download the archive for the worker host from GitHub Releases, extract it, and place woodstar on PATH. Releases include Linux and macOS archives for AMD64 and ARM64.
WOODSTAR_MDP_SERVER_URL=https://woodstar.example.com
WOODSTAR_MDP_KEY=<distribution-point-key>
WOODSTAR_MDP_DATA_DIR=/var/lib/woodstar-mdp
WOODSTAR_MDP_TLS_CERT_FILE=/etc/woodstar/tls/fullchain.pem
WOODSTAR_MDP_TLS_KEY_FILE=/etc/woodstar/tls/private-key.pem
woodstar mdp
The worker listens on :8080 by default. Set both worker TLS files for direct HTTPS, or leave both empty behind a reverse proxy.
The repository Compose file can run the same worker from the published image. Set the worker values in .env, then enable its profile:
docker compose --profile mdp up -d
The mdp profile is disabled during an ordinary docker compose up.
See Environment for every worker setting.
Caching
The worker keeps a WebSocket connection to the server and receives the complete desired package list. Missing or changed installers are cached and checked by size and SHA-256. Unwanted installers are removed.
The WebSocket upgrade requires an exact protocol match. The server rejects mismatched workers, and the UI marks them as incompatible. The two processes exchange build versions for diagnostics; build versions do not control protocol compatibility. Run the same release for both.
Cache state is kept in the data directory, and downloads resume after a restart. The UI reports each package as pending, syncing, current, or in error.
The worker uses the distribution-point key to connect and request short-lived download URLs. Database and storage credentials stay on the server.
Serving packages
Munki requests packages from the server as usual. When a matching point has the package, the server redirects the request with a signed, short-lived grant. The worker validates the grant and supports byte ranges for resumed downloads.
If the worker is offline, the cached package is stale, or the client's address does not match the configured CIDRs, the package comes from primary storage. This fallback happens before a redirect and cannot help when the selected cache is unreachable from the client.
Rotating a distribution-point key disconnects the old worker and invalidates its download grants. Update WOODSTAR_MDP_KEY before restarting the worker.