Skip to content

Latest commit

 

History

History
92 lines (78 loc) · 7.3 KB

v19.0-testing.md

File metadata and controls

92 lines (78 loc) · 7.3 KB

OpenVPN 19.0 testing

Scope and source decision

OpenVPN 19.0 uses Debian 13 Trixie packages for OpenVPN Community Edition, Easy-RSA, iptables and their supporting libraries. Debian supplies the complete application stack, so this appliance adds no third-party application repository or downloaded application artifact. The inherited TurnKey Core and Webmin packages continue to use the signed TurnKey Trixie repository.

The OpenVPN, Easy-RSA and iptables update path is normal authenticated APT. tests/v19.sh refreshes signed metadata, confirms an eligible candidate for each identity-defining package, and proves that the nonmutating check did not change installed versions. No separate compatible apply fixture exists or is needed for the Debian package route.

The acceptance command is:

TKLDEV_CONTAINER=tkldev19-jeremy-qa \
TKL_HARNESS_STATE_DIR=/home/agent/.local/state/jeremy-v19-pr-qa/openvpn \
TKL_HARNESS_LOCK_FILE=/home/agent/.local/state/jeremy-v19-pr-qa/build.lock \
/home/agent/turnkey/tools/test-v19-appliance openvpn \
  --source /home/agent/.local/state/jeremy-v19-pr-qa/worktrees/openvpn-candidate

It builds a configured Trixie root in TKLDev, imports it into a disposable privileged Docker container, follows normal systemd init and firstboot, and runs tests/v19.sh. The retained harness report records the exact source and harness commits, source archive/tree hashes, configured-root driver, runtime evidence, updater evidence, cleanup status and verdict.

Security and failure boundaries

  • Firstboot administrator inputs cross into Easy-RSA variables and OpenVPN configuration. The Python hook validates email, DNS/IP address and strict IPv4 networks before changing PKI; the shell initializer independently rejects unsafe email/address spellings. Failed initialization or service restart is fatal rather than silently leaving partial success.
  • Client names cross into certificate and filesystem paths. The helper scripts accept only a bounded portable name, validate email, subnet and port values, and create embedded-private-key profiles and keys with mode 0600 under a process umask of 0077.
  • The kernel routing table selects the current IPv4 default interface. The dedicated oneshot helper validates that kernel-provided name, installs one idempotent, appliance-labelled rule limited to the configured VPN subnet, records it below /run, and removes that exact rule on stop. No interface name such as eth0 is assumed.
  • OpenVPN starts as root only for device, socket and key setup, then follows the shipped configuration's user nobody, group nogroup and CRL chroot. The NAT service is bounded to CAP_NET_ADMIN and the CAP_NET_RAW socket capability required by iptables-legacy, a read-only system tree and its one /run state file.
  • The OpenVPN web root is global to the appliance and inherits Core's hardened TLS listeners and HTTP-to-HTTPS redirect; the application does not create a competing SSL socket or duplicate the shared cipher policy.

README crosswalk

README contract Focused command Required result Evidence
Server/gateway firstboot creates a working OpenVPN deployment Check inithook completion, server config, PKI and active openvpn@server after normal init Firstboot succeeds and the service has a CA, server key/cert, modern data ciphers and subnet topology tests/v19.sh; retained child/runtime result
Clients authenticate with certificates and keys Generate a disposable profile with openvpn-addclient, start a client in its own network namespace, and wait for tun0 The TLS client establishes a tunnel using the generated embedded profile tests/v19.sh; OpenVPN client log on failure
A private subnet behind a client can join the VPN Generate a client with an RFC 5737 test subnet, restart OpenVPN, and inspect its route and chrooted client-config access The scoped route is installed, the dropped OpenVPN process reads the root-owned CCD file, and revocation removes both route and CCD state tests/v19.sh; service journal on failure
Gateway profile routes client traffic through the VPN Resolve the Debian HTTPS endpoint outside the namespace, prove its route uses client tun0, and fetch it through that interface A nonempty authenticated HTTPS response traverses tunnel, server forwarding and default-interface NAT tests/v19.sh; retained runtime result
The tunnel carries application data Request the appliance HTTPS endpoint and a published profile through the server tunnel address The client receives a nonempty HTTPS response, the profile listing, and the exact generated profile over tun0 tests/v19.sh
Service configuration persists across restart Restart OpenVPN and the NAT service, wait for client reconnection and repeat the tunnel request Both services remain active, exactly one NAT rule remains, and tunnel data still passes tests/v19.sh
Client profiles can be revoked Stop the disposable client and run openvpn-removeclient The profile is removed and the Easy-RSA index records revocation tests/v19.sh
Embedded private keys are protected Inspect client profile and private-key modes and search the private directory for group/world access Profile and client key are 0600; no private key grants group/world permissions tests/v19.sh
Administrator input cannot append OpenVPN directives or escape client paths Submit a newline-bearing public address, a host-address CIDR and a path-bearing client name Each input fails and the existing server configuration digest is unchanged tests/v19.sh
OpenVPN is maintained from Debian Refresh APT and inspect OpenVPN, Easy-RSA and iptables candidates Signed Trixie metadata is accepted, eligible candidates exist, installed versions do not change and no Bookworm source remains tests/v19.sh; harness updater fields
Expiring HTTPS profile links are available Publish the disposable client under a random 192-bit URL token, download the page and profile through the tunnel, then run the expiry helper as www-data Lighttpd serves the profile with bounded permissions and the observed download is deleted tests/v19.sh; retained runtime result
Webmin and SSH use the inherited root credential Covered by the unchanged Core implementation Passes in the accepted Core 19 baseline Core 19 baseline evidence

The server profile's optional routed private LAN and the client profile's site-to-site routing use the same validated CIDR and authenticated tunnel primitives. Acceptance exercises the higher-value gateway path end to end; it does not create a second physical LAN solely to duplicate those primitives.

Known limitations and deferred work

The Docker path does not exercise the installer, host kernel variants, physical interfaces, cloud security groups or mobile QR scanners. The test does exercise privileged TUN creation, a separate client network namespace, certificate authentication, real encrypted data transfer, forwarding, NAT and service restart. The inherited Core 19 baseline covers unchanged platform behavior.

IPv6 enablement remains explicitly documented as future, untested work in docs/ipv6.md; it is not a v19.0 runtime claim. Performance, multi-client load, optional TLS 1.3-only configuration and exhaustive site-to-site topology coverage are outside the functional 20/80 gate.