# Landlock Policy Template: Minimal (Stateless Services) # This policy provides the absolute minimum filesystem access # Ideal for stateless microservices, API endpoints, and compute workloads # Version: 1.0 # Policy metadata policy: name: minimal version: "1.0" description: "Minimal Landlock policy for stateless services and microservices" category: minimal author: "ArmoredLinux" # Filesystem access rules # This is an extremely restrictive policy - only ephemeral storage and read-only system files filesystem: # Read-only access (minimal system files only) read_only: # Timezone data (if application needs time zone conversion) - path: /usr/share/zoneinfo recursive: true description: "Timezone information" # DNS resolution - path: /etc/hosts recursive: false description: "Hosts file" - path: /etc/resolv.conf recursive: false description: "DNS resolver configuration" # SSL/TLS certificates (for HTTPS clients) - path: /etc/ssl/certs recursive: true description: "SSL CA certificates" # System libraries (dynamically linked binaries only) # Comment out if using static binaries - path: /usr/lib recursive: true description: "System libraries" - path: /lib recursive: true description: "System libraries" # Application binary (read-only) - path: /app recursive: true description: "Application code (read-only)" # Read-write access (ephemeral only - no persistent storage) read_write_ephemeral: # Temporary files (tmpfs - memory-backed) - path: /tmp recursive: true storage_type: tmpfs description: "Temporary files (tmpfs)" # Runtime state (tmpfs) - path: /var/run recursive: true storage_type: tmpfs description: "Runtime state files" - path: /run recursive: true storage_type: tmpfs description: "Runtime state files" # NO persistent storage allowed read_write_persistent: [] # Execute access (application binary only) execute: # Application binary - path: /app/service description: "Application binary" # Dynamic linker (if using dynamically linked binaries) # Comment out for static binaries - path: /lib64/ld-linux-x86-64.so.2 description: "Dynamic linker" - path: /lib/ld-linux.so.2 description: "Dynamic linker (32-bit)" # NO shell access (critical for security) # If shell is needed, this is not a minimal container # Network access network: # Allow binding to application port only bind_ports: - port: 8080 protocol: tcp description: "Application HTTP port" # Allow outbound connections (minimal) egress: # DNS lookups - port: 53 protocol: udp description: "DNS queries" - port: 53 protocol: tcp description: "DNS queries (TCP)" # HTTPS (for API calls to external services) - port: 443 protocol: tcp description: "HTTPS outbound" # NTP (optional - for time synchronization) - port: 123 protocol: udp description: "NTP time sync" # Backend services (configure as needed) # - host: backend.example.com # port: 8000 # protocol: tcp # description: "Backend API" # Capabilities # Minimal containers need almost NO capabilities capabilities: # NET_BIND_SERVICE if binding to port < 1024 # Otherwise, NO capabilities needed # - CAP_NET_BIND_SERVICE # For truly minimal containers, use an empty list [] # System calls allowed (minimal set) # This is a very restrictive syscall allowlist syscalls: allow: # File operations (read-only) - open - openat - read - close - stat - fstat - lseek - mmap - munmap # Network operations - socket - bind - listen - accept - accept4 - connect - sendto - recvfrom - sendmsg - recvmsg - setsockopt - getsockopt - shutdown # Process operations (minimal) - clone - exit - exit_group - getpid - wait4 # Memory management - brk - mmap - munmap - mprotect # Time - gettimeofday - clock_gettime - nanosleep # Signals - rt_sigaction - rt_sigprocmask - rt_sigreturn # Thread operations (if multi-threaded) - futex - set_robust_list - get_robust_list # I/O multiplexing - epoll_create - epoll_create1 - epoll_ctl - epoll_wait - epoll_pwait - poll - ppoll - select - pselect6 # Write (only to allowed paths - enforced by Landlock) - write - writev # Enforcement mode enforcement: mode: strict log_violations: true require_landlock: true # Security notes notes: | MINIMAL POLICY PHILOSOPHY: This policy is designed for containers that: 1. Run a SINGLE stateless service 2. Have NO persistent storage requirements 3. Do NOT need shell access 4. Do NOT need file system writes (except /tmp) 5. Communicate only over network IDEAL USE CASES: - Stateless HTTP API servers - Message queue consumers - Stream processing workers - Serverless function handlers - Load balancer frontends - Reverse proxies - Caching layers (using external Redis/Memcached) SECURITY BENEFITS: 1. Attack Surface Reduction: - No shell = no RCE via shell injection - No writable persistent storage = no persistence for malware - Minimal syscalls = reduced kernel attack surface - No capabilities = no privilege escalation vectors 2. Container Escape Prevention: - Landlock prevents filesystem access outside allowed paths - No exec of arbitrary binaries - No ptrace, no kernel module loading - No access to sensitive kernel interfaces 3. Data Exfiltration Prevention: - No writable persistent storage prevents data staging - Network policies control egress destinations - Minimal filesystem access limits data visibility BUILDING MINIMAL CONTAINERS: For best results with this policy, build containers using: - Static binaries (no dynamic linking) - Multi-stage Docker builds (distroless final stage) - No package managers in final image - No shells or debugging tools - No write access to application code directories Example Dockerfile for minimal container: ```dockerfile FROM golang:1.21 AS builder WORKDIR /build COPY . . RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o service FROM scratch COPY --from=builder /build/service /app/service COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ ENTRYPOINT ["/app/service"] ``` CONFIGURATION NOTES: - Adjust /app path to match your application directory - Add specific backend service hosts to egress rules - Remove system libraries if using static binaries - Test thoroughly in permissive mode before enforcing MONITORING: Monitor for: - Landlock violations (indicates policy too restrictive or compromise attempt) - Unexpected network connections - High memory usage (could indicate memory leak or abuse) - Process crashes (could indicate syscall denials) This is the GOLD STANDARD for Voltainer security. All production services should strive to use this minimal policy or a close variant.