This project provides a highly optimized, fully containerized deployment of the OpenConnect VPN Server (ocserv). Built using a modern Docker multi-stage architecture, it completely isolates the VPN environment from the host system while ensuring you always run the latest official version with strict security standards.
- Extreme Lightness & Security: Uses a pinned
alpine:3.22base and compilesocserv 1.5.0(or newer) directly from official sources. The final image size is drastically minimized by stripping build dependencies. - Smart Certificate Management:
- Provisions and automatically renews Let's Encrypt certificates if a domain is provided (via bundled
acme.sh). Renewal runs daily via an in-container cron job; ocserv picks up the renewed cert files automatically. - Gracefully falls back to generating secure Self-Signed Certificates if no domain is used.
- Provisions and automatically renews Let's Encrypt certificates if a domain is provided (via bundled
- Robust Mobile & Network Compatibility:
- Full support for Cisco AnyConnect and OpenConnect clients.
- Uses GnuTLS NORMAL TLS Priorities with
%COMPATenabled for broad compatibility with Cisco AnyConnect and OpenConnect clients. - Uses a conservative fixed MTU (1280) and tuned Dead Peer Detection (DPD) to prevent UDP fragmentation and packet loss on mobile/cellular networks.
- Uses a conflict-free default subnet (
192.168.211.0/24) to avoid routing issues with home/corporate WiFi networks.
- Uses a conflict-free default subnet (
- Secure Architecture: Drops privileged mode. Requires only
NET_ADMINcapability and safely handlesiptablesNAT forwarding internally.
- Docker & Docker Compose installed on your server.
- TCP/UDP port
443open in your firewall. - (Optional) TCP port
80open if you plan to use Let's Encrypt auto-certificates.
git clone https://github.com/Arthur-WWW/ocserv-docker-setup.git
cd ocserv-docker-setupIf you have a domain name pointing to your server's IP and wish to use valid Let's Encrypt certificates:
- Open
docker-compose.yml. - Uncomment the
DOMAINandACME_EMAILenvironment variables and set them to your domain (e.g.,DOMAIN=vpn.example.com) and your email (e.g.,ACME_EMAIL=admin@example.com). - Uncomment the
80:80/tcpport mapping. Port 80 must be free on the host and reachable from the public internet, because acme.sh uses it for the ACME http-01 challenge in standalone mode.
If you skip this step, the server will automatically generate self-signed certificates on its first run.
For self-signed certificates, SAN values are optional. Leave them commented to keep the default CN-only certificate behavior; set them before the first run only if your client requires SANs:
# - SRV_DNS=vpn.example.com
# If you connect by VPS IP instead of DNS, set this to the VPS public IP.
# - SRV_IP=203.0.113.10Start the service in the background. The initial run will download the official ocserv source code and compile it locally.
docker-compose up -d --buildA convenient helper script manage-user.sh is provided to manage VPN credentials without needing to manually enter the container.
# Add a new VPN user (will prompt for a password)
./manage-user.sh add my_username
# List all current users
./manage-user.sh list
# Delete a VPN user
./manage-user.sh delete my_username
# Temporarily lock/unlock a user
./manage-user.sh lock my_username
./manage-user.sh unlock my_usernameDownload the official client for your platform:
- Windows / macOS / Linux: Cisco AnyConnect Secure Mobility Client or OpenConnect GUI
- iOS / Android: Search for
Cisco Secure ClientorAnyConnectin the App Store / Google Play.
- Open the client and add a new connection.
- Enter your Server IP address or Domain Name.
- If using self-signed certificates (no domain configured), you will receive an "Untrusted Server" warning. Accept/Continue anyway.
- Enter the username and password you created via the
manage-user.shscript. - You are now securely connected to the VPN! (Default is Full Tunnel: all traffic routes through the server).
All core configurations are exposed via the config/ directory after the first run.
config/ocserv.conf: The main VPN settings (Subnets, DNS, Routing, TLS configs). The service requires a restart (docker-compose restart) to apply changes.certs/: The directory where your certificates are stored. You can drop your own validserver-cert.pemandserver-key.pemhere manually if you prefer not to use the bundledacme.shlogic.
The default VPN client subnet is 192.168.211.0/24 in config/ocserv.conf. entrypoint.sh derives NAT from that CIDR automatically. If you need to override it without editing the config, set VPN_IPV4_CIDR in docker-compose.yml, and keep it matched to ipv4-network.
The default setup is IPv4 full tunnel. VPN_IPV6_MODE=off avoids creating partial IPv6 NAT rules. If your VPS and clients have public IPv6, either disable IPv6 on the clients to avoid IPv6 traffic bypassing the VPN, or enable full IPv6 tunneling:
- Uncomment the IPv6 block in
config/ocserv.conf. - Set
VPN_IPV6_MODE=natindocker-compose.yml. - Keep
VPN_IPV6_CIDRmatched to theipv6-networkvalue.