Commit Graph

1313 Commits

Author SHA1 Message Date
pascal
2e2d0d54dc inject proxy policies on nmdata path 2026-08-19 15:47:59 +02:00
pascal
d3c9053b2f update tests 2026-08-19 12:25:29 +02:00
pascal
70c75bb94c Merge branch 'main' into revert/component-types 2026-08-18 18:42:18 +02:00
Maycon Santos
d5b283dca8 [management] Refuse a usage limit a one-off setup key cannot honour (#7220)
refuse creating one-off keys without limits set to 1
2026-08-18 18:36:42 +02:00
Dmitri Dolguikh
6ee0987cba updated GetNetworkMapData test to verify all calls -- policies, routes, etc
Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
2026-08-17 11:10:31 +02:00
Dmitri Dolguikh
6fdde1385f switch to mocks in network_map_data test
Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
2026-08-17 10:17:50 +02:00
Dmitri Dolguikh
7bc38d9b85 fix linter issue
Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
2026-08-14 16:54:15 +02:00
Dmitri Dolguikh
84e4b08056 added tests to cover GetNetworkMapData() call
Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
2026-08-14 16:45:33 +02:00
Dmitri Dolguikh
fdb956a974 Merge remote-tracking branch 'origin/main' into revert/component-types
Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
2026-08-13 16:30:08 +02:00
Dmitri Dolguikh
c6db3ad575 removed unused func
Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
2026-08-13 16:28:21 +02:00
Dmitri Dolguikh
cb4460d1d9 fix error name
Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
2026-08-13 16:11:31 +02:00
Dmitri Dolguikh
c004d09d77 fix a linter issue
Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
2026-08-13 15:45:30 +02:00
Dmitri Dolguikh
4aa123b6ad wired up sqlite store for use in networkmap controller
Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
2026-08-13 13:16:23 +02:00
pascal
931598e593 fix authorized user groups for ssh + fix ignoring disabled policies + fix ignore invalid router 2026-08-12 17:43:43 +02:00
pascal
460778abb9 add test harness and first tests 2026-08-11 17:34:43 +02:00
Dmitri Dolguikh
4be6603815 added comments re: ordering of fields in intermediate DTOs
Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
2026-08-11 16:47:39 +02:00
Dmitri Dolguikh
05511cc13d cleanup sqlite store creation
Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
2026-08-11 16:05:59 +02:00
Maycon Santos
f805c149d9 [management] Record reverse proxy usage for activity accounting (#7116)
People who only ever reach private services through the reverse proxy were
invisible to activity accounting. Active users are counted from user.LastLogin
or from the LastSeen of a peer they own, and neither column was written on the
proxy paths — so a person signing in via SSO to a proxied service, or a peer
serving one over the mesh, never showed up in the 24 hour numbers.
Both writes now happen where the proxy already authenticates:
- GenerateSessionToken stamps LastLogin after the session token is signed,
  the same column and the same way the dashboard and device login paths do.
- ValidateTunnelPeer stamps the calling peer's LastSeen, the column its owner
  activates through.
The policy lives in a new reverseproxy/activity manager rather than in the gRPC
service, matching the module layout the other reverse proxy domains use. It
skips what can never count — service users, embedded proxy peers and WASM
clients — and throttles peer writes to once an hour, well inside the window
accounting asks about and far above the proxy's five minute tunnel cache.
The peer write is a single indexed UPDATE that touches only
peer_status_last_seen. Connected and SessionStartedAt are left alone so the
session-ownership fencing MarkPeerConnectedIfNewerSession relies on is never
disturbed, and the timestamp comes from the database clock rather than the
caller, for the same reason the other status writers take it from there. The
caller's cutoff travels into the statement's WHERE, so concurrent requests for
one peer collapse into a single write instead of each acting on its own stale
read, and a peer that was never seen — NULL last seen, since Status is an
embedded pointer — still records its first activity.
Nothing outside the reverse proxy changes behaviour: the only addition
elsewhere is the RefreshPeerLastSeen store method the manager calls.
2026-08-11 15:54:39 +02:00
Dmitri Dolguikh
9427fa87e1 moved GetNetworkMapData implementation to NetworkMapDBStoreImpl
Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
2026-08-11 15:42:11 +02:00
Dmitri Dolguikh
fe5e5c08eb Merge remote-tracking branch 'origin/revert/component-types' into revert/component-types
Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
2026-08-11 14:52:14 +02:00
Dmitri Dolguikh
8cbbea4536 support for GetAllowedUsers in sqlite
Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
2026-08-11 14:46:59 +02:00
Dmitri Dolguikh
cd6f63272b support for GetPrivateServices in sqlite
Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
2026-08-11 14:25:39 +02:00
Dmitri Dolguikh
859af13c12 support for GetRoutes in sqlite
Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
2026-08-11 13:49:36 +02:00
Dmitri Dolguikh
4375fdc7b6 support for GetPostureChecks in sqlite
Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
2026-08-11 13:42:14 +02:00
Dmitri Dolguikh
1caa0ddf27 support for GetPolicies in sqlite
Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
2026-08-11 13:36:15 +02:00
pascal
cd2a91ddd8 fir error handling and return values (linter complaint) 2026-08-11 12:45:25 +02:00
pascal
38c5932375 merge main 2026-08-11 12:01:51 +02:00
Dmitri Dolguikh
fe9ea43198 support for GetPeers in sqlite
Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
2026-08-11 11:09:34 +02:00
Dmitri Dolguikh
fad568fdb0 support for GetNetworkXIDToPublicIdMap in sqlite
Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
2026-08-11 10:51:34 +02:00
Dmitri Dolguikh
3da27221ac support for GetNetwork in sqlite
Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
2026-08-11 10:43:00 +02:00
Dmitri Dolguikh
d954a2dc3e support for GetNetworkRouters in sqlite
Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
2026-08-10 20:10:41 +02:00
Brad Ison
27b2d3f351 [management] Add a proxy-connect authorizer seam (#7136)
At proxy connect time, the declared cluster address is validated for
shape and checked for availability (`IsClusterAddressAvailable`), and
from then on the declaration is what routes the cluster's mappings to
the connection. Deployments that embed management through the
integrations seam may need a policy on that claim — deciding which
credential is allowed to declare which address.

This adds an optional `ProxyConnectAuthorizer` hook on
`ProxyServiceServer`, following the pattern of the existing `Set*` seams
(`SetServiceManager`, `SetAgentNetworkSynthesizer`,
`SetAgentNetworkLimitsService`, `SetProxyController`):

- A nil-able interface field plus `SetProxyConnectAuthorizer`, guarded
by the existing mutex.
- One call at the end of `validateProxyConnect`, so both
`GetMappingUpdate` and `SyncMappings` are covered by a single site.
- **Nothing installs it by default** — with the hook unset (always, in
this repo), behavior is byte-for-byte unchanged, which the tests pin.

Design details:

- The authorizer runs **last** — after input validation and the
availability check — and **outside** the account-scoped branch, so
management-wide tokens and token-less connects are also presented to it
rather than bypassing policy.
- The authorizer receives the presented `*types.ProxyAccessToken` (nil
when none), the proxy ID, and the declared address. Everything it needs
is already in the request/context; no proto or schema change.
- A plain error from the authorizer surfaces as `PermissionDenied`,
keeping an authorization rejection distinguishable from the
`AlreadyExists` used for address conflicts in proxy logs. A status error
passes through unchanged so implementations can pick their own code.
2026-08-10 19:50:00 +02:00
Brad Ison
ebfdf7d7b8 [management] Rework Agent Network endpoint identity and settings bootstrap (#7085)
Store the per-account gateway endpoint as {domain, proxy_address} with a
global unique index on the full hostname; dedicated = (domain ==
proxy_address). Bootstrap becomes an explicit POST carrying exactly one
of proxy_address (server allocates an adjective-noun label beneath it)
or endpoint (claimed verbatim, address-first); provider create loses its
bootstrap side effect. PUT is a full replace with every field required —
the immutable identity fields must be echoed unchanged and a mismatch is
rejected with 422. A guarded DELETE releases the endpoint: refused with
412 while providers exist or a proxy is actively serving the endpoint
hostname (matched case-insensitively); re-creating bootstraps fresh. A
self-addressed pin excludes its address from the account's cluster allow
list, and the live mapping update path now addresses the serving proxy
from the synthesized service. Existing rows are migrated on all three
store engines.
2026-08-10 19:06:55 +02:00
Dmitri Dolguikh
433a4f12bf added support for GetNetworkResources in sqlite; moved several more internal types into shared_types
Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
2026-08-10 18:07:31 +02:00
Dmitri Dolguikh
3834e67a51 add support for GetNameServerGroups in sqlite
Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
2026-08-10 17:53:34 +02:00
Dmitri Dolguikh
78947c1611 support for GetGroups in sqlite
Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
2026-08-10 17:14:37 +02:00
Dmitri Dolguikh
763b8f6933 support for GetDomains in sqlite
Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
2026-08-10 15:55:24 +02:00
Dmitri Dolguikh
e530c25812 support for GetAppliedZoneCandidates in sqlite
Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
2026-08-10 14:59:03 +02:00
Dmitri Dolguikh
166b3d7739 moved test for RecordTypeAndRdata into the parent package
Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
2026-08-10 14:21:19 +02:00
Dmitri Dolguikh
20f18d1479 extracted struct-handling helpers into their own file; move sql_type_conversion_test to the parent module
Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
2026-08-10 14:15:11 +02:00
Dmitri Dolguikh
5594289924 Merge remote-tracking branch 'origin/revert/component-types' into revert/component-types
Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
2026-08-10 14:08:23 +02:00
Dmitri Dolguikh
a03635680b support for GetDnsSettings in sqlite store
Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
2026-08-10 14:07:52 +02:00
pascal
905e1c14ba add validated peers cache for nmdata 2026-08-10 14:02:06 +02:00
Dmitri Dolguikh
65f184141b added support for GetAccountSettings to sqlite store
Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
2026-08-10 13:31:55 +02:00
Maycon Santos
f65f7b347e [management] Deny reverse proxy access to pending and blocked users (#7105)
A user in the Pending Approval state could complete SSO and reach any
SSO-protected reverse proxy service distributed to a group they belong
to, including the All Users group. The reverse proxy authorization path
checked the session token signature, that the user exists, that the
user's account matches the service's account, and group membership —
never the user's account status. The REST API (`permissions/manager.go`)
and peer registration both gate on that state, but the proxy gRPC
service does not go through the permissions manager, so neither gate
applied. A pending user is persisted as blocked and pending approval, so
blocked users reached those services the same way.

`ValidateSession` now denies on account status, reporting
`pending_approval` or `user_blocked` so the proxy access log and the
denied page carry the cause rather than a generic refusal.
`GenerateSessionToken` refuses to mint a token for such a user at all,
so the browser never receives a session cookie and the OIDC callback can
tell the user why instead of showing "Service configuration error".
`ValidateUserGroupAccess` and `ValidateTunnelPeer` close the same gap;
for the tunnel path this covers a user blocked after their peer was
registered, since peer group membership alone kept mesh-origin access
open.

A single helper produces both the denied reason for the RPC responses
and the sentinel error for the error-returning callers, so the four
entry points cannot drift apart. A user the store cannot resolve is
denied rather than passed through.

One thing deliberately left out: session cookies are validated locally
by the proxy against the service public key with no management
round-trip, so a cookie issued before a user is blocked stays valid
until it expires (24h by default). That is a revocation-propagation
problem rather than this authorization gap, and every option for it
(per-request validation with a cache, short-lived tokens with refresh,
push-based revocation) changes the proxy hot path or the
proxy/management protocol. Worth its own ticket.
2026-08-08 20:48:34 +09:00
Dmitri Dolguikh
935d1c5863 move read-only queries to an interface to reuse in tests
Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
2026-08-07 19:23:52 +02:00
Pascal Fischer
2ee21d2b5c [management] Affected peers for user updates (#7099) 2026-08-07 18:07:53 +02:00
Pascal Fischer
524b8b9718 [management] prewarm a posture check cache on network map generation (#7093) 2026-08-07 15:03:40 +02:00
Dmitri Dolguikh
b19cf7405d Merge remote-tracking branch 'origin/revert/component-types' into revert/component-types
Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
2026-08-06 15:18:13 +02:00
Dmitri Dolguikh
90e0c5bd0c added GetPolicies test
Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>
2026-08-06 15:17:39 +02:00