mirror of
https://github.com/netbirdio/docs.git
synced 2026-08-26 17:51:27 +02:00
317 lines
14 KiB
Plaintext
317 lines
14 KiB
Plaintext
import { Note, Warning } from '@/components/mdx'
|
|
|
|
export const description =
|
|
'Connect applications and development tools to the local NetBird daemon through its gRPC socket.'
|
|
|
|
# gRPC Daemon Socket
|
|
|
|
The NetBird daemon exposes a local gRPC API that the NetBird CLI and desktop app use. Your integration can use the same socket to check status, manage the connection, inspect configuration, work with profiles and networks, and call other local daemon operations.
|
|
|
|
The gRPC socket is the primary local daemon API. If your integration cannot use gRPC or generated Protocol Buffer bindings, use the [HTTP/JSON daemon socket](/client/json-socket) instead.
|
|
|
|
<Note>
|
|
The gRPC socket controls the **local NetBird daemon**. It is separate from the
|
|
NetBird Management API and does not replace it.
|
|
</Note>
|
|
|
|
## Default Addresses
|
|
|
|
The HTTP/JSON gateway is optional. The gRPC socket is available whenever the NetBird daemon is running.
|
|
|
|
| Platform | Default address |
|
|
| --------------- | ------------------------------ |
|
|
| Linux and macOS | `unix:///var/run/netbird.sock` |
|
|
| Windows | `npipe://netbird` |
|
|
|
|
On Windows the daemon serves a named pipe. Which path that is depends on what the
|
|
daemon may create: running as a service or elevated it serves
|
|
`\\.\pipe\ProtectedPrefix\Administrators\netbird`, a namespace only administrators
|
|
can create in, and otherwise it falls back to `\\.\pipe\netbird`. Clients try both
|
|
and check who owns the pipe before using the plain name, so passing
|
|
`npipe://netbird` is enough. Windows installations that predate the named pipe are
|
|
migrated from `tcp://127.0.0.1:41731` automatically.
|
|
|
|
<Warning>
|
|
**Security warning:** The default Unix socket allows read and write access for
|
|
local users, so any local user can read status and configuration and perform
|
|
operations that do not require privileges. Operations that decide who may
|
|
obtain a shell on the machine are refused unless the caller is root, or an
|
|
administrator on Windows: see [Privileged
|
|
operations](#privileged-operations). If you require local-user isolation
|
|
beyond that, place a custom socket inside a restricted directory and ensure
|
|
that the directory is recreated securely at boot.
|
|
</Warning>
|
|
|
|
On Linux installations that use an instance-specific systemd service, the socket can instead be under `/var/run/netbird/<instance>.sock`. The NetBird CLI automatically uses the only socket in that directory when the default socket does not exist. If multiple instance sockets exist, pass the intended address explicitly with `--daemon-addr`.
|
|
|
|
You can see the address option in the CLI help:
|
|
|
|
```shell
|
|
netbird --help
|
|
```
|
|
|
|
## Configure the Address
|
|
|
|
Use the global `--daemon-addr` option when installing or reconfiguring the service. The address must use one of these formats:
|
|
|
|
```text
|
|
unix:///path/to/netbird.sock
|
|
tcp://host:port
|
|
npipe://name
|
|
```
|
|
|
|
<Warning>
|
|
**Connectivity warning:** Reconfiguring the service restarts NetBird and can
|
|
briefly interrupt tunnel connectivity, routes, and DNS.
|
|
</Warning>
|
|
|
|
### Use a Custom Unix Socket
|
|
|
|
```shell
|
|
sudo netbird service reconfigure \
|
|
--daemon-addr unix:///var/run/netbird-integration-grpc.sock
|
|
```
|
|
|
|
The parent directory must already exist and be writable by the NetBird service. If you use a dedicated directory to restrict access, configure systemd or tmpfiles to recreate it securely because directories under `/run` do not persist across reboots.
|
|
|
|
After changing the socket, pass the same address to NetBird CLI commands that need to contact the daemon:
|
|
|
|
```shell
|
|
netbird --daemon-addr unix:///var/run/netbird-integration-grpc.sock status
|
|
```
|
|
|
|
<Note>
|
|
This `--daemon-addr` command only works after configuring the custom gRPC
|
|
listener above. If the daemon uses its default listener, run `netbird status`
|
|
instead. Do not pass an HTTP/JSON socket to `--daemon-addr`.
|
|
</Note>
|
|
|
|
### Use a TCP Socket
|
|
|
|
```shell
|
|
sudo netbird service reconfigure \
|
|
--daemon-addr tcp://127.0.0.1:41731
|
|
```
|
|
|
|
Then specify that address when using the CLI on platforms where it is not the default:
|
|
|
|
```shell
|
|
netbird --daemon-addr tcp://127.0.0.1:41731 status
|
|
```
|
|
|
|
<Warning>
|
|
**Security warning:** The daemon gRPC server does not add authentication or
|
|
TLS. Keep TCP listeners bound to a trusted interface such as `127.0.0.1` and
|
|
do not expose them to an untrusted network. The API includes operations that
|
|
can read or change the local NetBird daemon's state.
|
|
|
|
A TCP connection also carries no caller identity, so the daemon cannot tell
|
|
who is calling and refuses every [privileged
|
|
operation](#privileged-operations) on that socket, whoever runs the client.
|
|
Use a Unix socket, or `npipe://` on Windows, if your integration needs them.
|
|
</Warning>
|
|
|
|
## Privileged Operations
|
|
|
|
On the default sockets any local user can connect, so the daemon authorizes operations
|
|
by the identity of whoever calls it, read from the kernel rather than supplied by
|
|
the client: `SO_PEERCRED` on Linux, `LOCAL_PEERCRED` on macOS, and the named-pipe
|
|
client token on Windows. A caller whose identity cannot be established is refused.
|
|
|
|
Since 0.76.0 the following require root, or an administrator on Windows, because
|
|
they decide who may obtain a shell on the machine:
|
|
|
|
| Change | Refused when |
|
|
| --- | --- |
|
|
| Enable the NetBird SSH server | the caller is not privileged |
|
|
| Enable SSH root login | the caller is not privileged |
|
|
| Disable SSH authentication | the caller is not privileged |
|
|
| Change the management URL | the caller is not privileged and that profile has the SSH server enabled |
|
|
| Deregister the peer (logout) | the caller is not privileged and that profile has the SSH server enabled |
|
|
|
|
Only the direction that creates the capability is guarded. Turning the SSH server or
|
|
root login off, and re-enabling SSH authentication, are always allowed, and restating a
|
|
value that is already set is not a change, so an integration that submits a whole
|
|
settings form does not start failing once an administrator enables SSH.
|
|
|
|
Removing a profile is not refused. An unprivileged caller removes it locally and the
|
|
daemon skips the deregistration, which leaves the peer registered on the management
|
|
server rather than detached from it.
|
|
|
|
A profile written before the SSH server flag existed counts as having it enabled,
|
|
because the daemon reads an unset flag the same way the engine does. The management URL
|
|
and deregistration guards therefore apply on those installations even though nobody
|
|
enabled SSH explicitly.
|
|
|
|
A refusal comes back as gRPC `PermissionDenied` carrying a `google.rpc.ErrorInfo`
|
|
detail, so an integration can recognise it without parsing the message:
|
|
|
|
```text
|
|
reason: PRIVILEGE_REQUIRED
|
|
domain: daemon.netbird.io
|
|
metadata: summary = "Enabling the NetBird SSH server requires root."
|
|
command = "sudo netbird down; sudo netbird up --allow-server-ssh"
|
|
```
|
|
|
|
Render `summary` and `command` rather than the raw error: `command` is the same
|
|
operation with the privileges it needs, ready to run.
|
|
|
|
<Note>
|
|
When the daemon itself runs unprivileged, as in a rootless container or on
|
|
Windows in netstack mode, a caller running as the daemon's own user is treated
|
|
as privileged. Such a caller can already rewrite the configuration the daemon
|
|
reads, so refusing it would protect nothing.
|
|
</Note>
|
|
|
|
## Service Definition
|
|
|
|
The socket provides `daemon.DaemonService`. NetBird's
|
|
[`client/proto/daemon.proto`](https://github.com/netbirdio/netbird/blob/main/client/proto/daemon.proto)
|
|
file lists the available methods, streaming types, and request and response schemas.
|
|
|
|
Here are a few common methods. Check `daemon.proto` for the full list.
|
|
|
|
| Method | Type | Purpose |
|
|
| ----------------- | ---------------- | --------------------------------------------------------- |
|
|
| `Status` | Unary | Read connection status and peer information. |
|
|
| `SubscribeStatus` | Server streaming | Receive the current status and subsequent status changes. |
|
|
| `GetConfig` | Unary | Read the active daemon configuration. |
|
|
| `ListNetworks` | Unary | List networks available to the client. |
|
|
| `Up` | Unary | Start the NetBird connection. |
|
|
| `Down` | Unary | Stop the NetBird connection. |
|
|
| `ListProfiles` | Unary | List configured client profiles. |
|
|
| `SubscribeEvents` | Server streaming | Receive daemon system events. |
|
|
|
|
The service also includes methods that change configuration, profiles, network selection, logging, and other daemon state. Only give socket access to processes that you trust to control the local NetBird client.
|
|
|
|
<Note>
|
|
The daemon does not enable gRPC server reflection. Tools and integrations must
|
|
use `daemon.proto`, generated client bindings, or a compiled descriptor set to
|
|
learn the service schema.
|
|
</Note>
|
|
|
|
## Test the Socket with grpcurl
|
|
|
|
[`grpcurl`](https://github.com/fullstorydev/grpcurl) is a command-line tool for invoking gRPC methods. Because it needs access to the `.proto` files to perform requests, we need to download the repository at the same version that the daemon to not have a mismatch on the Protocol Buffer definition.
|
|
|
|
```shell
|
|
export NETBIRD_VERSION=v$(netbird version)
|
|
git clone --depth 1 \
|
|
--branch "$NETBIRD_VERSION" \
|
|
https://github.com/netbirdio/netbird.git
|
|
cd netbird
|
|
```
|
|
|
|
Run the following examples from the root of the cloned `netbird` repository.
|
|
|
|
### Query Status Through the Unix Socket
|
|
|
|
```shell
|
|
grpcurl \
|
|
-plaintext \
|
|
-unix \
|
|
-import-path ./client/proto \
|
|
-proto daemon.proto \
|
|
-d '{}' \
|
|
unix:///var/run/netbird.sock \
|
|
daemon.DaemonService/Status
|
|
```
|
|
|
|
To request full peer status, set fields from `StatusRequest` in the JSON request body:
|
|
|
|
**Sensitive output:** Full peer status may contain network topology, endpoint, route, and peer information. Review or redact it before sharing the output.
|
|
|
|
```shell
|
|
grpcurl \
|
|
-plaintext \
|
|
-unix \
|
|
-import-path ./client/proto \
|
|
-proto daemon.proto \
|
|
-d '{"getFullPeerStatus": true}' \
|
|
unix:///var/run/netbird.sock \
|
|
daemon.DaemonService/Status
|
|
```
|
|
|
|
### Query Status Through a TCP Socket
|
|
|
|
This applies to a custom loopback TCP listener, since `grpcurl` cannot dial a
|
|
Windows named pipe and the Windows default is therefore not reachable this way. Use
|
|
a client that can open the pipe, or configure a TCP listener for testing and accept
|
|
that [privileged operations](#privileged-operations) are refused on it:
|
|
|
|
```shell
|
|
grpcurl \
|
|
-plaintext \
|
|
-import-path ./client/proto \
|
|
-proto daemon.proto \
|
|
-d '{}' \
|
|
127.0.0.1:41731 \
|
|
daemon.DaemonService/Status
|
|
```
|
|
|
|
`-plaintext` is required because the local daemon socket does not use TLS. For a Unix socket, pass the full `unix:///...` URI and include `-unix`. The URI form also avoids a Unix-socket regression in some `grpcurl` 1.9.x builds.
|
|
|
|
### Subscribe to Status Changes
|
|
|
|
Server-streaming methods remain connected and print each response as it arrives. For example:
|
|
|
|
```shell
|
|
grpcurl \
|
|
-plaintext \
|
|
-unix \
|
|
-import-path ./client/proto \
|
|
-proto daemon.proto \
|
|
-d '{}' \
|
|
unix:///var/run/netbird.sock \
|
|
daemon.DaemonService/SubscribeStatus
|
|
```
|
|
|
|
Press `Ctrl+C` to end the stream.
|
|
|
|
## Build an Integration
|
|
|
|
For a long-running integration, generate a gRPC client from the same `daemon.proto` revision as the installed NetBird client:
|
|
|
|
1. Download or vendor `client/proto/daemon.proto` from the NetBird repository.
|
|
2. Generate client bindings with the Protocol Buffer and gRPC tools for your language.
|
|
3. Create a local gRPC channel to the configured Unix or TCP address without TLS. That does not make the socket safe to expose remotely.
|
|
4. Create a `daemon.DaemonService` client from that channel.
|
|
5. Call unary methods or consume server streams using the generated request and response types.
|
|
|
|
Use a protobuf definition and generated bindings that match your deployed NetBird version. A newer client may call methods or use fields that an older daemon does not support.
|
|
|
|
The HTTP/JSON gateway exposes this service for environments where generated gRPC clients are unavailable. See [HTTP/JSON Daemon Socket](/client/json-socket) for setup and HTTP examples.
|
|
|
|
## Troubleshooting
|
|
|
|
### The Unix Socket Does Not Exist
|
|
|
|
Check that the service is running:
|
|
|
|
```shell
|
|
sudo netbird service status
|
|
```
|
|
|
|
If you use an instance-specific service, inspect `/var/run/netbird/` for its socket or pass the configured address with `--daemon-addr`.
|
|
|
|
### A Tool Reports That Reflection Is Unsupported
|
|
|
|
This is expected. Supply `daemon.proto` with your tool's equivalent of the `grpcurl -proto` and `-import-path` options, or use a descriptor set generated from that file.
|
|
|
|
### A Client Receives an Unavailable or Connection-Refused Error
|
|
|
|
Confirm that the daemon is running and that the integration uses the same socket address as the service. For a Unix socket, also verify access to the socket and each parent directory. For TCP, verify the host and port and ensure the listener remains bound to a trusted interface.
|
|
|
|
### A Call Is Refused With PermissionDenied
|
|
|
|
The operation is one of the [privileged operations](#privileged-operations) and the
|
|
caller is not root, or not an administrator on Windows. Check the `ErrorInfo` detail
|
|
on the error: `PRIVILEGE_REQUIRED` in domain `daemon.netbird.io` means the daemon
|
|
identified the caller and refused the change, rather than failing to reach it. On a
|
|
TCP socket every such operation is refused, because the transport carries no caller
|
|
identity.
|
|
|
|
### A Method or Field Is Unimplemented
|
|
|
|
The integration's generated bindings may be newer than the installed NetBird daemon. Compare the installed client version with the revision of `daemon.proto` used to generate the bindings, then use a compatible schema or upgrade NetBird.
|