7.6 KiB
Docker Socket Permissions and Security
This document covers the security considerations and configuration options for Docker socket access in Zastava Agent deployments.
Overview
The Zastava Agent requires read access to the Docker socket (/var/run/docker.sock) to:
- Monitor container lifecycle events - Start, stop, pause, die, etc.
- Inspect running containers - Image digest, labels, environment variables
- Collect runtime evidence - Loaded libraries, process information
Default Configuration
By default, the agent runs as:
- User:
zastava-agent(system user) - Group:
docker(grants socket access) - Socket:
/var/run/docker.sock
# systemd service configuration
User=zastava-agent
Group=docker
ReadWritePaths=/var/run/docker.sock
Security Considerations
Docker Socket Exposure Risks
The Docker socket provides significant privileges:
| Capability | Risk Level | Mitigation |
|---|---|---|
| List containers | Low | Required for operation |
| Inspect containers | Low | Required for operation |
| Read container logs | Medium | Agent does not use this |
| Create containers | High | Agent does not use this |
| Execute in containers | Critical | Agent does not use this |
| Pull images | High | Agent does not use this |
| Remove containers | High | Agent does not use this |
Agent Behavior
The Zastava Agent performs read-only operations:
// Operations used by agent
docker.ContainerList(...) // List running containers
docker.ContainerInspect(...) // Get container details
docker.Events(...) // Subscribe to lifecycle events
The agent does not perform write operations such as creating, starting, stopping, or removing containers.
Alternative Configurations
Option 1: Docker API Proxy (Recommended for High-Security)
Deploy a Docker API proxy that restricts available operations:
# docker-proxy configuration example
allowed_endpoints:
- "GET /containers/json" # List containers
- "GET /containers/*/json" # Inspect container
- "GET /events" # Subscribe to events
- "GET /_ping" # Health check
Example proxy: Tecnativa/docker-socket-proxy
# Deploy proxy
docker run -d \
--name docker-proxy \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-e CONTAINERS=1 \
-e EVENTS=1 \
-p 2375:2375 \
tecnativa/docker-socket-proxy
Configure agent to use proxy:
ZASTAVA_AGENT__DockerEndpoint=tcp://localhost:2375
Option 2: Unix Socket with ACLs
Use filesystem ACLs for fine-grained access:
# Install ACL support
sudo apt-get install acl
# Set ACL for zastava-agent user
sudo setfacl -m u:zastava-agent:rw /var/run/docker.sock
# Verify ACL
getfacl /var/run/docker.sock
This allows removing the user from the docker group while maintaining socket access.
Option 3: SELinux/AppArmor Policies
SELinux Policy
# zastava-agent.te
module zastava_agent 1.0;
require {
type docker_var_run_t;
type zastava_agent_t;
class sock_file { read write };
}
# Allow read/write to Docker socket
allow zastava_agent_t docker_var_run_t:sock_file { read write getattr };
AppArmor Profile
# /etc/apparmor.d/zastava-agent
profile zastava-agent /opt/stellaops/zastava-agent/StellaOps.Zastava.Agent {
# Docker socket access
/var/run/docker.sock rw,
# Deny network access except to scanner backend
network inet stream,
network inet6 stream,
# Read-only system access
/etc/stellaops/* r,
/opt/stellaops/zastava-agent/** mr,
# Data directory
/var/lib/zastava-agent/** rw,
}
Option 4: Rootless Docker
For maximum isolation, use rootless Docker:
# Install rootless Docker
dockerd-rootless-setuptool.sh install
# Configure agent to use rootless socket
export ZASTAVA_AGENT__DockerEndpoint=unix:///run/user/1000/docker.sock
Note: Rootless Docker has some limitations with networking and storage drivers.
Log Paths
Agent Logs
| Component | Log Location |
|---|---|
| Agent stdout/stderr | journalctl -u zastava-agent |
| Runtime events | /var/lib/zastava-agent/runtime-events/*.ndjson |
| Health check | Agent stdout (structured JSON) |
Log Configuration
# Set log level
Serilog__MinimumLevel__Default=Information
# Available levels: Verbose, Debug, Information, Warning, Error, Fatal
Log Rotation
Event buffer files are automatically rotated:
# Default settings
event_buffer:
max_file_size_mb: 10
max_total_size_mb: 100
retention_hours: 24
Health Check Configuration
The agent exposes HTTP health endpoints:
| Endpoint | Port | Description |
|---|---|---|
/healthz |
8080 | Liveness probe |
/readyz |
8080 | Readiness probe |
/livez |
8080 | Alias for liveness |
Health Check Port
Configure via environment variable:
ZASTAVA_AGENT__HealthCheck__Port=8080
Health Check Behavior
Liveness (/healthz):
- Returns 200 if agent process is running
- Returns 503 if critical subsystems failed
Readiness (/readyz):
- Returns 200 if agent can process events
- Returns 503 if:
- Docker socket is unreachable
- Event buffer is not writable
- Backend connection failed
Prometheus Metrics
Health metrics are exposed at /metrics:
# HELP zastava_agent_docker_connected Docker connectivity status
# TYPE zastava_agent_docker_connected gauge
zastava_agent_docker_connected 1
# HELP zastava_agent_buffer_writable Event buffer writability
# TYPE zastava_agent_buffer_writable gauge
zastava_agent_buffer_writable 1
# HELP zastava_agent_events_buffered Number of events in buffer
# TYPE zastava_agent_events_buffered gauge
zastava_agent_events_buffered 42
Monitoring Recommendations
Alerting Rules
groups:
- name: zastava-agent
rules:
- alert: ZastavaAgentDown
expr: up{job="zastava-agent"} == 0
for: 5m
annotations:
summary: "Zastava Agent is down on {{ $labels.instance }}"
- alert: ZastavaDockerDisconnected
expr: zastava_agent_docker_connected == 0
for: 1m
annotations:
summary: "Zastava Agent lost Docker connectivity"
- alert: ZastavaBufferNotWritable
expr: zastava_agent_buffer_writable == 0
for: 1m
severity: critical
annotations:
summary: "Zastava event buffer is not writable"
Grafana Dashboard
Import the Zastava monitoring dashboard from:
docs/modules/zastava/operations/dashboards/zastava-observability.json
Troubleshooting
Cannot Access Docker Socket
# Check socket exists
ls -la /var/run/docker.sock
# Check agent user groups
id zastava-agent
# Check Docker daemon is running
systemctl status docker
# Test socket access manually
sudo -u zastava-agent docker ps
Permission Denied Errors
# Add user to docker group (if not using ACLs)
sudo usermod -aG docker zastava-agent
# Restart agent
sudo systemctl restart zastava-agent
Events Not Being Received
# Check Docker events stream
docker events --since 1m
# Verify agent can see events
journalctl -u zastava-agent | grep -i "event"
# Check event buffer
ls -la /var/lib/zastava-agent/runtime-events/