Sign inSign up

oorabona/sslh

By oorabona

•Updated 1 day ago

sslh container

Image
0

50K+

oorabona/sslh repository overview

⁠SSLH — Protocol Multiplexer in a 2 MB Container

Docker Pulls Docker Image Size GHCR GitHub Stars

Run SSH, HTTPS, OpenVPN, and XMPP on the same port. SSLH detects the protocol at connection time and forwards it to the right backend — a lifesaver on networks where only port 443 is open.

⁠Why this image

  • ~2 MB — FROM scratch, no OS, no shell, no package manager
  • Static binaries — zero shared library CVEs to track
  • Multi-arch — amd64 / arm64 / arm/v7
  • 3 flavors — sslh-ev (default, libev), sslh-select, sslh-fork
  • Auto-updated — CI tracks yrutschle/sslh⁠ releases
  • SBOM + attestation — every image ships with a Sigstore-signed SPDX

⁠Verify this image

Every build ships a Sigstore-signed SBOM and a full Trivy scan — verify them yourself, no login required:

gh attestation verify oci://ghcr.io/oorabona/sslh:latest --owner oorabona

Full walkthrough (SBOM payload, Trivy findings, multi-arch manifest inspection, upstream dependency tracking) → https://oorabona.github.io/docker-containers/verify-images/⁠

⁠Platforms

  • amd64 - x86_64 systems
  • arm64 - ARM 64-bit systems
  • arm/v7 - ARM 32-bit systems

⁠Features

  • FROM scratch - Absolute minimal attack surface (no OS, no shell)
  • Static binaries - Self-contained, no runtime dependencies
  • Multiple flavors - sslh-fork, sslh-select, sslh-ev included
  • Non-root execution - Runs as nobody user (uid 65534)
  • Stripped binaries - Minimal size (~2-3MB total image)

Available SSLH flavors (v2.0+):

  • sslh-fork - Original SSLH project
  • sslh-select - Uses select instead of epoll
  • sslh-ev - Uses libev (default, best performance)

⁠How to run it?

IMPORTANT: This is a FROM scratch image with no shell. Environment variables are NOT supported for configuration. You must provide full command line arguments.

⁠Basic Usage
# Check version
docker run --rm oorabona/sslh

# Run with full command line
docker run -d \
  --name sslh \
  -p 443:443 \
  oorabona/sslh \
  -f \
  -p 0.0.0.0:443 \
  --ssh ssh.example.com:22 \
  --tls backend.example.com:8443 \
  --openvpn vpn.example.com:1194

Key arguments:

  • -f - Required: Keep process in foreground (Docker expects this)
  • -p <ip>:<port> - Listen address and port
  • --ssh <host>:<port> - SSH backend
  • --tls <host>:<port> - TLS/HTTPS backend
  • --openvpn <host>:<port> - OpenVPN backend
⁠Using Different Flavors

By default, sslh-ev is used. To use a different flavor, override the entrypoint:

# Use sslh-fork
docker run -d --entrypoint /usr/local/bin/sslh-fork oorabona/sslh -f -p 0.0.0.0:443 ...

# Use sslh-select
docker run -d --entrypoint /usr/local/bin/sslh-select oorabona/sslh -f -p 0.0.0.0:443 ...
⁠Using docker-compose
services:
  sslh:
    image: oorabona/sslh
    ports:
      - "443:443"
    command:
      - -f
      - -p
      - "0.0.0.0:443"
      - --ssh
      - "192.168.1.2:22"
      - --tls
      - "192.168.2.1:8443"
      - --openvpn
      - "192.168.2.1:1194"
    restart: unless-stopped
⁠Using a configuration file

For complex configurations, use a config file:

docker run -d \
  --name sslh \
  -p 443:443 \
  -v /path/to/sslh.cfg:/etc/sslh.cfg:ro \
  oorabona/sslh -f -F /etc/sslh.cfg

⁠Security

⁠Base Security
  • FROM scratch: No operating system, no shell, no package manager
  • Static linking: No shared library vulnerabilities
  • Minimal attack surface: Only sslh binary and CA certificates
  • Non-root: Runs as nobody user (uid 65534)
# Maximum security runtime configuration
docker run -d \
  --name sslh \
  --read-only \
  --cap-drop ALL \
  --cap-add NET_BIND_SERVICE \
  --security-opt no-new-privileges:true \
  -p 443:443 \
  oorabona/sslh -f -p 0.0.0.0:443 --ssh backend:22 --tls backend:8443
⁠Docker Compose Security Template
services:
  sslh:
    image: ghcr.io/oorabona/sslh:latest
    read_only: true
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE
    security_opt:
      - no-new-privileges:true
    ports:
      - "443:443"
    command:
      - -f
      - -p
      - "0.0.0.0:443"
      - --ssh
      - "backend:22"
      - --tls
      - "backend:8443"
    restart: unless-stopped

⁠SSLH Configuration Examples

⁠Configuration file format
foreground: true;
listen:
(
  { host: "0.0.0.0"; port: "443"; }
);

protocols:
(
  { name: "ssh"; service: "ssh"; host: "localhost"; port: "22"; fork: true; },
  { name: "openvpn"; host: "localhost"; port: "1194"; },
  { name: "xmpp"; host: "localhost"; port: "5222"; },
  { name: "http"; host: "localhost"; port: "80"; },
  { name: "tls"; host: "localhost"; port: "443"; log_level: 0; },
  { name: "anyprot"; host: "localhost"; port: "443"; }
);
⁠Notes
  • UDP: Use config file (not command line). sslh-fork doesn't support UDP.
  • Transparent proxy: Requires host network configuration. See SSLH documentation⁠.

For more examples, see the SSLH project⁠.

⁠Building

./make build sslh
⁠Build Arguments
  • VERSION - Version tag for sslh release (e.g., v2.0.0). Defaults to latest
  • UPSTREAM_VERSION - Upstream version override for downloads. If provided, takes precedence over VERSION
  • OS_IMAGE_BASE - Base image name (default: alpine)
  • OS_IMAGE_TAG - Base image tag (default: latest)
  • NPROC - Number of parallel jobs for make compilation (default: 1)

Example with custom arguments:

./make build sslh v2.0.0

⁠Licence

MIT

Tag summary

Content type

Image

Digest

sha256:29a2f4af4…

Size

2.4 MB

Last updated

1 day ago

docker pull oorabona/sslh