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 ✅
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
Control Server (ocserv-web-panel)
↓ gRPC + mTLS
Agent (this project)
↓ exec/shell
ocserv daemon
- 🔐 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
✅ 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
show iroutes- invalid JSON (we contributed fix upstream)show sessions all/valid- trailing commas (we reported regression)
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 certsOn 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.
- Go 1.25+
- Podman and podman-compose
- protobuf-compiler (for proto generation)
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.yamlOption 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# 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 onlyThis 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)
# Fast checks in 2-3 seconds (auto-formats code!)
./scripts/quick-check.shFeatures:
- ✅ Auto-formats Go code with
gofmt -s -w - ✅ Runs
go vetfor common mistakes - ✅ Builds the project
- ✅ Runs all unit tests
Install git hooks to automatically format code before commits:
# One-time setup
./scripts/install-hooks.shInstalled 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# Run all CI checks locally (saves GitHub Actions minutes!)
./scripts/test-local.shSee LOCAL_TESTING.md for details.
# Run all tests in containers
make compose-test
# View logs
make compose-logs# Build multi-arch binaries
make compose-build
# Binaries will be in bin/:
# - bin/ocserv-agent-linux-amd64
# - bin/ocserv-agent-linux-arm64- 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
- 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 Policy - Vulnerability disclosure process
- OSSF Scorecard Improvements - Security roadmap (4.9 → 7.5+/10)
- ocserv Compatibility - Feature coverage analysis
- 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 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.
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-downImportant: Do NOT use go build or go test directly on the host. Always use Podman Compose targets for consistency and reproducibility.
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
- 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
- ✅ 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)
- 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
- System metrics (CPU, memory, load)
- ocserv metrics (sessions, bandwidth)
- Custom application metrics
- OpenTelemetry traces for all gRPC calls
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.
# 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-agentgit clone https://github.com/dantte-lp/ocserv-agent.git
cd ocserv-agent
make compose-build
sudo make installpodman 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# 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/HealthCheckWe 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
<type>(<scope>): <subject>
<body>
<footer>
Types: feat, fix, docs, style, refactor, test, chore
This project is licensed under the MIT License - see the LICENSE file for details.
- ocserv - OpenConnect VPN server
- gRPC - High-performance RPC framework
- zerolog - Zero allocation JSON logger
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
- GitHub: @dantte-lp
- Issues: GitHub Issues
See ROADMAP.md for detailed project roadmap and timeline.
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
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)
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)
- 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.