Erebus: A Rootless User-Space VPN Proxy
Erebus enables rootless VPN connectivity in restricted environments
Erebus is a user-space VPN proxy that allows users to establish VPN connections without requiring root privileges or modifying the host's networking stack. By implementing the OpenVPN protocol and a TCP/IP stack entirely within a single process, Erebus bypasses the need for kernel tun/tap interfaces and routing table modifications, making it ideal for environments where sudo access is unavailable, such as CI runners, sandboxes, and unprivileged containers.
Architecture: Moving the VPN stack to user space
Erebus replaces the traditional kernel-based routing and TCP handling with its own internal logic. The only system privilege required by the tool is the ability to open a standard network socket.
The data flow
When a request is made, the data follows this path:
- Local HTTP Client: A client application points to the local Erebus proxy.
- HTTP Proxy: Erebus accepts and relays the request.
- User-Space TCP/IP Stack: The process builds and parses IPv4, TCP, and ICMP packets by hand.
- Encryption: Packets are encrypted using the OpenVPN static-key (wire format v1) protocol, applying HMAC and packet IDs.
- Transport: The encrypted data is sent as a UDP datagram or TCP frame to the OpenVPN server.
Key Features and Capabilities
Rootless Operation
Erebus requires no sudo permissions, no setup scripts, and does not touch the host's interfaces, routes, or DNS settings. It can be started and stopped as a standard user process.
Opt-in Traffic Routing
Connectivity is explicit rather than system-wide. Users must point specific applications to the local proxy to route traffic over the VPN.
- Outbound: A local HTTP/1.x proxy forwards requests to resources on the VPN.
- Inbound: Port forwards expose local services to VPN peers bidirectionally.
Protocol Support
- OpenVPN: Supports static-key mode (pre-shared key) over UDP or TCP. It supports CBC ciphers (AES, ARIA, Camellia) and various HMAC digests.
- IPsec: Includes an IKEv2 control plane and an ESP data plane that interoperate with strongSwan. Because rootless processes cannot send raw ESP, all traffic is UDP-encapsulated (NAT-T) using pre-shared keys.
Usage and Installation
Erebus is written in Common Lisp (SBCL) and is distributed as a Debian package for Debian/Ubuntu derivatives.
Quick Start Configuration
A minimal configuration for an outbound UDP proxy is defined in an INI file:
[erebus]
client-ip = 10.8.0.2
[openvpn-server]
proto = udp
host = vpn.example.com
port = 1194
secret = /etc/erebus/static.key
cipher = AES-256-CBC
auth = SHA256
[proxy-out]
address = 127.0.0.1
port = 11023
To use the proxy, users can route traffic via the command line:
http_proxy=http://127.0.0.1:11023 curl http://10.8.0.1/
Performance and Limitations
Erebus is an early-stage experimental project that prioritizes correctness and clarity over performance.
Use Case Suitability
| Ideal For | Not Ideal For |
|---|---|
| Internal HTTP services in unprivileged containers | System-wide VPN routing |
| CI jobs needing private endpoints | Bulk data transfer |
| Sandboxed or multi-tenant hosts | TLS-mode OpenVPN (certificates) |
| Exposing a single local port to a VPN peer | HTTPS CONNECT tunneling or SOCKS |
Performance Trade-offs
Because the implementation sends data one piece at a time and waits for confirmation before sending the next, large downloads are significantly slower than a standard proxy. This design choice ensures code simplicity and interoperability.