Skip to content

volh/sockretary

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

sockretary

A socket activation proxy written in Rust that starts and stops systemd services on demand.

Why

I have a bunch of home-grown tools and web apps that I vibe-coded for personal use. Most of them sit idle 99% of the time, but still consume RAM if left running. This tool is part of my vibe-slop management system - it keeps services dormant until actually needed, then spins them up on first request and shuts them down after a period of inactivity.

Features

  • Socket Activation: Compatible with systemd socket activation (receives file descriptors)
  • Automatic Service Management: Starts/stops systemd units on demand via D-Bus
  • Health Checking: HTTP health checks with configurable retries and timeouts
  • Metrics Collection: Prometheus-compatible metrics endpoint
  • Multiple Protocols: TCP, UDP, and Unix socket support
  • Inactivity Timeout: Automatically stops services after period of inactivity
  • Graceful Shutdown: Handles SIGTERM/SIGINT with proper cleanup
  • Configuration: YAML-based configuration with CLI overrides

Installation

cargo install sockretary

Or from source:

git clone https://github.com/volh/sockretary
cd sockretary
cargo install --path .

Quick Start

  1. Generate an example configuration:

    sockretary --generate-config > myapp.yaml
  2. Edit the configuration for your service:

    proxy:
      mode: tcp
      backend_address: "127.0.0.1:8080"
      max_connections: 100
    
    service:
      unit: "myapp.service"
      startup_timeout: 30s
    
    timeouts:
      inactivity: 5m
  3. Create systemd units:

    # /etc/systemd/system/myapp-proxy.socket
    [Unit]
    Description=MyApp Proxy Socket
    
    [Socket]
    ListenStream=127.0.0.1:3000
    Accept=no
    
    [Install]
    WantedBy=sockets.target
    # /etc/systemd/system/myapp-proxy.service
    [Unit]
    Description=MyApp Proxy
    Requires=myapp-proxy.socket
    
    [Service]
    Type=simple
    ExecStart=/usr/local/bin/sockretary -c /etc/sockretary/myapp.yaml
    User=myuser
    Group=myuser
    
    [Install]
    WantedBy=multi-user.target
  4. Enable and start:

    sudo systemctl enable myapp-proxy.socket
    sudo systemctl start myapp-proxy.socket

Configuration

Full Configuration Example

proxy:
  mode: tcp                    # tcp, udp, unix
  backend_address: "127.0.0.1:8080"
  max_connections: 100
  buffer_size: 8192

service:
  unit: "myapp.service"
  startup_timeout: 30s
  graceful_shutdown: true

timeouts:
  inactivity: 5m              # Stop service after inactivity
  connection: 30s             # Connection timeout
  read: 30s                   # Read timeout
  write: 30s                  # Write timeout

health_check:
  path: "/health"             # Health check endpoint
  timeout: 5s                 # Per-request timeout
  interval: 10s               # Check interval
  retries: 3                  # Retries before marking unhealthy
  expected_status: 200        # Expected HTTP status

metrics:
  port: 9090                  # Prometheus metrics port
  bind: "127.0.0.1"           # Bind address

logging:
  level: "info"               # trace, debug, info, warn, error
  format: "pretty"            # pretty, json

CLI Options

sockretary [OPTIONS]

OPTIONS:
  -c, --config <FILE>         Configuration file path
  -u, --unit <UNIT>          systemd unit to manage (overrides config)
  -b, --backend <ADDRESS>    Backend address (overrides config)
  -t, --timeout <DURATION>   Inactivity timeout (overrides config)
  -v, --log-level <LEVEL>    Log level [default: info]
      --generate-config      Generate example configuration and exit
  -h, --help                 Print help
  -V, --version              Print version

Architecture

Internet/Network
       ↓
   systemd socket
       ↓
   sockretary  ←--→  systemd (start/stop service via D-Bus)
       ↓
   Backend Service

How It Works

  1. Socket Inheritance: Receives pre-bound socket from systemd via file descriptor (fd 3)
  2. Service Management: Communicates with systemd via D-Bus to start/stop units
  3. Proxy Traffic: Forwards connections between clients and backend service
  4. Activity Monitoring: Tracks connection activity and data transfer
  5. Health Monitoring: Performs periodic HTTP health checks on backend (if configured)
  6. Automatic Shutdown: Stops service after configured inactivity period

Monitoring

Prometheus Metrics

When metrics are enabled, the following metrics are available at /metrics:

  • sockretary_connections_total - Total connections handled
  • sockretary_connections_active - Currently active connections
  • sockretary_connection_duration_seconds - Connection duration histogram
  • sockretary_bytes_total - Total bytes transferred
  • sockretary_service_starts_total - Service start count
  • sockretary_service_stops_total - Service stop count
  • sockretary_service_uptime_seconds - Service uptime
  • sockretary_health_checks_total - Health check count by status
  • sockretary_backend_healthy - Backend health status (1=healthy, 0=unhealthy)
  • sockretary_errors_total - Error count by type

Health Endpoint

Basic health check available at /health on the metrics port.

Troubleshooting

Common Issues

  1. "LISTEN_PID not set": Not running under systemd socket activation

    • Test with: systemd-socket-activate -l 127.0.0.1:3000 sockretary
  2. D-Bus connection failed: Missing systemd or wrong permissions

    • Ensure running on systemd-based system
    • Check user has access to system D-Bus
  3. Backend connection failed: Service not ready or wrong address

    • Check backend service is running
    • Verify backend_address in configuration
    • Enable health checking to wait for readiness
  4. Permission denied on socket: SELinux or file permissions

    • Check SELinux context: ls -Z /path/to/socket
    • Ensure proper user/group in systemd service unit

Testing

Test socket activation manually:

# Terminal 1: Start proxy with systemd-socket-activate
systemd-socket-activate -l 127.0.0.1:3000 sockretary \
  --unit test.service \
  --backend 127.0.0.1:8080 \
  --timeout 30s

# Terminal 2: Test connection
curl http://127.0.0.1:3000/

Security

  1. Run as non-root user with minimal permissions
  2. Use systemd security features:
    [Service]
    DynamicUser=yes
    ProtectSystem=strict
    ProtectHome=yes
    PrivateTmp=yes
    NoNewPrivileges=yes
  3. Bind metrics to localhost only unless needed externally
  4. Use firewall rules to restrict access to proxy ports

License

MIT - see LICENSE file.

Related

About

Socket activation proxy for systemd - starts services on demand, stops on idle

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages