Files
ovgate/docker/openvpngate.conf
T
iceBear67andClaude Opus 5 f37cd0a125 Add container build, compose example and deployment docs
Multi-stage Dockerfile on debian:trixie-slim. openvpn3 and lwIP are cloned
at pinned refs and handed to CMake through OVG_OPENVPN3_DIR/OVG_LWIP_DIR
rather than left to FetchContent, whose GIT_TAG master would make the same
Dockerfile build a different VPN client each week. The unit suite runs in
the builder stage.

docker/openvpngate.conf overrides only the keys whose host default is wrong
inside a container -- loopback listen addresses, which make a published port
reach nothing, and relative state paths, which put the node failure history
on a layer that gets thrown away. Everything else stays absent and takes the
compiled-in default so the file cannot drift from the code.

The compose example drops every capability, runs read-only as uid 10001 and
publishes both ports to host loopback: the admin endpoint has no auth and
includes POST /switch. That configuration is the design constraint of this
project (no root, no tun device) turned into something testable.

docs/DOCKER.md 8 records what was checked against the source and what was
not: this sandbox has no docker daemon, so neither the image build nor the
compose file has actually been run.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-28 05:54:44 +00:00

72 lines
3.5 KiB
Plaintext

# openvpngate -- configuration baked into the container image.
#
# This file sets ONLY the keys whose host default is wrong inside a container.
# Everything else is left absent and takes the compiled-in default, so this
# file cannot drift from the code the way a copied-and-edited full config does.
#
# etc/openvpngate.conf in the source tree is the annotated reference: every key,
# its default, and why that is the default. Read that one to change behaviour,
# then add the key here.
# ---------------------------------------------------------------------------
[socks5]
# ---------------------------------------------------------------------------
# The default is 127.0.0.1, which inside a container means "reachable from this
# container only" -- a published port would connect to nothing. Bind everywhere
# and let the container runtime decide who gets to reach it: docker-compose.yml
# publishes this to host loopback, not to the LAN.
listen_address = 0.0.0.0
listen_port = 1080
require_auth = true
# Credentials stay out of the image. Mount a file here (docker-compose.yml
# does) -- SIGHUP re-reads it without dropping a live session:
#
# docker compose kill -s HUP openvpngate
#
# If this path is missing the process exits at startup with
# "config: cannot open auth file"; if it is a *directory* -- which is what
# Docker silently creates for a bind mount whose source does not exist -- the
# file parses as empty and startup warns "every login will be refused". The
# compose file uses create_host_path: false so that case fails loudly instead.
auth_file = /etc/openvpngate/socks5.auth
# ---------------------------------------------------------------------------
[vpngate]
# ---------------------------------------------------------------------------
# Absolute. The default is relative (var/vpngate_cache.csv) and would resolve
# against the working directory; inside the image that is /var/lib/openvpngate,
# which happens to be right, but only by accident. Say it explicitly, because
# this is also the one path that survives a container replacement and the one
# directory a read-only rootfs still permits writing to.
cache_path = /var/lib/openvpngate/vpngate_cache.csv
# ---------------------------------------------------------------------------
[selector]
# ---------------------------------------------------------------------------
# Same reasoning. Worth persisting for a different reason though: this is the
# record of which nodes have failed on you, and losing it on every `up` means
# walking back into the same broken node with a flattering API score.
history_path = /var/lib/openvpngate/node_history.tsv
# ---------------------------------------------------------------------------
[admin]
# ---------------------------------------------------------------------------
# Bound everywhere for the same reason as socks5 above -- but this endpoint has
# NO authentication and includes POST /switch, so whoever can reach it can force
# your gateway onto another node. It is protected here by *publishing* rules,
# not by the bind address: keep it on 127.0.0.1 on the host side, or set
# enabled = false and drop the HEALTHCHECK from the Dockerfile, which probes it.
enabled = true
listen_address = 0.0.0.0
listen_port = 9080
# ---------------------------------------------------------------------------
[log]
# ---------------------------------------------------------------------------
# stderr, so that `docker logs` and the compose log driver see it. Logging to a
# file inside a container puts the record on the layer that gets thrown away.
level = info
file = -