nats and bao can listen on a routable address, opt-in
This commit is contained in:
parent
4b71bd97eb
commit
892675628d
3 changed files with 174 additions and 6 deletions
|
|
@ -2891,6 +2891,30 @@ in
|
|||
misconfiguration rather than a topology.
|
||||
'';
|
||||
};
|
||||
|
||||
openFirewall = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
example = true;
|
||||
description = ''
|
||||
Open {option}`services.hyperhive.swarm.bao.port` in the host firewall
|
||||
on every interface, so hives on other hosts can reach the addresses in
|
||||
{option}`services.hyperhive.deploy.bao.extraListenAddresses` over the
|
||||
LAN or the internet. Off by default: the port is otherwise open only on
|
||||
the agent bridge.
|
||||
|
||||
⚠️ This exposes the secret store beyond the tunnel. Every listener
|
||||
requires a client certificate signed by
|
||||
{option}`services.hyperhive.deploy.bao.clientCaFile`, and nothing
|
||||
answers without one, which is why setting this without that file, or
|
||||
without any extra address, fails evaluation. Whether the store may be
|
||||
reachable at all from outside a private network is the operator's
|
||||
decision.
|
||||
|
||||
Point `bao.<swarm domain>` in the operator's upstream DNS at the
|
||||
address the other hives reach.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
# ⚠️ Gated on `deploy.bao.enable`, and that is load-bearing rather than
|
||||
|
|
@ -2936,6 +2960,24 @@ in
|
|||
deploy.bao.otel.telemetryPort. Pick free ports.
|
||||
'';
|
||||
}
|
||||
{
|
||||
assertion = !baoDeploy.openFirewall || baoDeploy.clientCaFile != null;
|
||||
message = ''
|
||||
services.hyperhive.deploy.bao.openFirewall opens the store's port to
|
||||
every interface, but services.hyperhive.deploy.bao.clientCaFile is
|
||||
null, so its listeners would not require a client certificate. Set
|
||||
clientCaFile, or leave openFirewall off.
|
||||
'';
|
||||
}
|
||||
{
|
||||
assertion = !baoDeploy.openFirewall || baoDeploy.extraListenAddresses != [ ];
|
||||
message = ''
|
||||
services.hyperhive.deploy.bao.openFirewall is set, but
|
||||
services.hyperhive.deploy.bao.extraListenAddresses is empty: the
|
||||
store listens on loopback only, so the open port reaches nothing.
|
||||
Name the address other hives reach, or leave openFirewall off.
|
||||
'';
|
||||
}
|
||||
{
|
||||
assertion = cfg.ui.domain != cfg.domain;
|
||||
message = ''
|
||||
|
|
@ -3090,6 +3132,11 @@ in
|
|||
# certificate its CA signed.
|
||||
services.hyperhive.network.exposeHostPorts = [ cfg.port ];
|
||||
|
||||
# Every listener, bridge-IP passthrough included, requires the client
|
||||
# certificate (see `listenerTls`), so opening the port host-wide adds
|
||||
# reach and no unauthenticated path.
|
||||
networking.firewall.allowedTCPPorts = lib.mkIf baoDeploy.openFirewall [ cfg.port ];
|
||||
|
||||
# The operators' door to the UI, shaped like ./swarm-victorialogs.nix's
|
||||
# vhost. It proxies to the container's nginx over loopback (shared
|
||||
# netns), so no port opens anywhere. `auth_request` only proves a
|
||||
|
|
|
|||
|
|
@ -57,8 +57,9 @@ in
|
|||
3000, every agent in 8100..8999 via FNV-1a hash).
|
||||
|
||||
Opened on the bridge interface, for agent containers, and on
|
||||
`wg-hive` when this host is on the mesh, for other hives. Never
|
||||
host-wide. TLS only: a client that does not speak it is refused.
|
||||
`wg-hive` when this host is on the mesh, for other hives. Host-wide
|
||||
only when {option}`services.hyperhive.deploy.nats.openFirewall` is
|
||||
set. TLS only: a client that does not speak it is refused.
|
||||
|
||||
Unlike {option}`services.hyperhive.deploy.nats.monitorPort` and
|
||||
{option}`services.hyperhive.deploy.nats.metricsPort`, the
|
||||
|
|
|
|||
|
|
@ -505,6 +505,28 @@ in
|
|||
A path, never a value.
|
||||
'';
|
||||
};
|
||||
|
||||
openFirewall = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
example = true;
|
||||
description = ''
|
||||
Open {option}`services.hyperhive.swarm.nats.port` in the host firewall
|
||||
on every interface, so hives on other hosts can reach the queue on
|
||||
this host's LAN or public address. Off by default: the port is
|
||||
otherwise open only on the agent bridge and, when this host is on the
|
||||
mesh, on `wg-hive`.
|
||||
|
||||
⚠️ This exposes the queue beyond the tunnel. The server binds every
|
||||
address, so the firewall is the only thing this option changes. What
|
||||
protects the port is the queue itself: TLS is required, and
|
||||
`auth_callout` refuses every client it cannot identify. Whether that
|
||||
is enough to expose the queue is the operator's decision.
|
||||
|
||||
Point `nats.<swarm domain>` in the operator's upstream DNS at the
|
||||
address the other hives reach.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf deployCfg.nats.enable {
|
||||
|
|
@ -681,14 +703,18 @@ in
|
|||
# by the firewall and looks exactly like every other NATS failure,
|
||||
# a timeout.
|
||||
#
|
||||
# ⚠️ Never the world. What makes it safe to open at all is that the
|
||||
# queue is fail-closed: `auth_callout` admits nobody until the responder
|
||||
# above answers for them, so an agent that reaches this port still has to
|
||||
# present a token authelia vouches for.
|
||||
# ⚠️ The bridge only, unless `openFirewall` opts in. What makes it safe to
|
||||
# open at all is that the queue is fail-closed: `auth_callout` admits
|
||||
# nobody until the responder above answers for them, so a client that
|
||||
# reaches this port still has to present a token authelia vouches for.
|
||||
#
|
||||
# An agent reaches it by name, which dnsmasq answers with the bridge IP.
|
||||
services.hyperhive.network.exposeHostPorts = [ cfg.port ];
|
||||
|
||||
# The server binds every address (the container shares the host netns and
|
||||
# sets no listen host), so reachability is the firewall alone.
|
||||
networking.firewall.allowedTCPPorts = lib.mkIf deployCfg.nats.openFirewall [ cfg.port ];
|
||||
|
||||
# The bind source has to exist before the container starts, leaf or not:
|
||||
# nixos-container refuses to start over a missing one, which would take
|
||||
# the whole queue down rather than only its TLS.
|
||||
|
|
|
|||
Loading…
Reference in a new issue