XDR Podman Quadlets for User Session: Enhanced Container Security
This guide demonstrates how to deploy XDR (Extended Detection and Response) agents as Podman Quadlets in user sessions, providing rootless container-based security monitoring with seamless systemd integration. This approach enhances security by running XDR agents without root privileges while maintaining full monitoring capabilities.
Overview
Podman Quadlets represent a modern approach to container management, combining the security benefits of rootless containers with the reliability of systemd service management. When applied to XDR deployment, this creates a robust security monitoring solution that:
- Runs without root privileges (enhanced security)
- Integrates with systemd for automatic startup and management
- Provides isolated execution environments
- Enables easy updates and maintenance
- Scales across multiple user sessions
Prerequisites
System Requirements
- Operating System: Linux with systemd 250+ (RHEL 9, Ubuntu 22.04, Fedora 36+)
- Podman: Version 4.4+ with quadlet support
- User Account: Regular user account (non-root)
- XDR Agent: Container image for your XDR solution
Initial Setup
# Verify Podman versionpodman --version
# Check systemd user instancesystemctl --user status
# Enable lingering for user (allows services to run without login)sudo loginctl enable-linger $USER
# Create quadlet directory structuremkdir -p ~/.config/containers/systemd/
Understanding Quadlets
Quadlets are systemd unit files that define how Podman containers should run. They’re automatically converted to proper systemd services by the podman-systemd-generator
.
Key Benefits
- Declarative Configuration: Define containers as systemd units
- Automatic Management: Systemd handles lifecycle, restarts, and dependencies
- User Session Support: Run containers in user context without root
- Native Integration: Leverage systemd features like timers and dependencies
XDR Agent Quadlet Configuration
Basic XDR Container Quadlet
Create ~/.config/containers/systemd/xdr-agent.container
:
[Unit]Description=XDR Security AgentDocumentation=https://docs.example.com/xdr-agentWants=network-online.targetAfter=network-online.targetStartLimitIntervalSec=60StartLimitBurst=3
[Container]# Container imageImage=registry.example.com/security/xdr-agent:latestContainerName=xdr-agent
# Security optionsSecurityLabelDisable=falseReadOnly=trueNoNewPrivileges=true
# Resource limitsCpuLimit=2MemoryLimit=2GMemoryReservation=1G
# Environment variablesEnvironment="XDR_SERVER=xdr.example.com"Environment="XDR_PORT=8443"Environment="LOG_LEVEL=info"EnvironmentFile=/home/%u/.config/xdr/agent.env
# Volume mountsVolume=/home/%u/.config/xdr/certs:/etc/xdr/certs:ro,ZVolume=/var/log/journal:/var/log/journal:roVolume=/proc:/host/proc:roVolume=/sys:/host/sys:roVolume=/etc/os-release:/host/etc/os-release:ro
# Tmpfs for temporary dataTmpfs=/tmp:size=512M,mode=1777Tmpfs=/var/tmp:size=512M,mode=1777
# Network configurationNetwork=hostHostname=xdr-%H
# Health checkHealthCmd="/usr/bin/xdr-agent healthcheck"HealthInterval=30sHealthRetries=3HealthTimeout=10sHealthStartPeriod=60s
# Labels for managementLabel="io.containers.autoupdate=registry"Label="com.example.component=security"Label="com.example.managed-by=quadlet"
[Service]# Restart policyRestart=alwaysRestartSec=30
# Systemd integrationType=notifyNotifyAccess=all
# Security hardeningPrivateTmp=yesProtectSystem=strictProtectHome=read-onlyProtectKernelTunables=yesProtectKernelModules=yesProtectControlGroups=yesRestrictRealtime=yesRestrictSUIDSGID=yesLockPersonality=yes
# TimeoutsTimeoutStartSec=120TimeoutStopSec=30
[Install]WantedBy=default.target
Advanced XDR Configuration with Secrets
Create ~/.config/containers/systemd/xdr-agent-advanced.container
:
[Unit]Description=Advanced XDR Security Agent with Secret ManagementDocumentation=https://docs.example.com/xdr-agentRequires=podman-secret-xdr-token.serviceAfter=podman-secret-xdr-token.service
[Container]Image=registry.example.com/security/xdr-agent:latestContainerName=xdr-agent-advanced
# Pull policyPull=newerPullRetryCount=3PullRetryDelay=10s
# User and group mappingUserNS=keep-idUser=1000Group=1000
# Capabilities (minimal required set)DropCapability=allAddCapability=CAP_SYS_PTRACE,CAP_DAC_READ_SEARCH,CAP_NET_RAW
# Secret managementSecret=xdr-token,type=env,target=XDR_AUTH_TOKENSecret=xdr-cert,type=mount,target=/etc/xdr/cert.pemSecret=xdr-key,type=mount,target=/etc/xdr/key.pem,mode=0600
# Advanced volumes with specific optionsVolume=/home/%u/.config/xdr/config.yaml:/etc/xdr/config.yaml:ro,ZVolume=xdr-data:/var/lib/xdr:ZVolume=/run/user/%U/podman/podman.sock:/var/run/docker.sock:ro
# Environment with interpolationEnvironment="HOSTNAME=%H"Environment="XDR_NODE_ID=%H-%u"Environment="XDR_CLUSTER_NAME=production"
# Entrypoint overrideEntrypoint=/usr/bin/xdr-agentCmd="--config=/etc/xdr/config.yaml" "--node-id=$XDR_NODE_ID"
# Logging configurationLogDriver=journaldLogOpt="tag=xdr-agent"LogOpt="labels=com.example.component"
[Service]Type=notifyRestart=on-failureRestartSec=30RestartPreventExitStatus=0 2
# Dependency orderingRequiresMountsFor=/home/%u/.config/xdr
# Resource accountingCPUAccounting=yesMemoryAccounting=yesTasksAccounting=yesIOAccounting=yes
# WatchdogWatchdogSec=60
[Install]WantedBy=default.target
Supporting Services
Secret Creation Service
Create ~/.config/containers/systemd/podman-secret-xdr-token.service
:
[Unit]Description=Create Podman Secret for XDR TokenConditionPathExists=!/run/user/%U/containers/secrets/xdr-tokenBefore=xdr-agent-advanced.service
[Service]Type=oneshotRemainAfterExit=yesExecStart=/bin/bash -c 'podman secret create xdr-token /home/%u/.config/xdr/token'ExecStop=podman secret rm xdr-token
[Install]WantedBy=default.target
Auto-Update Timer
Create ~/.config/containers/systemd/podman-auto-update-xdr.timer
:
[Unit]Description=Auto-update XDR containersDocumentation=man:podman-auto-update(1)
[Timer]OnCalendar=dailyRandomizedDelaySec=900Persistent=true
[Install]WantedBy=timers.target
Create ~/.config/containers/systemd/podman-auto-update-xdr.service
:
[Unit]Description=Auto-update XDR containersDocumentation=man:podman-auto-update(1)Wants=network-online.targetAfter=network-online.target
[Service]Type=oneshotExecStart=/usr/bin/podman auto-update --label "io.containers.autoupdate=registry"ExecStartPost=/usr/bin/systemctl --user try-restart xdr-agent.service
[Install]WantedBy=default.target
Configuration Files
XDR Agent Configuration
Create ~/.config/xdr/config.yaml
:
# XDR Agent Configurationversion: 2
agent: id: ${XDR_NODE_ID} name: ${HOSTNAME}-xdr type: endpoint
server: url: https://${XDR_SERVER}:${XDR_PORT} tls: cert: /etc/xdr/cert.pem key: /etc/xdr/key.pem ca: /etc/xdr/ca.pem verify: true
collectors: system: enabled: true interval: 60s metrics: - cpu - memory - disk - network
process: enabled: true interval: 30s include_cmdline: true
file_integrity: enabled: true paths: - /etc - /usr/bin - /usr/sbin - /home/%u/.ssh exclude: - "*.log" - "*.tmp"
network: enabled: true capture_packets: false connection_tracking: true
container: enabled: true runtime: podman socket: /var/run/docker.sock
logging: level: ${LOG_LEVEL} format: json outputs: - type: file path: /var/lib/xdr/agent.log rotate: max_size: 100M max_age: 7d max_backups: 5 - type: syslog facility: local0 tag: xdr-agent
response: enabled: true actions: - quarantine - kill_process - block_network require_approval: true
performance: max_cpu_percent: 20 max_memory_mb: 2048 rate_limit: events_per_second: 1000 burst: 5000
Environment File
Create ~/.config/xdr/agent.env
:
# XDR Agent Environment Variables# This file should be protected with appropriate permissions
# Server ConfigurationXDR_SERVER=xdr.example.comXDR_PORT=8443
# Agent SettingsXDR_DEPLOYMENT_TYPE=productionXDR_REGION=us-east-1XDR_TENANT_ID=tenant-123
# FeaturesXDR_FEATURE_EDR=trueXDR_FEATURE_DLP=falseXDR_FEATURE_COMPLIANCE=true
# Performance TuningXDR_WORKER_THREADS=4XDR_BUFFER_SIZE=65536XDR_BATCH_SIZE=100
# LoggingLOG_LEVEL=infoLOG_FORMAT=json
Deployment Process
Initial Deployment
#!/bin/bash# deploy-xdr.sh - XDR Deployment Script
set -euo pipefail
XDR_USER="${USER}"XDR_HOME="/home/${XDR_USER}"XDR_CONFIG="${XDR_HOME}/.config/xdr"
echo "Deploying XDR Agent for user: ${XDR_USER}"
# Create directoriesecho "Creating configuration directories..."mkdir -p "${XDR_CONFIG}/certs"mkdir -p "${XDR_HOME}/.config/containers/systemd"
# Set permissionschmod 700 "${XDR_CONFIG}"chmod 700 "${XDR_CONFIG}/certs"
# Generate or copy certificatesecho "Setting up certificates..."# Copy your certificates to ${XDR_CONFIG}/certs/# Ensure proper permissions (600 for keys, 644 for certs)
# Create secretsecho "Creating secrets..."if [ -f "${XDR_CONFIG}/token" ]; then podman secret create xdr-token "${XDR_CONFIG}/token" || truefi
# Reload systemdecho "Reloading systemd configuration..."systemctl --user daemon-reload
# Enable and start servicesecho "Enabling XDR services..."systemctl --user enable --now podman-secret-xdr-token.servicesystemctl --user enable --now xdr-agent.servicesystemctl --user enable --now podman-auto-update-xdr.timer
# Verify deploymentecho "Verifying deployment..."systemctl --user status xdr-agent.service --no-pagerpodman ps --filter "name=xdr-agent"
echo "XDR Agent deployment complete!"
Health Monitoring Script
Create ~/.local/bin/xdr-health-check.sh
:
#!/bin/bash# XDR Health Monitoring Script
set -euo pipefail
# Colors for outputRED='\033[0;31m'GREEN='\033[0;32m'YELLOW='\033[1;33m'NC='\033[0m' # No Color
echo "XDR Agent Health Check"echo "====================="
# Check service statusecho -n "Service Status: "if systemctl --user is-active --quiet xdr-agent.service; then echo -e "${GREEN}ACTIVE${NC}"else echo -e "${RED}INACTIVE${NC}" exit 1fi
# Check container statusecho -n "Container Status: "if podman ps --format "{{.Names}}" | grep -q "xdr-agent"; then echo -e "${GREEN}RUNNING${NC}"else echo -e "${RED}NOT RUNNING${NC}" exit 1fi
# Check container healthecho -n "Container Health: "HEALTH=$(podman inspect xdr-agent --format '{{.State.Health.Status}}' 2>/dev/null || echo "unknown")case $HEALTH in healthy) echo -e "${GREEN}HEALTHY${NC}" ;; starting) echo -e "${YELLOW}STARTING${NC}" ;; unhealthy) echo -e "${RED}UNHEALTHY${NC}" exit 1 ;; *) echo -e "${YELLOW}UNKNOWN${NC}" ;;esac
# Check resource usageecho -e "\nResource Usage:"podman stats --no-stream --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}" xdr-agent
# Check recent logs for errorsecho -e "\nRecent Errors (last 10 minutes):"journalctl --user -u xdr-agent.service --since "10 minutes ago" -p err --no-pager || echo "No errors found"
# Check auto-update statusecho -e "\nAuto-Update Status:"systemctl --user status podman-auto-update-xdr.timer --no-pager | grep -E "Loaded:|Active:|Trigger:"
echo -e "\nHealth check complete!"
Troubleshooting
Common Issues and Solutions
Service Won’t Start
# Check service statussystemctl --user status xdr-agent.service
# View detailed logsjournalctl --user -u xdr-agent.service -f
# Check quadlet generation/usr/lib/systemd/system-generators/podman-system-generator --user --dryrun
# Verify quadlet syntaxsystemd-analyze --user verify xdr-agent.service
Permission Issues
# Fix SELinux contextsrestorecon -Rv ~/.config/xdr/
# Check volume permissionspodman unshare ls -la /var/lib/containers/storage/volumes/xdr-data/_data
# Reset user namespacepodman system migrate
Network Connectivity
# Test from containerpodman run --rm -it --network host \ registry.example.com/security/xdr-agent:latest \ curl -v https://xdr.example.com:8443/health
# Check firewall rulesfirewall-cmd --list-all
Debug Mode
Create ~/.config/containers/systemd/xdr-agent-debug.container
for debugging:
[Unit]Description=XDR Agent Debug ModeConflicts=xdr-agent.service
[Container]Image=registry.example.com/security/xdr-agent:latestContainerName=xdr-agent-debug
# Debug settingsEnvironment="LOG_LEVEL=debug"Environment="XDR_DEBUG=true"
# Interactive modeInteractive=trueTTY=true
# Override entrypoint for debuggingEntrypoint=/bin/bash
# Mount source code for debugging (if available)Volume=/home/%u/src/xdr-agent:/src:ro,Z
# Same mounts as productionVolume=/home/%u/.config/xdr/certs:/etc/xdr/certs:ro,ZVolume=/var/log/journal:/var/log/journal:ro
[Service]Type=simpleRestart=no
[Install]WantedBy=default.target
Performance Optimization
Resource Tuning
Create ~/.config/containers/systemd/xdr-agent.resource
:
[Unit]Description=Resource limits for XDR Agent
[Slice]# CPU allocationCPUWeight=50CPUQuota=200%
# Memory limitsMemoryMax=2GMemoryHigh=1500M
# IO limitsIOWeight=50IOReadBandwidthMax=/var/lib/containers 50MIOWriteBandwidthMax=/var/lib/containers 20M
# Task limitsTasksMax=100
Monitoring Dashboard
Create a monitoring script ~/.local/bin/xdr-monitor.sh
:
#!/bin/bash# Real-time XDR monitoring dashboard
watch -n 5 'echo "=== XDR Agent Monitor ==="echoecho "Service Status:"systemctl --user is-active xdr-agent.serviceechoecho "Container Stats:"podman stats --no-stream xdr-agentechoecho "Recent Logs:"journalctl --user -u xdr-agent.service -n 5 --no-pagerechoecho "Network Connections:"podman exec xdr-agent ss -tunap 2>/dev/null | head -10'
Security Best Practices
1. Rootless Operation
- Always run XDR agents in user sessions when possible
- Use
loginctl enable-linger
for persistent monitoring - Avoid privileged containers unless absolutely necessary
2. Secret Management
# Use Podman secrets for sensitive datapodman secret create xdr-api-key api-key.txtrm api-key.txt
# Rotate secrets regularlypodman secret rm xdr-api-keypodman secret create xdr-api-key new-api-key.txt
3. Network Isolation
# For enhanced security, use custom networks[Container]Network=xdr-networkIP=10.88.0.10
4. Audit Logging
# Enable audit logging for XDR activitiesauditctl -w /home/$USER/.config/xdr/ -p wa -k xdr_config_changeauditctl -w /var/lib/containers/storage/volumes/xdr-data/ -p wa -k xdr_data_access
Integration with XDR Platforms
Wazuh Integration
# Add to config.yaml for Wazuh XDRintegrations: wazuh: enabled: true manager: wazuh.example.com port: 1514 protocol: tcp agent_name: ${HOSTNAME}-podman groups: - linux - containers - xdr
Elastic Security Integration
# Add to config.yaml for Elasticintegrations: elastic: enabled: true hosts: - https://elastic1.example.com:9200 - https://elastic2.example.com:9200 username: xdr_agent api_key: ${ELASTIC_API_KEY} index: xdr-events
Conclusion
Deploying XDR agents as Podman Quadlets in user sessions provides a secure, maintainable, and scalable approach to endpoint security monitoring. This configuration offers:
- Enhanced Security: Rootless containers with minimal privileges
- Operational Excellence: Systemd integration for reliability
- Easy Management: Declarative configuration and automatic updates
- Flexible Deployment: Adaptable to various XDR platforms
By following this guide, organizations can implement enterprise-grade security monitoring while adhering to the principle of least privilege and modern container best practices.