@@ -325,3 +325,73 @@ The bucket needs correct access settings:
325325
326326- Public access must be enabled, not prevented.
327327- Access control should be set to fine-grained ("legacy ACL"), not uniform.
328+
329+ ## Systemd Integration
330+
331+ Zipserver supports systemd's sandboxing features through environment variables:
332+
333+ | Variable | Purpose | Systemd Directive |
334+ | ----------| ---------| -------------------|
335+ | ` RUNTIME_DIRECTORY ` | Temp directory for zip extraction (instead of ` ./zip_tmp ` ) | ` RuntimeDirectory= ` |
336+ | ` CREDENTIALS_DIRECTORY ` | Resolves credential paths like ` PrivateKeyPath ` | ` LoadCredential= ` |
337+ | ` ZIPSERVER_TMP_DIR ` | Custom temp directory (takes precedence over ` RUNTIME_DIRECTORY ` ) | - |
338+
339+ ### Credential Resolution
340+
341+ When ` CREDENTIALS_DIRECTORY ` is set, zipserver checks this directory first when loading credential files (e.g., ` PrivateKeyPath ` , ` GCSPrivateKeyPath ` ). This allows your config to use relative paths like ` "PrivateKeyPath": "secret/storage.pem" ` while systemd loads the actual file via ` LoadCredential= ` .
342+
343+ ### Example Hardened Unit File
344+
345+ ``` ini
346+ [Unit]
347+ Description =zipserver
348+ After =network.target
349+
350+ [Service]
351+ User =myuser
352+
353+ # Load credentials to /run/credentials/zipserver/
354+ LoadCredential =zipserver.json:/path/to/config/zipserver.json
355+ LoadCredential =storage.pem:/path/to/credentials/storage.pem
356+
357+ ExecStart =/usr/local/bin/zipserver --config =${CREDENTIALS_DIRECTORY}/zipserver.json
358+
359+ # Temp directory for zip extraction
360+ RuntimeDirectory =zipserver
361+ RuntimeDirectoryMode =0700
362+
363+ # Filesystem restrictions
364+ ProtectSystem =strict
365+ ProtectHome =tmpfs
366+ BindReadOnlyPaths =/usr/local/bin/zipserver
367+ PrivateTmp =true
368+
369+ # Network
370+ RestrictAddressFamilies =AF_INET AF_INET6 AF_UNIX
371+
372+ # Privilege restrictions
373+ NoNewPrivileges =true
374+ ProtectKernelTunables =true
375+ ProtectKernelModules =true
376+ ProtectControlGroups =true
377+ ProtectKernelLogs =true
378+ CapabilityBoundingSet =
379+ AmbientCapabilities =
380+
381+ # System call filtering
382+ SystemCallArchitectures =native
383+ SystemCallFilter =@system-service
384+ SystemCallFilter =~@privileged @resources
385+
386+ # Memory protections
387+ MemoryDenyWriteExecute =true
388+
389+ [Install]
390+ WantedBy =multi-user.target
391+ ```
392+
393+ ** Notes:**
394+
395+ - ` ProtectHome=tmpfs ` combined with ` BindReadOnlyPaths= ` allows exposing only the binary while hiding home directories
396+ - Use ` systemd-analyze security zipserver.service ` to check the security score
397+ - The ` RuntimeDirectory ` is automatically cleaned up when the service stops
0 commit comments