vpn
VPN profiles, and the gateways that carry sessions' traffic through them.
A profile is what an administrator imported from a provider's config files:
a template (an OpenVPN client config without its remote lines, or a
WireGuard [Interface]), the credentials the template asks for, and an
endpoint list with one entry per server the files named. A bundle of
thousands of files from a provider is one template and a long endpoint
list, because the files differ in the server alone; files whose template
differs become profiles of their own. The record is shared
(vpn_profiles.yml): every node reads the name, the endpoints, which of
them are published to users, the connection cap, and who may use the
profile. The template, the OpenVPN username and password, and the WireGuard
preshared keys are the profile's secrets: with a store key they are sealed
under the cluster key (filecrypt.wrap) before the record leaves the node,
and without one they are kept as the users' files are.
A session that chose a profile and an endpoint starts on an internal Docker
network of its own, which has no route out, beside a gateway container
(vpn_image) that holds the one tunnel to the endpoint, forwards the
sessions' traffic into it and nowhere else, and answers their DNS through
it. The server's own container joins the network to reach the session, the
session's /etc/resolv.conf names the gateway, and a one-shot helper from
the same image, run in the session's network namespace, points its default
route at the gateway. The session's image needs nothing for this, and a
gateway that is down leaves its sessions with no path out. One gateway per
profile and endpoint on a node carries every session that picked them, so a
provider's device limit is spent once per endpoint in use, and
max_tunnels caps the gateways of a profile on a node. A gateway starts
with the first session that needs it and stops with the last; its rendered
files live under node_state_path/vpn/<key> while it runs.
attributelogger= logging.getLogger(__name__)attributeKINDS= ('wireguard', 'openvpn')attributeMANAGED_LABEL= 'sealskin.managed-by'attributeMANAGED_VALUE= 'sealskin-vpn'attributeKEY_LABEL= 'sealskin.vpn'attributePROFILE_LABEL= 'sealskin.vpn.profile'attributeENDPOINT_LABEL= 'sealskin.vpn.endpoint'attributeGATEWAY_HOST= 2attributeHEALTHY_TIMEOUT= 120attributeORPHAN_GRACE= 90attributeREMOTE_STATE= 'running'attributeMAX_BUNDLE_BYTES= 64 * 1024 * 1024attributeMAX_FILE_BYTES= 1024 * 1024attributeMAX_FILES= 20000attributeCONFIG_SUFFIXES= ('.ovpn', '.conf')