Major architectural change from rootless user services to system-level (rootful) containers to enable group-based Unix socket access for containerized applications. Infrastructure Changes: - PostgreSQL: Export postgres-clients group GID as Ansible fact - Valkey: Export valkey-clients group GID as Ansible fact - Valkey: Add socket-fix service to maintain correct socket group ownership - Both: Set socket directories to 770 with client group ownership Authentik Role Refactoring: - Remove rootless container configuration (subuid/subgid, lingering, user systemd) - Deploy Quadlet files to /etc/containers/systemd/ (system-level) - Use dynamic GID facts in container PodmanArgs (--group-add) - Simplify user creation to system user with infrastructure group membership - Update handlers for system scope service management - Remove unnecessary container security options (no user namespace isolation) Container Template Changes: - Pod: Remove --userns args, change WantedBy to multi-user.target - Containers: Replace Annotation with PodmanArgs using dynamic GIDs - Remove /dev/shm mounts and SecurityLabelDisable (not needed for rootful) - Change WantedBy to multi-user.target for system services Documentation Updates: - Add ADR-005: Rootful Containers with Infrastructure Fact Pattern - Update ADR-003: Podman + systemd for system-level deployment - Update authentik-deployment-guide.md for system scope commands - Update service-integration-guide.md with rootful pattern examples - Document discarded rootless approach and rationale Why Rootful Succeeds: - Direct UID/GID mapping preserves supplementary groups - Container process groups match host socket group ownership - No user namespace remapping breaking permissions Why Rootless Failed (Discarded): - User namespace UID/GID remapping broke group-based socket access - Supplementary groups remapped into subgid range didn't match socket ownership - Even with --userns=host and keep_original_groups, permissions failed Pattern Established: - Infrastructure roles create client groups and export GID facts - Application roles validate facts and consume in container templates - Rootful containers run as dedicated users with --group-add for socket access - System-level deployment provides standard systemd service management Deployment Validated: - Services in /system.slice/ ✓ - Process groups: 961 (valkey-clients), 962 (postgres-clients), 966 (authentik) ✓ - Socket permissions: 770 with client groups ✓ - HTTP endpoint responding ✓
81 lines
1.7 KiB
Django/Jinja
81 lines
1.7 KiB
Django/Jinja
# Valkey Systemd Service
|
|
# Generated by rick-infra Valkey role
|
|
#
|
|
# This service provides a secure, hardened Valkey instance with proper configuration loading
|
|
|
|
[Unit]
|
|
Description=Valkey (Redis-compatible) Key-Value Store
|
|
Documentation=https://valkey.io/
|
|
After=network.target
|
|
Wants=network-online.target
|
|
{% if valkey_unix_socket_enabled and valkey_client_group_create %}
|
|
Wants=valkey-socket-fix.service
|
|
{% endif %}
|
|
|
|
[Service]
|
|
Type=notify
|
|
User=valkey
|
|
Group=valkey
|
|
|
|
# Core service configuration - ensures config file is loaded
|
|
ExecStart=/usr/bin/valkey-server /etc/valkey/valkey.conf --supervised systemd
|
|
ExecReload=/bin/kill -USR2 $MAINPID
|
|
|
|
# Restart configuration
|
|
Restart=on-failure
|
|
RestartSec=5s
|
|
TimeoutStartSec=60
|
|
TimeoutStopSec=60
|
|
|
|
# Runtime directory
|
|
RuntimeDirectory=valkey
|
|
RuntimeDirectoryMode=755
|
|
|
|
# Resource limits
|
|
LimitNOFILE=10032
|
|
|
|
# Security hardening
|
|
NoNewPrivileges=yes
|
|
PrivateTmp=yes
|
|
PrivateDevices=yes
|
|
ProtectSystem=strict
|
|
ProtectHome=yes
|
|
ProtectKernelTunables=yes
|
|
ProtectKernelModules=yes
|
|
ProtectControlGroups=yes
|
|
RestrictRealtime=yes
|
|
RestrictSUIDSGID=yes
|
|
|
|
# Network security
|
|
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
|
|
|
|
# Filesystem permissions
|
|
ReadWritePaths=/var/lib/valkey
|
|
ReadOnlyPaths=/etc/valkey
|
|
|
|
# System call filtering
|
|
SystemCallFilter=@system-service
|
|
SystemCallFilter=~@privileged @resources @obsolete
|
|
|
|
# Memory and resource limits
|
|
MemoryDenyWriteExecute=yes
|
|
LockPersonality=yes
|
|
|
|
# Capabilities (remove all unnecessary capabilities)
|
|
CapabilityBoundingSet=
|
|
AmbientCapabilities=
|
|
|
|
# Process isolation
|
|
PrivateUsers=yes
|
|
RemoveIPC=yes
|
|
|
|
# Additional security
|
|
UMask=0027
|
|
|
|
# Ensure service stops cleanly
|
|
KillMode=mixed
|
|
KillSignal=SIGTERM
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
Alias=redis.service |