Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 104 additions & 1 deletion netbird/DOCS.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,12 @@ comparison to installing any other Home Assistant add-on.

## Configuration

You'll see the config file at `/addon_config/*_netbird/config.json` after first boot.
After the first boot you'll see the NetBird configuration in this add-on's own
configuration directory: `/config` as seen from inside the add-on, which Home
Assistant exposes to you as `/addon_configs/xxxxxxxx_netbird`, where
`xxxxxxxx_netbird` is the slug of your installation (visible in the address bar
when the add-on page is open). It holds `config.json`, plus a `profiles`
directory if you use the [`profile`](#option-profile) option.

### Option: `log_level`

Expand Down Expand Up @@ -75,6 +80,28 @@ Hostname in the NetBird network (used to during registration)

This hostname will be used in the Peers to identify your machine.

### Option: `profile`

Name of the profile to connect with (default: the single, unnamed profile)

A profile is a separate NetBird configuration: each one keeps its own peer
identity and credentials, so switching the profile makes this client join a
different NetBird network or account. Leave the option empty to keep using the
single default configuration at `config.json`; set it to a name and the client
uses `profiles/<name>.json` instead. Both paths are relative to the add-on
configuration directory described under [Configuration](#configuration).

A name may be up to 64 characters of letters, digits, `-` and `_`. The name
`null` is not allowed, because the add-on cannot tell it apart from an unset
option.

A profile that has not been registered yet needs a `setup_key`, or the login URL
printed in the log, the first time it starts. Once registered, a profile keeps
working when you switch away and back again.

See [Switching profiles from Home Assistant](#switching-profiles-from-home-assistant)
for changing profiles from an automation.

### Option: `rosenpass`

Rosenpass can be enabled by setting a flag on client start-up.
Expand All @@ -97,6 +124,82 @@ Extra environment variables to pass to the NetBird client.
This is a list of environment variables that will be passed to the NetBird client.
You can use this to configure the client further.

## Switching profiles from Home Assistant

Home Assistant can switch profiles by changing the `profile` option and
restarting the add-on. Add the following to `configuration.yaml`, replacing
`xxxxxxxx_netbird` with the slug of your installation (visible in the address bar
when the add-on page is open):

```yaml
rest_command:
netbird_info:
url: http://supervisor/addons/xxxxxxxx_netbird/info
method: get
headers:
x-supervisor-token: !env_var SUPERVISOR_TOKEN
netbird_set_options:
url: http://supervisor/addons/xxxxxxxx_netbird/options
method: post
content_type: application/json
headers:
x-supervisor-token: !env_var SUPERVISOR_TOKEN
payload: '{{ {"options": options} | to_json }}'
netbird_restart:
url: http://supervisor/addons/xxxxxxxx_netbird/restart
method: post
headers:
x-supervisor-token: !env_var SUPERVISOR_TOKEN

script:
netbird_switch_profile:
alias: Switch NetBird profile
fields:
profile:
description: Profile to connect with, or empty for the default profile.
example: work
sequence:
- action: rest_command.netbird_info
response_variable: info
- condition: template
value_template: "{{ info.status == 200 }}"
- action: rest_command.netbird_set_options
response_variable: updated
data:
options: "{{ info.content.data.options | combine({'profile': profile}) }}"
Comment thread
coderabbitai[bot] marked this conversation as resolved.
- condition: template
value_template: "{{ updated.status == 200 }}"
- action: rest_command.netbird_restart
Comment thread
coderabbitai[bot] marked this conversation as resolved.
```

Then call `script.netbird_switch_profile` with the profile you want:

```yaml
action: script.netbird_switch_profile
data:
profile: work
```

Keep the `netbird_info` step. The Supervisor **replaces** the stored options with
whatever is posted, so sending only the profile would reset every other option
(including your `setup_key`) to its default. Reading the current options first
and merging the new profile into them avoids that.

Keep the two `condition` steps as well. A `rest_command` that gets an error
response logs a warning but does not fail the script, so without them a rejected
options update would still be followed by a restart, quietly bringing the add-on
back up on the *old* profile. With them, the script stops instead and the add-on
keeps running untouched.

Because the whole options map has to be posted back, the payload contains your
`setup_key`. Home Assistant logs that payload at warning level whenever one of
these calls fails, and logs the payload and headers (including the Supervisor
token) if you set `homeassistant.components.rest_command` to `debug`. Treat
those logs as secrets, and scrub them before sharing them.

Switching restarts the add-on, so the connection drops for a few seconds and all
peers see the machine go offline and come back under its new identity.

## Changelog & Releases

This repository keeps a change log using [GitHub's releases][releases]
Expand Down
2 changes: 2 additions & 0 deletions netbird/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ options:
management_url: ""
setup_key: ""
hostname: ""
profile: ""
rosenpass: false
rosenpass_permissive: false
env_vars: []
Expand All @@ -35,6 +36,7 @@ schema:
management_url: str?
setup_key: str?
hostname: match(^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?)*)?$)?
profile: match(^(?!null$)([a-zA-Z0-9_-]{1,64})?$)?
rosenpass: bool
rosenpass_permissive: bool
env_vars:
Expand Down
40 changes: 37 additions & 3 deletions netbird/rootfs/etc/s6-overlay/s6-rc.d/netbird/run
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,52 @@ declare value

# Get the options configured in HASS GUI
readonly CONFIG_OLD_PATH=/homeassistant/netbird/config.json
readonly CONFIG_PATH=/config/config.json

[ -f "${CONFIG_OLD_PATH}" ] && mv "${CONFIG_OLD_PATH}" "${CONFIG_PATH}"
readonly CONFIG_DEFAULT_PATH=/config/config.json
readonly PROFILES_DIR=/config/profiles

# Migrate the config from the pre-addon_config location, but never on top of an
# existing one: that would discard the current peer identity and credentials.
if [ -f "${CONFIG_OLD_PATH}" ]; then
if [ -f "${CONFIG_DEFAULT_PATH}" ]; then
bashio::log.warning "Ignoring ${CONFIG_OLD_PATH}: ${CONFIG_DEFAULT_PATH} already exists"
elif ! mv "${CONFIG_OLD_PATH}" "${CONFIG_DEFAULT_PATH}"; then
bashio::exit.nok "Could not migrate ${CONFIG_OLD_PATH} to ${CONFIG_DEFAULT_PATH}"
fi
fi

admin_url="$(bashio::config 'admin_url')"
management_url="$(bashio::config 'management_url')"
setup_key="$(bashio::config 'setup_key')"
hostname="$(bashio::config 'hostname')"
profile="$(bashio::config 'profile')"
rosenpass="$(bashio::config 'rosenpass')"
rosenpass_permissive="$(bashio::config 'rosenpass_permissive')"
log_level="$(bashio::config 'log_level')"

# Select the profile to run (see issue #423).
# A NetBird profile is simply its own config file: each one holds a separate
# peer identity, management URL and credentials, so pointing the client at a
# different config file switches the whole account/network it joins. Leaving
# the option empty keeps using the single default config, so existing installs
# are unaffected.
# bashio prints "null" for an option that is not set, and cannot tell that
# apart from the literal string; the schema rejects "null" as a profile name so
# the two can never collide here.
if [ "${profile}" = "" ] || [ "${profile}" = "null" ]; then
bashio::log.info "No profile set, using the default profile"
CONFIG_PATH="${CONFIG_DEFAULT_PATH}"
else
# The profile name becomes part of a file path, so re-validate it here
# instead of relying on the options schema alone.
if [[ ! "${profile}" =~ ^[a-zA-Z0-9_-]{1,64}$ ]]; then
bashio::exit.nok "Invalid profile name: ${profile} (allowed: letters, digits, '-' and '_', up to 64 characters)"
fi
bashio::log.info "Using ${profile} as profile"
mkdir -p "${PROFILES_DIR}"
CONFIG_PATH="${PROFILES_DIR}/${profile}.json"
fi
readonly CONFIG_PATH

# Self-heal a stale NetBird Cloud management URL (see issue #401).
# Older installs persisted https://app.netbird.io as the Management URL in
# config.json. app.netbird.io only serves the web dashboard and does not
Expand Down
14 changes: 14 additions & 0 deletions netbird/translations/en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,20 @@ configuration:
description: >-
Hostname of the client (default "netbird-client")
This is the name of the client that will be displayed in the NetBird dashboard.
profile:
name: Profile
description: >-
Name of the profile to connect with (default: the single, unnamed profile)

Every profile keeps its own peer identity and credentials in its own
configuration file, so switching the profile makes the add-on join a
different NetBird network or account. Changing this option and restarting
the add-on switches profiles, which also lets Home Assistant automations
switch networks. A profile that has not been registered yet needs a
`setup_key`, or the login URL printed in the log, on its first start.

Up to 64 characters of letters, digits, `-` and `_`. The name `null` is
not allowed, as it cannot be told apart from an unset option.
rosenpass:
name: Rosenpass
description: >-
Expand Down
Loading