Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/sockudo/sockudo/llms.txt

Use this file to discover all available pages before exploring further.

Overview

Security is critical for production WebSocket infrastructure. This guide covers essential security configurations and best practices for deploying Sockudo safely.

SSL/TLS Configuration

Enable HTTPS/WSS

Always use SSL/TLS in production to encrypt WebSocket traffic and prevent man-in-the-middle attacks.
Environment Variables:
# Enable SSL
SSL_ENABLED=true

# Certificate paths
SSL_CERT_PATH=/etc/ssl/certs/sockudo.crt
SSL_KEY_PATH=/etc/ssl/private/sockudo.key

# Redirect HTTP to HTTPS
SSL_REDIRECT_HTTP=true
SSL_HTTP_PORT=80

# Domain name
DOMAIN=your-domain.com
Configuration File:
{
  "ssl": {
    "enabled": true,
    "cert_path": "/etc/ssl/certs/sockudo.crt",
    "key_path": "/etc/ssl/private/sockudo.key",
    "redirect_http": true
  }
}

Using Let’s Encrypt

# Install Certbot
sudo apt-get install certbot

# Obtain certificate
sudo certbot certonly --standalone -d your-domain.com

# Configure Sockudo
SSL_CERT_PATH=/etc/letsencrypt/live/your-domain.com/fullchain.pem
SSL_KEY_PATH=/etc/letsencrypt/live/your-domain.com/privkey.pem

SSL with Reverse Proxy

Nginx Configuration:
server {
    listen 443 ssl http2;
    server_name your-domain.com;

    ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    location / {
        proxy_pass http://localhost:6001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Origin Validation

Configure Allowed Origins

Origin validation restricts which domains can establish WebSocket connections, providing defense against cross-site attacks. For Default App:
# Comma-separated list of allowed origins
SOCKUDO_DEFAULT_APP_ALLOWED_ORIGINS=https://app.example.com,https://*.staging.example.com,http://localhost:3000
In Config File:
{
  "app_manager": {
    "array": {
      "apps": [
        {
          "id": "production-app",
          "key": "app-key",
          "secret": "app-secret",
          "allowed_origins": [
            "https://app.example.com",
            "https://admin.example.com",
            "https://*.staging.example.com"
          ]
        }
      ]
    }
  }
}

Origin Pattern Matching

Protocol-Agnostic (Recommended):
"allowed_origins": [
  "example.com",              // Matches both HTTP and HTTPS
  "api.example.com",          // Subdomain, both protocols
  "localhost:3000"            // Development, both protocols
]
Protocol-Specific:
"allowed_origins": [
  "https://secure.example.com",  // HTTPS only
  "http://insecure.example.com"  // HTTP only
]
Wildcards:
"allowed_origins": [
  "*.example.com",            // Any subdomain, any protocol
  "https://*.secure.com"      // Any subdomain, HTTPS only
]
Never use "*" (allow all origins) in production. This defeats the purpose of origin validation.

Error Handling

When origin validation fails, clients receive error code 4009:
{
  "event": "pusher:error",
  "data": {
    "code": 4009,
    "message": "Origin not allowed"
  }
}

Rate Limiting

Enable Rate Limiting

# Enable rate limiter
RATE_LIMITER_ENABLED=true

# Backend (memory for single-node, redis for multi-node)
RATE_LIMITER_DRIVER=redis

# API rate limits
RATE_LIMITER_API_MAX_REQUESTS=100
RATE_LIMITER_API_WINDOW_SECONDS=60

# Trust X-Forwarded-For headers (if behind proxy)
RATE_LIMITER_API_TRUST_HOPS=1

# WebSocket rate limits
RATE_LIMITER_WS_MAX_REQUESTS=20
RATE_LIMITER_WS_WINDOW_SECONDS=60
Configuration File:
{
  "rate_limiter": {
    "enabled": true,
    "driver": "redis",
    "api": {
      "max_requests": 100,
      "window_seconds": 60,
      "trust_hops": 1
    },
    "websocket": {
      "max_requests": 20,
      "window_seconds": 60
    }
  }
}

Per-App Rate Limits

{
  "app_manager": {
    "array": {
      "apps": [
        {
          "id": "my-app",
          "max_client_events_per_second": 100,
          "max_backend_events_per_second": 1000
        }
      ]
    }
  }
}

Secret Management

Application Credentials

Never commit secrets to version control. Use environment variables or secret management systems.
Development:
# Use simple credentials for local development
SOCKUDO_DEFAULT_APP_ID=dev-app
SOCKUDO_DEFAULT_APP_KEY=dev-key
SOCKUDO_DEFAULT_APP_SECRET=dev-secret
Production:
# Generate strong secrets
SOCKUDO_DEFAULT_APP_ID=prod-app-$(openssl rand -hex 8)
SOCKUDO_DEFAULT_APP_KEY=$(openssl rand -base64 32)
SOCKUDO_DEFAULT_APP_SECRET=$(openssl rand -base64 64)

Database Credentials

# Generate strong passwords
REDIS_PASSWORD=$(openssl rand -base64 32)
MYSQL_PASSWORD=$(openssl rand -base64 32)
DATABASE_MYSQL_PASSWORD=$MYSQL_PASSWORD

JWT Secrets

# Generate JWT secret
JWT_SECRET=$(openssl rand -base64 32)

Using Secret Management Systems

AWS Secrets Manager:
# Store secret
aws secretsmanager create-secret \
  --name sockudo/prod/app-secret \
  --secret-string "$(openssl rand -base64 64)"

# Retrieve in startup script
export SOCKUDO_DEFAULT_APP_SECRET=$(aws secretsmanager get-secret-value \
  --secret-id sockudo/prod/app-secret \
  --query SecretString \
  --output text)
HashiCorp Vault:
# Store secret
vault kv put secret/sockudo/prod app_secret="$(openssl rand -base64 64)"

# Retrieve in startup script
export SOCKUDO_DEFAULT_APP_SECRET=$(vault kv get -field=app_secret secret/sockudo/prod)

Authentication

Private Channel Authentication

Private channels require HMAC-SHA256 signatures:
# Generate auth signature for testing
echo -n "socket_id:channel_name" | openssl dgst -sha256 -hmac "app_secret" -hex
Server-side Authentication Endpoint:
const crypto = require('crypto');

app.post('/pusher/auth', (req, res) => {
  const socketId = req.body.socket_id;
  const channel = req.body.channel_name;
  
  // Verify user is authorized for this channel
  if (!isAuthorized(req.user, channel)) {
    return res.status(403).json({ error: 'Forbidden' });
  }
  
  const stringToSign = `${socketId}:${channel}`;
  const signature = crypto
    .createHmac('sha256', APP_SECRET)
    .update(stringToSign)
    .digest('hex');
  
  const auth = `${APP_KEY}:${signature}`;
  
  res.json({ auth });
});

Presence Channel Authentication

Presence channels require additional user data:
const userInfo = {
  user_id: req.user.id,
  user_info: {
    name: req.user.name,
    email: req.user.email
  }
};

const stringToSign = `${socketId}:${channel}:${JSON.stringify(userInfo)}`;
const signature = crypto
  .createHmac('sha256', APP_SECRET)
  .update(stringToSign)
  .digest('hex');

const auth = `${APP_KEY}:${signature}`;

res.json({ 
  auth,
  channel_data: JSON.stringify(userInfo)
});

CORS Configuration

# CORS settings
CORS_ORIGINS=https://app.example.com,https://admin.example.com
CORS_METHODS=GET,POST,OPTIONS
CORS_HEADERS=Authorization,Content-Type,X-Requested-With,Accept
CORS_CREDENTIALS=true
Configuration File:
{
  "cors": {
    "credentials": true,
    "origin": [
      "https://app.example.com",
      "https://admin.example.com"
    ],
    "methods": ["GET", "POST", "OPTIONS"],
    "allowed_headers": [
      "Authorization",
      "Content-Type",
      "X-Requested-With",
      "Accept"
    ]
  }
}
Never use "*" for CORS_ORIGINS in production with CORS_CREDENTIALS=true. Browsers will reject requests.

Network Security

Firewall Rules

# Allow WebSocket port
sudo ufw allow 6001/tcp

# Allow metrics port (internal only)
sudo ufw allow from 10.0.0.0/8 to any port 9601

# Deny all other traffic
sudo ufw default deny incoming
sudo ufw default allow outgoing

# Enable firewall
sudo ufw enable

Unix Socket Deployment

For deployments behind reverse proxies, use Unix sockets instead of TCP:
# Enable Unix socket
UNIX_SOCKET_ENABLED=true
UNIX_SOCKET_PATH=/var/run/sockudo/sockudo.sock
UNIX_SOCKET_PERMISSION_MODE=660
Benefits:
  • Not exposed to network
  • Filesystem-based access control
  • Better performance for local communication

Nginx Configuration with Unix Socket:

upstream sockudo {
    server unix:/var/run/sockudo/sockudo.sock;
}

server {
    listen 443 ssl;
    server_name your-domain.com;
    
    location / {
        proxy_pass http://sockudo;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

Resource Limits

Connection Limits

# Per-app connection limits
SOCKUDO_DEFAULT_APP_MAX_CONNECTIONS=10000

# Global limits via systemd
sudo systemctl edit sockudo
Add:
[Service]
LimitNOFILE=65536
LimitNPROC=32768

Payload Limits

# WebSocket payload limit
WEBSOCKET_MAX_PAYLOAD_KB=64

# HTTP API payload limit
HTTP_API_REQUEST_LIMIT_IN_MB=10

# Event payload limit
SOCKUDO_DEFAULT_APP_MAX_EVENT_PAYLOAD_IN_KB=100

Channel Limits

{
  "channel_limits": {
    "max_name_length": 200,
    "cache_ttl": 3600
  },
  "event_limits": {
    "max_channels_at_once": 100,
    "max_name_length": 200,
    "max_payload_in_kb": 100,
    "max_batch_size": 10
  },
  "presence": {
    "max_members_per_channel": 100,
    "max_member_size_in_kb": 2
  }
}

Logging & Monitoring

Structured Logging for Security

# JSON format for SIEM integration
LOG_OUTPUT_FORMAT=json
LOG_COLORS_ENABLED=false
LOG_INCLUDE_TARGET=true
Configuration:
{
  "logging": {
    "colors_enabled": false,
    "include_target": true
  }
}

Security Event Monitoring

Monitor these events in your logs:
  • Failed authentication attempts
  • Origin validation failures (error code 4009)
  • Rate limit violations
  • Unusual connection patterns
  • Memory/CPU anomalies

Metrics to Monitor

# Connection metrics
curl http://localhost:9601/metrics | grep connections

# Error metrics
curl http://localhost:9601/metrics | grep error

# Rate limit metrics
curl http://localhost:9601/metrics | grep rate_limit

Production Deployment Checklist

Security Configuration

  • SSL/TLS enabled with valid certificates
  • Origin validation configured with specific domains
  • Rate limiting enabled with appropriate limits
  • Strong app credentials generated and stored securely
  • CORS configured with specific origins (no wildcards)
  • Firewall rules configured
  • Resource limits set
  • Structured logging enabled (JSON format)

Authentication & Authorization

  • Private channel authentication implemented
  • Presence channel authentication implemented
  • Auth endpoint validates user permissions
  • Secrets stored in secret management system
  • JWT secrets generated securely

Network Security

  • WebSocket port firewalled (allow only from load balancer)
  • Metrics port restricted to internal network
  • Reverse proxy configured with SSL
  • Unix sockets used if behind proxy
  • HTTP to HTTPS redirect enabled

Monitoring

  • Prometheus metrics enabled
  • Security events logged
  • Log aggregation configured
  • Alerting set up for security events
  • Regular security audits scheduled

Security Best Practices Summary

  1. Always use SSL/TLS in production
  2. Enable origin validation with specific domains
  3. Enable rate limiting to prevent abuse
  4. Use strong secrets generated with cryptographic tools
  5. Never commit secrets to version control
  6. Implement proper authentication for private/presence channels
  7. Configure CORS with specific origins
  8. Use firewall rules to restrict access
  9. Set resource limits to prevent DoS
  10. Enable structured logging for security monitoring
  11. Monitor security metrics continuously
  12. Keep Sockudo updated with security patches

Next Steps