Service commands¶
Commands that run and install the server roles. Writing a first configuration
from flags is gdsgate setup. Global flags are in the
CLI hub.
gdsgate proxy¶
Run the Proxy: public listener, internal reverse-tunnel listener, WebSocket fallback listener, single Authority client. Stateless.
Reads: [endpoints], [enroll], [proxy].
TOKEN_FILE="<proxy-enrollment-token-file>"
GDSGATE_ENROLL_TOKEN="$(<"$TOKEN_FILE")" \
gdsgate --config proxy.toml proxy
The Proxy registers on first start, consuming the token, persists its identity to
[enroll].state_dir, and on subsequent starts reuses the persisted identity.
With no [enroll].endpoint, the Proxy runs plaintext, for dev and loopback only.
gdsgate proxy init --domain <name>¶
Write the configuration a Proxy is started from. Writes a file and starts
nothing; enrolling the node is gdsgate join.
Writes: [endpoints], [proxy], [telemetry]. Composed by
setup prepare it also writes [enroll] and, where
the deployment named one, [oidc].
gdsgate proxy init --domain gate.example.com \
--tls-cert /etc/letsencrypt/live/gate.example.com/fullchain.pem \
--tls-key /etc/letsencrypt/live/gate.example.com/privkey.pem \
--output /etc/gdsgate/proxy.toml
| Flag | Default | Meaning |
|---|---|---|
--domain <name> |
required | The name clients dial. The certificate has to carry it. |
--listen <addr> |
0.0.0.0:50061 |
Client-facing bind. A port below 1024 is accepted with a condition in the plan: the shipped systemd unit cannot bind it. Put a front or an nftables redirect ahead of it. |
--authority <addr> |
127.0.0.1:50051 |
Where Authority answers. |
--authority-enroll <addr> |
127.0.0.1:50050 |
Where Authority answers registration; the relay forwards a joining node's first exchange there. Written only with --join-relay. The plan names it as a condition when left at the default. |
--join-relay |
off | Bind proxy_join, for nodes whose only route to the control plane is this gateway. |
--tls-cert, --tls-key |
unset | What the client-facing listener presents. |
--output <path> |
/etc/gdsgate/proxy.toml |
Where the configuration goes. |
--save <dir>, --node <name> |
unset | Write a bundle for another machine; nothing on this machine changes. |
--approve-plan <digest> |
unset | Refuse unless the plan is the one that digest names. |
--dry-run, --json |
off | Show the plan; print it as JSON. |
proxy_internal (0.0.0.0:50062) and proxy_ws (0.0.0.0:50063) are always
written. proxy_join is bound only with --join-relay; it accepts callers
that have not authenticated, and the plan says so. With it comes
authority_enroll, the address the relay forwards registration to. If
Authority's ports were moved and this address was left at the default, a
joining node is told its token is unknown.
An existing file is refused; change it with
setup change. Exit codes are the
setup contract.
gdsgate connector¶
Run the Connector: dials the Proxy's reverse-tunnel listener, registers the
resources declared in [[connector.backends]], and serves them.
Reads: [endpoints], [enroll], [connector].
TOKEN_FILE="<connector-enrollment-token-file>"
GDSGATE_ENROLL_TOKEN="$(<"$TOKEN_FILE")" \
gdsgate --config connector.toml connector
For any SSH backend, of either model, the connector loads its host key from
<state_dir>/ssh_host_ed25519_key, generating one on first start. A jump host
appears in the caller's known_hosts under this key.
An enrolled connector serving an SSH backend also keeps
<state_dir>/activation.json, the highest activation epoch it has seen. It
refuses to start when that file cannot be read or written. See
gdsgate authority activate.
On Windows a connector refuses to start with an SSH backend that uses
ssh_profile = "git", login_mode = "host_user", or session ceilings in
[connector.backends.session].
gdsgate agent-host¶
Runs the agent host: starts the agents declared for this node, each in its own cage. See the agent host guide.
Reads: [endpoints].authority, [enroll], [agent_host],
[telemetry].metrics_listen.
TOKEN_FILE="<agent-host-enrollment-token-file>"
GDSGATE_ENROLL_TOKEN="$(<"$TOKEN_FILE")" \
gdsgate --config agent-host.toml agent-host
Binds no listener. Connects to Authority over mutual TLS. The enrollment token is used once; the node certificate is renewed without a token.
The agents and their access are declared on Authority with
authority set-agent; this
host has no configuration for them. Enroll the node with
gdsgate join --role agent-host, using a token from
gdsgate authority create-token --role agent-host.
A node holding no enrolled identity is refused under
[security].profile = "pilot" or "production".
Agents run on Linux only. On Linux, install the unit from
packaging/systemd/gdsgate-agent-host.service by hand; service install does
not offer this role. On Windows the process starts but runs no agents, and logs
each declared agent as not held.
gdsgate connector recordings push [--dry-run]¶
Delivers the recordings a running connector is holding in
central mode but has not yet
gotten to Authority, or says why not, without waiting for the next scheduled
delivery pass.
gdsgate --config connector.toml connector recordings push --dry-run
gdsgate --config connector.toml connector recordings push
--dry-run lists what is on disk and, for each cast, why it is still there;
nothing is uploaded and nothing is removed. A real run uploads and removes what
the store accepts, printing one line per cast, delivered or held back, and a
summary.
The command asks the running connector to deliver, over its local control
channel: the socket ${enroll.state_dir}/connector.sock on Linux, a named pipe
derived from that path on Windows. When no connector is listening, the command
says so and exits 1; the connector's next start runs a delivery pass.
When a delivery pass is already running, the command says it is waiting, waits for it, then runs its own.
Exit codes, the same four gdsgate join uses:
| Exit | Meaning |
|---|---|
0 |
At least one cast was delivered. |
1 |
Nothing was delivered and something is held back, including a pass that stopped partway through, an unreachable store for one. |
2 |
The arguments do not parse. |
3 |
There was nothing to deliver. |
See gdsgate doctor to check
whether anything is waiting before running this by hand, and the
admin guide for the operator recipe
this command is part of.
gdsgate all¶
Run Authority, Proxy and an embedded Connector in one process. store_url
defaults to a SQLite file (~/.gdsgate/state/store.db) that survives restarts.
Other connectors can still register on the registration listener.
Reads: every section.
gdsgate service install|uninstall <role>¶
Installs a role as a service, or removes it. Server roles require root on Linux
and an elevated prompt on Windows. install does not start the service unless
--start is supplied for client. The agent host is not offered; see
gdsgate agent-host.
Linux¶
Roles: authority, proxy, connector. The unit is the shipped one from
packaging/systemd, with the paths filled in.
| Property | Value |
|---|---|
| Unit | /etc/systemd/system/gdsgate-<role>.service, enabled |
| Program | the gdsgate that runs install; refused under /tmp, /var/tmp, /home, /root and /run/user, which the unit hides from the service |
| Account | DynamicUser=yes, in the gdsgate group |
| Configuration | --config, default /etc/gdsgate/<role>.toml; its directory, its *.toml, *.cedar and *.keys, and every file the configuration names inside it (a registration key, a certificate) are given to the gdsgate group, files 0640 |
| Environment | <role>.env beside the configuration, optional |
| State | /var/lib/gdsgate/<dir>, the one directory the service may write |
| Log | journalctl -u gdsgate-<role> |
| Start | with the machine; Restart=on-failure after 2 s |
| Certificate reload | systemctl reload gdsgate-<role> re-reads the listener certificates (authority, proxy) |
<dir> is the directory under /var/lib/gdsgate that the role's configured
paths are in: [enroll].state_dir for proxy and connector, the SQLite
store and [audit].export_path for authority. Without one, it is the role's
name. A file the role reads from under /var/lib/gdsgate has to be in the
same directory. install refuses the configuration if one of these paths is
elsewhere:
| Refusal | Fix |
|---|---|
... is outside /var/lib/gdsgate |
Move the written path under /var/lib/gdsgate/<role>. |
... is where every role's directory is |
Name a directory under it, such as /var/lib/gdsgate/connector. |
... is directly in /var/lib/gdsgate |
Move the file into the role's directory and change the path in the configuration. |
... are in two directories under /var/lib/gdsgate |
Keep the role's files in one directory. |
When /var/lib/gdsgate is a link into /var/lib/private (left by units that
shared one state directory), install turns it into a directory. Role
directories stay where they were; files that sat directly in it move back. A
unit that still has StateDirectory=gdsgate no longer starts, and install
names it: install that role again.
Every Linux service install, including client, checks the shared parent
/var/lib/gdsgate. An install run as root creates or repairs this directory
to mode 0755 before registering the service. A parent left at 0700 blocks
service accounts from reaching their private state. The repair changes only
the common parent; role directories and key files keep their permissions.
An unprivileged install reports an invalid existing parent and requires an
administrator to repair it. Unexpected links and non-directory entries are
refused. doctor reports the same parent
problem without changing permissions.
gdsgate --config /etc/gdsgate/authority.toml service install authority
systemctl start gdsgate-authority.service
gdsgate service uninstall authority
Resident client¶
Linux also supports client: the default protected system unit runs as the
original user and retains their configuration and identity. It needs elevation
and the trusted kernel filter command. A user unit is available with
local_user_only = false and a loopback access level. Normal gdsgate up
handles installation and startup, asking for elevation once when needed. --foreground runs the
resident directly. See Resident service.
sudo gdsgate --config "$CLIENT_CONFIG" service install client --start
sudo gdsgate service uninstall client
--start is accepted only for client. On Windows, client installs the same
privileged network helper as client-net; the resident remains in the user
session. An ordinary up ensures that helper is running.
Windows¶
Roles: authority, proxy, connector, client-net, client.
| Property | Value |
|---|---|
| Service name | gdsgate-<role> |
| Account | virtual account NT SERVICE\gdsgate-<role>; client-net runs as SYSTEM |
| Configuration | --config, default %ProgramData%\gdsgate\<role>.toml; client-net reads none |
| State | %ProgramData%\gdsgate\state\<role>, owned by the service account |
| Log | %ProgramData%\gdsgate\logs\gdsgate-<role>\gdsgate-<role>.log, rotated at 32 MiB, three kept; the service account writes its own directory there and no other |
| Start | with the machine; restarted 5 s after a failure, including an exit with an error |
| Certificate reload | sc.exe control gdsgate-<role> paramchange re-reads the listener certificates |
install gives the service account read access to the configuration, every
file it names, and gdsgate.exe. It also makes the account the owner of its
state directories. Secret files lose every entry except their owner, SYSTEM
and the gdsgate service accounts. Running install again for a registered
service renews those grants: run it after adding a file to the configuration.
On both systems uninstall stops the service and removes the unit or the
registration. Configuration, state and log stay where they are. Removing a
service that is not installed succeeds.
gdsgate service install authority
sc.exe start gdsgate-authority
gdsgate service uninstall authority
gdsgate client-net¶
Windows only; refused on Linux, where the resident client runs from
gdsgate-client@.service. The service sets the NRPT rule and holds the Wintun
adapter for the resident client; see
Resident client on Windows. A delegated run
under --sandbox basic or strict uses it to let the run's container reach its
endpoints, read drive letters and use NUL; see
The sandbox on Windows. The Windows
installer registers it with gdsgate service install client-net. Do not run it
by hand.
Service lifecycle¶
proxy, connector, authority and all run in the foreground until stopped;
run them under systemd on Linux or the service manager on Windows. Before
treating a replacement as ready, check /healthz and /readyz: a process can
be live while its dependencies are not ready.