* Add mesh prerequisite gate (NetBird verification before app config) Implements the design in docs/mesh-prerequisite-gate.md per the user's DECIDE A-D answers: a permanent admin override, B1 (reachable) verification with host mesh IP shown informationally, members allowed in with a notice instead of being blocked, and mesh.required defaulting off so the live production instance is unaffected. - system_config kv table + getConfig/setConfig helpers - /api/system/mesh-status, /mesh/verify, /mesh/override, /mesh/required - AuthContext gains a 'needs-mesh' status (admins only) and exposes meshStatus for a member-facing banner - MeshGate page reuses the integration create+test flow to connect NetBird * Make mesh verification universal (CIDR check, not NetBird-specific) Replace the NetBird-adapter-based "reachable" check with a vendor-agnostic one: the admin supplies the mesh's IP range (CIDR), and verification just confirms this host has an address inside it. Works identically for NetBird, WireGuard, ZeroTier, Tailscale, or any other mesh tech, with no integration record or vendor API call required. * Add reachability fallback for routed meshes (VPC peering, etc.) A host can be on the mesh's "side" of a routed network (e.g. a VPC peered into a NetBird/WireGuard mesh) without holding a local IP in the mesh's own CIDR. Local-IP-in-CIDR stays the primary check; if it fails, the admin can supply a known peer/gateway IP on the mesh and we verify by pinging it instead. Adds iputils to the backend image for the ping binary. --------- Co-authored-by: Claude <noreply@anthropic.com>
43 lines
1.6 KiB
Docker
43 lines
1.6 KiB
Docker
FROM node:22-alpine AS build
|
|
WORKDIR /app
|
|
# Native modules (better-sqlite3, ssh2, node-pty) need a toolchain to compile.
|
|
RUN apk add --no-cache python3 make g++
|
|
COPY package.json package-lock.json* ./
|
|
RUN npm install --omit=dev=false
|
|
COPY . .
|
|
RUN npm run build
|
|
|
|
FROM node:22-alpine
|
|
WORKDIR /app
|
|
ENV NODE_ENV=production
|
|
# Toolchain is needed again here: production deps are reinstalled fresh, and the
|
|
# native modules (better-sqlite3, ssh2, node-pty) compile from source on install.
|
|
# openssh-client provides the `ssh` binary, which node-pty shells out to for
|
|
# certificate-based auth (ssh2 has no OpenSSH certificate support).
|
|
# iputils provides `ping`, used by the mesh-gate reachability check.
|
|
RUN apk add --no-cache python3 make g++ openssh-client iputils
|
|
COPY package.json package-lock.json* ./
|
|
RUN npm install --omit=dev
|
|
COPY --from=build /app/dist ./dist
|
|
# Old-format encrypted PEM keys (e.g. "BEGIN RSA PRIVATE KEY" + DEK-Info) rely on an
|
|
# MD5-based KDF that OpenSSL 3's default provider disables. Enable the legacy provider
|
|
# so `ssh` (used for certificate-based auth) can still decrypt these keys.
|
|
RUN { \
|
|
echo 'openssl_conf = openssl_init'; \
|
|
echo ''; \
|
|
echo '[openssl_init]'; \
|
|
echo 'providers = provider_sect'; \
|
|
echo ''; \
|
|
echo '[provider_sect]'; \
|
|
echo 'default = default_sect'; \
|
|
echo 'legacy = legacy_sect'; \
|
|
echo ''; \
|
|
echo '[default_sect]'; \
|
|
echo 'activate = 1'; \
|
|
echo ''; \
|
|
echo '[legacy_sect]'; \
|
|
echo 'activate = 1'; \
|
|
} > /etc/ssl/openssl-legacy.cnf
|
|
ENV OPENSSL_CONF=/etc/ssl/openssl-legacy.cnf
|
|
EXPOSE 4000
|
|
CMD ["node", "dist/server.js"]
|