README
ยถ
ocserv-agent
ocserv-agent - A lightweight Go agent for remote management of OpenConnect VPN servers (ocserv) via gRPC with mTLS authentication.
Status: BETA (v0.6.0) - Production-tested deployment with zero downtime! Integration tests complete (119 tests), 75-80% coverage achieved, all phases done.
Latest Release: v0.6.0 BETA (October 2025) - All integration tests complete (100%), production deployment validated โ
๐ Overview
ocserv-agent is a production-tested BETA agent that runs on each ocserv instance and provides secure remote management capabilities through a gRPC API. It enables centralized control of distributed VPN infrastructure.
Current Release: v0.6.0 BETA (October 2025)
- โ Integration tests complete: 119 tests (82 occtl + 11 systemctl + 26 gRPC)
- โ Test coverage: 75-80% overall (exceeded target!), ~90% for occtl.go
- โ Production deployment: Zero-downtime deployment to OracleLinux 9.6 server
- โ Mock ocserv server: 900+ lines, 14 production fixtures
- โ Ansible automation: Automated deployment with backup/rollback
- โ All 5 phases complete: Infrastructure, Occtl, Systemctl, gRPC, Production
Previous Release: v0.5.0 BETA (October 2025)
- โ CRITICAL security fixes: Fixed 4 command injection vulnerabilities
- โ Test coverage expansion: internal/grpc 0% โ 87.6%, overall 40% โ 51.2%
- โ Security-first testing: validateArguments 100% coverage
Architecture
Control Server (ocserv-web-panel)
โ gRPC + mTLS
Agent (this project)
โ exec/shell
ocserv daemon
Key Features
- ๐ Secure Communication: mTLS authentication, TLS 1.3 minimum, client certificate verification
- ๐ ocserv Control: Execute occtl/systemctl commands remotely (13/16 working, 3 upstream bugs)
- โ๏ธ Configuration Management: Read ocserv configs (main, per-user, per-group)
- ๐ Security Hardening: Command whitelist, input validation, command injection protection
- ๐ Comprehensive Docs: 800+ lines of documentation, ROADMAP, release notes
- ๐๏ธ Production Ready: Certificate auto-generation, systemd service, multi-platform builds
- ๐ณ Container-First: Podman Compose based development and testing
- ๐ค Open Source: MIT license, OSSF security best practices, upstream contributions
- โ Test Coverage: 97.1% config, 77.6% cert, 82-100% ocserv/config (2,225 lines of tests)
- โ๏ธ DevOps: Automatic formatting, git hooks, CI optimizations
What's Working (v0.5.0)
โ Core Features:
- gRPC server with mTLS authentication
- ExecuteCommand RPC (occtl/systemctl commands)
- HealthCheck RPC (Tier 1 - heartbeat)
- Config file reading (main, per-user, per-group)
- Command validation and security
- Certificate auto-generation (bootstrap mode)
โ occtl Commands (13/16):
show users,show user [NAME],show id [ID]show status,show statsshow ip bans,show ip ban points,unban ip [IP]disconnect user [NAME],disconnect id [ID]reload
โ ๏ธ Known Issues (3/16 - upstream ocserv bugs):
show iroutes- invalid JSON (we contributed fix upstream)show sessions all/valid- trailing commas (we reported regression)
๐ Quick Start
TLS Certificate Setup
ocserv-agent requires TLS certificates for secure communication. You have two options:
๐ Bootstrap Mode (Recommended for Testing)
Enable auto-generation in config:
tls:
enabled: true
auto_generate: true # Auto-generate self-signed certs
On first run, agent will generate:
- Self-signed CA certificate
- Agent certificate signed by CA
- Private key
๐ญ Production Mode (Recommended for Production)
Generate certificates manually or disable auto-generation:
# Option A: Generate with CLI command
sudo ocserv-agent gencert -output /etc/ocserv-agent/certs
# Option B: Use your own CA-signed certificates
# Place your certs in /etc/ocserv-agent/certs/
# - agent.crt (agent certificate)
# - agent.key (private key)
# - ca.crt (CA certificate)
Set config:
tls:
enabled: true
auto_generate: false # Use existing certificates
cert_file: "/etc/ocserv-agent/certs/agent.crt"
key_file: "/etc/ocserv-agent/certs/agent.key"
ca_file: "/etc/ocserv-agent/certs/ca.crt"
๐ See docs/CERTIFICATES.md for detailed certificate management guide.
๐ Quick Start
Prerequisites
- Go 1.25+
- Podman and podman-compose
- protobuf-compiler (for proto generation)
Installation & First Run
Option 1: Quick Start (Development)
# Clone repository
git clone https://github.com/dantte-lp/ocserv-agent.git
cd ocserv-agent
# Build binary
make build
# Create config with TLS auto-generation
cat > config.yaml <<EOF
agent_id: "server-01"
control_server:
address: "localhost:9090"
tls:
enabled: true
auto_generate: true # Auto-generate self-signed certs on first run
cert_file: "/etc/ocserv-agent/certs/agent.crt"
key_file: "/etc/ocserv-agent/certs/agent.key"
ca_file: "/etc/ocserv-agent/certs/ca.crt"
ocserv:
config_path: "/etc/ocserv/ocserv.conf"
ctl_socket: "/var/run/occtl.socket"
systemd_service: "ocserv"
backup_dir: "/var/backups/ocserv-agent"
logging:
level: "info"
format: "json"
security:
allowed_commands: ["occtl", "systemctl"]
max_command_timeout: 300s
EOF
# Run agent (certificates will be auto-generated)
sudo ./bin/ocserv-agent --config config.yaml
Option 2: Production Deployment with Ansible
See deploy/ansible/README.md for automated deployment.
Option 3: Container Development
# Start development server with hot reload
make compose-dev
Running Tests
๐ Full Build Pipeline (Recommended)
# Run everything: security + tests + multi-platform build
make build-all
# Or run specific stages:
make build-all-security # Security scans only
make build-all-test # Tests only
make build-all-build # Multi-platform build only
This runs the complete CI/CD pipeline locally:
- Security scans (gosec, govulncheck, trivy)
- Unit tests with coverage
- Linting (golangci-lint)
- Multi-platform builds (Linux/FreeBSD, amd64/arm64)
๐ Quick Local Check (Before Commit)
# Fast checks in 2-3 seconds (auto-formats code!)
./scripts/quick-check.sh
Features:
- โ
Auto-formats Go code with
gofmt -s -w - โ
Runs
go vetfor common mistakes - โ Builds the project
- โ Runs all unit tests
๐ช Git Hooks (Automatic Formatting)
Install git hooks to automatically format code before commits:
# One-time setup
./scripts/install-hooks.sh
Installed hooks:
- pre-commit: Auto-formats Go code with
gofmtbefore each commit - pre-push: Runs
quick-check.shbefore each push
Skip hooks temporarily:
git commit --no-verify # Skip pre-commit hook
git push --no-verify # Skip pre-push hook
๐ฌ Full Local CI (Before Push)
# Run all CI checks locally (saves GitHub Actions minutes!)
./scripts/test-local.sh
See LOCAL_TESTING.md for details.
๐ณ Container Tests
# Run all tests in containers
make compose-test
# View logs
make compose-logs
Building
# Build multi-arch binaries
make compose-build
# Binaries will be in bin/:
# - bin/ocserv-agent-linux-amd64
# - bin/ocserv-agent-linux-arm64
๐ Documentation
User Guides
- Release Notes v0.5.0 - Latest release: Test coverage & security fixes
- Project Roadmap - Development roadmap and timeline
- occtl Commands Reference - Complete command guide with examples
- gRPC Testing Guide - Test API with grpcurl
- Certificate Management - TLS/mTLS setup (bootstrap + production)
- Configuration Guide - All configuration options
Developer Guides
- Local Testing Guide - Development and CI testing
- GitHub Actions Workflows - CI/CD pipeline
- Contributing Guide - Development workflow
- TODO Management - Current tasks and progress (tactical)
Security
- Security Policy - Vulnerability disclosure process
- OSSF Scorecard Improvements - Security roadmap (4.9 โ 7.5+/10)
- ocserv Compatibility - Feature coverage analysis
Releases
- v0.5.0 Release Notes - Test coverage expansion & security fixes (Oct 2025) โ
- v0.4.0 Release Notes - Test foundation & DevOps (Oct 2025)
- v0.3.1 Release Notes - Critical bugfixes + documentation (Oct 2025)
- All Releases - Full release history
- v0.3.0 Release Notes - Certificate auto-generation (Oct 2025)
๐ง Configuration
Configuration is done via YAML file:
# /etc/ocserv-agent/config.yaml
agent_id: "server-01"
control_server:
address: "control.example.com:9090"
tls:
enabled: true
cert_file: "/etc/ocserv-agent/certs/agent.crt"
key_file: "/etc/ocserv-agent/certs/agent.key"
ca_file: "/etc/ocserv-agent/certs/ca.crt"
ocserv:
config_path: "/etc/ocserv/ocserv.conf"
systemd_service: "ocserv"
See config.yaml.example for all options.
๐ ๏ธ Development Workflow
This project uses Podman Compose for all development and testing:
# Start development (hot reload)
make compose-dev
# Run tests
make compose-test
# Build binaries
make compose-build
# Stop all services
make compose-down
Important: Do NOT use go build or go test directly on the host. Always use Podman Compose targets for consistency and reproducibility.
๐๏ธ Project Structure
ocserv-agent/
โโโ cmd/
โ โโโ agent/ # Main entrypoint
โโโ internal/
โ โโโ config/ # Configuration loading
โ โโโ grpc/ # gRPC server
โ โโโ ocserv/ # ocserv management
โ โโโ health/ # Health checks
โ โโโ metrics/ # Metrics collection
โ โโโ telemetry/ # OpenTelemetry
โโโ pkg/
โ โโโ proto/ # Protocol Buffers
โโโ deploy/
โ โโโ compose/ # Podman Compose files
โ โโโ systemd/ # systemd service
โ โโโ scripts/ # Deployment scripts
โโโ docs/
โ โโโ todo/ # Task management
โ โโโ releases/ # Release notes
โโโ test/
โโโ mock-server/ # Mock control server
โโโ mock-ocserv/ # Mock ocserv
๐ Security
- mTLS: Client certificate authentication required (TLS 1.3 minimum)
- Command Whitelist: Only approved commands (occtl, systemctl)
- Input Validation: Protection against command injection, shell metacharacters, path traversal
- Audit Logging: All commands logged with context (user, timestamp, result)
- Capability-Based: Runs with minimal privileges (CAP_NET_ADMIN only)
- Security Scanning: gosec, govulncheck, trivy, CodeQL
- OSSF Scorecard: 5.9/10 (improving to 7.5+/10)
- Vulnerability Disclosure: SECURITY.md with 48h response time
Recent Security Improvements (v0.3.1 - v0.5.0)
- โ v0.5.0: CRITICAL command injection fixes (backtick, escaped chars, newlines, control chars)
- โ v0.5.0: Security validation 100% coverage (29 injection test cases)
- โ SECURITY.md vulnerability disclosure policy created
- โ Removed hardcoded credentials from repository
- โ Sanitized all deployment scripts
- โ OSSF Scorecard improved from 4.9/10 to 5.9/10
- โ Branch protection with required PR reviews (v0.4.0)
- โ Admin bypass for emergency hotfixes (v0.4.0)
- ๐ Roadmap to 7.5+/10 in v0.6.0 (GPG signing, dependency pinning, token permissions)
๐ Monitoring
Health Checks (3-Tier)
- Tier 1 - Heartbeat (every 10-15s): Basic status, CPU, RAM, active sessions
- Tier 2 - Deep Check (every 1-2m): Process status, port listening, config validation
- Tier 3 - Application Check (on-demand): End-to-end VPN connection test
Metrics
- System metrics (CPU, memory, load)
- ocserv metrics (sessions, bandwidth)
- Custom application metrics
- OpenTelemetry traces for all gRPC calls
๐ API
The agent provides the following gRPC services:
AgentStream: Bidirectional streaming for heartbeat and commandsExecuteCommand: Execute occtl/systemctl commandsUpdateConfig: Update ocserv configuration with backupStreamLogs: Stream ocserv logs in real-timeHealthCheck: Multi-tier health checks
See agent.proto for full API specification.
๐ฆ Installation
From Binary
# Download latest release
wget https://github.com/dantte-lp/ocserv-agent/releases/download/v0.5.0/ocserv-agent-v0.5.0-linux-amd64.tar.gz
tar -xzf ocserv-agent-v0.5.0-linux-amd64.tar.gz
# Install to /etc/ocserv-agent
sudo mkdir -p /etc/ocserv-agent
sudo mv ocserv-agent /etc/ocserv-agent/
sudo chmod +x /etc/ocserv-agent/ocserv-agent
# Install systemd service
sudo cp deploy/systemd/ocserv-agent.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now ocserv-agent
From Source
git clone https://github.com/dantte-lp/ocserv-agent.git
cd ocserv-agent
make compose-build
sudo make install
Docker
podman pull ghcr.io/dantte-lp/ocserv-agent:latest
podman run -d \
--name ocserv-agent \
-v /etc/ocserv-agent:/etc/ocserv-agent:z \
ghcr.io/dantte-lp/ocserv-agent:latest
๐งช Testing
# Unit tests
make compose-test
# Integration tests
cd test/integration
go test -v ./...
# Test with grpcurl
grpcurl -cacert certs/ca.crt \
-cert certs/admin.crt \
-key certs/admin.key \
-d '{"tier": 1}' \
localhost:9090 \
agent.v1.AgentService/HealthCheck
๐ค Contributing
We welcome contributions! Please follow our development workflow:
- Read the Contributing Guide for detailed instructions
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes and ensure CI passes
- Create a Pull Request
Required checks before merge:
- โ Test (Go 1.25)
- โ Code Quality Checks
- โ golangci-lint
See CONTRIBUTING.md for complete workflow documentation
Commit Message Format
<type>(<scope>): <subject>
<body>
<footer>
Types: feat, fix, docs, style, refactor, test, chore
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
๐ Acknowledgments
- ocserv - OpenConnect VPN server
- gRPC - High-performance RPC framework
- zerolog - Zero allocation JSON logger
Upstream Contributions
We actively contribute bug reports and fixes to the ocserv project:
-
Issue #661 - Root cause analysis for
show iroutesinvalid JSON- Identified 3 bugs in
src/occtl/unix.c:1018-1045 - Provided proposed fix with code examples
- Identified 3 bugs in
-
Issue #669 - Reported regression of #220 in ocserv 1.3.0
- Trailing commas in
show sessionscommands - Production-tested and documented
- Trailing commas in
๐ฌ Contact
- GitHub: @dantte-lp
- Issues: GitHub Issues
๐บ๏ธ Roadmap
See ROADMAP.md for detailed project roadmap and timeline.
โ v0.4.0 BETA (Completed - October 2025)
Test Foundation & DevOps:
- โ internal/config: 97.1% coverage (PR #14)
- โ internal/cert: 77.6% coverage (certificate generation tests)
- โ internal/ocserv/config.go: 82-100% coverage (config parser tests)
- โ Test infrastructure with 8 fixture files
- โ 2,225 lines of test code
DevOps Improvements:
- โ Automatic code formatting (scripts/quick-check.sh)
- โ Git hooks (pre-commit: auto-format, pre-push: checks) (PR #16)
- โ
One-time setup:
./scripts/install-hooks.sh - โ CI path filtering (skip expensive jobs for docs-only changes)
Security:
- โ Branch protection with required reviews
- โ Admin bypass for hotfixes
- โ OSSF Scorecard: 5.9/10
โ v0.5.0 BETA (Completed - October 2025)
Test Coverage Expansion & Security Fixes:
- โ CRITICAL: Fixed 4 command injection vulnerabilities (29 test cases)
- โ internal/grpc: 0% โ 87.6% coverage (exceeded >80% target!)
- โ internal/ocserv: 15.8% โ 23.1% coverage
- โ Overall internal: ~40% โ 51.2% (+11.2%)
- โ 1,600+ new lines of test code
- โ Test infrastructure: TLS certificate helpers, security validation
- โ validateArguments: 100% coverage (security-first testing)
๐ฎ Next: v0.6.0 (Security Hardening & Integration Tests)
Target: January 2026
Goals:
- OSSF Scorecard: 7.5+/10 (GPG signing, dependency pinning, token permissions)
- Integration tests with mock ocserv
- Rate limiting for gRPC API
- Security scanning in CI (gosec, trivy)
๐ Future (v0.6.0+)
- Bidirectional streaming (AgentStream RPC)
- Enhanced metrics (Prometheus exporter)
- Heartbeat with exponential backoff
- ocserv-fw firewall integration
- Virtual hosts support
- RADIUS/Kerberos monitoring
See CURRENT.md for current tasks and ROADMAP.md for long-term project roadmap.
Directories
ยถ
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
agent
command
|
|
|
internal
|
|
|
ocserv/testutil
Package testutil provides test utilities for integration testing
|
Package testutil provides test utilities for integration testing |
|
testutil/grpc
Package testutil provides testing utilities for gRPC integration tests
|
Package testutil provides testing utilities for gRPC integration tests |
|
test
|
|
|
mock-ocserv
command
mock-ocserv: Mock ocserv Unix socket server for integration testing
|
mock-ocserv: Mock ocserv Unix socket server for integration testing |
|
mock-server
command
|