Sign inSign up

mseyv/ocserv

By mseyv

•Updated 4 months ago

Docker-ready OpenConnect SSL VPN (ocserv) with AnyConnect support, camouflage, and routing.

Image
Networking
Security
0

75

mseyv/ocserv repository overview

⁠Cisco AnyConnect Compatibility VPN Server (ocserv)

A production-ready, high-performance OpenConnect SSL VPN server (ocserv) packaged inside a lightweight Docker container. It supports Cisco AnyConnect and OpenConnect clients, featuring advanced routing, camouflage secrets, per-user/per-group configurations, and persistent authentication.

⁠Features

  • Cisco AnyConnect / OpenConnect Compatible: Seamless integration with official AnyConnect and open-source OpenConnect clients.
  • Camouflage Mode: Adds an extra layer of stealth by hiding the VPN endpoint behind a secret URL parameter.
  • Granular Access Control: Comprehensive support for per-user and per-group configuration profiles (routing, DNS split-tunneling, rate limiting).
  • Robust Networking: Fully isolated execution with built-in health checks and custom resource allocations.
  • Production Security: Configured to drop worker privileges (nobody/nogroup) for active client connections.

⁠Quick Start

⁠1. Project Directory Structure

Before launching the container, ensure you have the following directory structure in your project folder to persist data:

.
├── docker-compose.yml
└── data/
    ├── certs/
    ├── config-per-user/
    ├── config-per-group/
    ├── defaults/
    └── ocpasswd
⁠2. Deploying with Docker Compose

Save the following configuration into your docker-compose.yml file, configure your environment variables, and spin up the service:

services:
  ocserv:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: ocserv
    restart: unless-stopped

    # Privileged is required for:
    #   - TUN device (/dev/net/tun)
    #   - iptables/nftables for routing & firewall rules
    #   - Network namespace manipulation
    privileged: true

    ports:
      - "443:443/tcp"
      - "443:443/udp"

    environment:
      # --- VPN domain (used for cert generation) ---
      - OCSERV_DOMAIN=vpn.domain.example
      # --- Camouflage secret (clients use https://host/?SECRET) ---
      - OCSERV_CAMOUFLAGE_SECRET=${OCSERV_CAMOUFLAGE_SECRET:-changeme123}
      # --- Internal VPN subnet ---
      - OCSERV_IPV4_NETWORK=10.8.0.0
      - OCSERV_IPV4_NETMASK=255.255.255.0
      # --- DNS pushed to clients ---
      - OCSERV_DNS=1.1.1.1
      # --- Max concurrent clients ---
      - OCSERV_MAX_CLIENTS=64
      # --- Worker privilege drop ---
      - OCSERV_WORKER_USER=nobody
      - OCSERV_WORKER_GROUP=nogroup

    volumes:
      # --- Persistent TLS certificates (mount your own or auto-gen) ---
      - ./data/certs:/etc/ocserv/certs

      # --- Password file (ocpasswd format) ---
      - ./data/ocpasswd:/etc/ocserv/ocpasswd

      # --- Per-user configuration files ---
      - ./data/config-per-user:/etc/ocserv/config-per-user

      # --- Per-group configuration files ---
      - ./data/config-per-group:/etc/ocserv/config-per-group

      # --- Default configs (fallback when no user/group match) ---
      - ./data/defaults:/etc/ocserv/defaults

    healthcheck:
      test: ["CMD-SHELL", "nc -z localhost 443 || exit 1"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 10s

    deploy:
      resources:
        limits:
          memory: 512M
        reservations:
          memory: 128M

Run the container:

docker-compose up -d

⁠Critical Configuration: SSL/TLS Certificates

The image automatically handles initial template management. However, for a production environment or when shifting domains, you must explicitly configure the Server Template (server.tmpl).

⚠️ Important Step after First Run:

  1. Locate the auto-generated server.tmpl inside your mounted ./data/certs/ directory.
  2. Open the file and update the cn (Common Name) and dns_name fields to match your real VPN domain name (e.g., vpn.domain.example).
  3. Save the file and regenerate/re-sign your certificates using your CA or internal script.
  4. Restart the container (docker-compose restart) to apply the changes. Failure to do this will cause TLS handshake errors on AnyConnect clients.

⁠Configuration Reference

⁠Environment Variables
VariableDefaultDescription
OCSERV_DOMAINvpn.domain.exampleThe primary public domain name for your VPN gateway.
OCSERV_CAMOUFLAGE_SECRETchangeme123URL secret token required by clients to initiate connection.
OCSERV_IPV4_NETWORK10.8.0.0The internal virtual subnet pool assigned to VPN clients.
OCSERV_IPV4_NETMASK255.255.255.0Subnet mask for the client IP address pool.
OCSERV_DNS1.1.1.1Upstream DNS server pushed to connected clients.
OCSERV_MAX_CLIENTS64Maximum number of concurrent active client sessions.
⁠Volumes & Persistence
  • ./data/certs ➔ /etc/ocserv/certs: Stores your server certificates, private keys, and server.tmpl.
  • ./data/ocpasswd ➔ /etc/ocserv/ocpasswd: Plaintext-based user database (manage via ocpasswd utility).
  • ./data/config-per-user ➔ /etc/ocserv/config-per-user: Advanced overrides matching precise usernames (e.g., specific static IPs, targeted route or no-route keys).

⁠Technical Considerations

  • Privileged Mode: The container explicitly requires privileged: true in order to dynamically provision the virtual TUN network adapter (/dev/net/tun), manipulate inner network namespaces, and manage localized kernel firewall tables (iptables/nftables).
  • Health Assessment: Includes an embedded TCP loopback tester running every 30 seconds to maintain container high availability.

Tag summary

Content type

Image

Digest

sha256:faa069685…

Size

10.6 MB

Last updated

4 months ago

docker pull mseyv/ocserv:1.4.2