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>
72 lines
3.5 KiB
Plaintext
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 = -
|