WIP: netbird
This commit is contained in:
parent
86593e3b7d
commit
03e0b54183
|
@ -57,4 +57,6 @@
|
||||||
nixpkgs.config.permittedInsecurePackages = lib.trace "remove when possible" [
|
nixpkgs.config.permittedInsecurePackages = lib.trace "remove when possible" [
|
||||||
"nix-2.16.2"
|
"nix-2.16.2"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
services.netbird.enable = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
apispotify = "apisptfy";
|
apispotify = "apisptfy";
|
||||||
kanidm = "auth";
|
kanidm = "auth";
|
||||||
oauth2-proxy = "oauth2";
|
oauth2-proxy = "oauth2";
|
||||||
|
netbird = "netbird";
|
||||||
};
|
};
|
||||||
in "${domains.${hostName}}.${config.secrets.secrets.global.domains.web}";
|
in "${domains.${hostName}}.${config.secrets.secrets.global.domains.web}";
|
||||||
# TODO hard coded elisabeth nicht so schön
|
# TODO hard coded elisabeth nicht so schön
|
||||||
|
@ -61,6 +62,49 @@ in {
|
||||||
{
|
{
|
||||||
enable = true;
|
enable = true;
|
||||||
recommendedSetup = true;
|
recommendedSetup = true;
|
||||||
|
upstreams.netbird = {
|
||||||
|
servers."${ipOf "netbird"}:80" = {};
|
||||||
|
extraConfig = ''
|
||||||
|
zone netbird 64k ;
|
||||||
|
keepalive 5 ;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
upstreams.netbird-mgmt = {
|
||||||
|
servers."${ipOf "netbird"}:3000" = {};
|
||||||
|
extraConfig = ''
|
||||||
|
zone netbird 64k ;
|
||||||
|
keepalive 5 ;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
virtualHosts.${domainOf "netbird"} = {
|
||||||
|
forceSSL = true;
|
||||||
|
useACMEHost = "web";
|
||||||
|
locations = {
|
||||||
|
"/" = {
|
||||||
|
proxyPass = "http://netbird";
|
||||||
|
proxyWebsockets = true;
|
||||||
|
X-Frame-Options = "SAMEORIGIN";
|
||||||
|
};
|
||||||
|
"/signalexchange.SignalExchange/".extraConfig = ''
|
||||||
|
grpc_pass grpc://${ipOf "netbird"}:3001;
|
||||||
|
grpc_read_timeout 1d;
|
||||||
|
grpc_send_timeout 1d;
|
||||||
|
grpc_socket_keepalive on;
|
||||||
|
'';
|
||||||
|
|
||||||
|
"/api".proxyPass = "http://netbird-mgmt";
|
||||||
|
|
||||||
|
"/management.ManagementService/".extraConfig = ''
|
||||||
|
grpc_pass grpc://${ipOf "netbird"}:3000;
|
||||||
|
grpc_read_timeout 1d;
|
||||||
|
grpc_send_timeout 1d;
|
||||||
|
grpc_socket_keepalive on;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
extraConfig = ''
|
||||||
|
client_max_body_size 500M ;
|
||||||
|
'';
|
||||||
|
};
|
||||||
}
|
}
|
||||||
(blockOf "vaultwarden" {maxBodySize = "1G";})
|
(blockOf "vaultwarden" {maxBodySize = "1G";})
|
||||||
(blockOf "forgejo" {maxBodySize = "1G";})
|
(blockOf "forgejo" {maxBodySize = "1G";})
|
||||||
|
@ -154,7 +198,7 @@ in {
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
(blockOf "paperless" {maxBodySize = "5G";})
|
(blockOf "paperless" {maxBodySize = "5G";})
|
||||||
(blockOf "ttrss" {port = 80;})
|
#(blockOf "ttrss" {port = 80;})
|
||||||
(blockOf "yourspotify" {port = 80;})
|
(blockOf "yourspotify" {port = 80;})
|
||||||
(blockOf "apispotify" {
|
(blockOf "apispotify" {
|
||||||
port = 80;
|
port = 80;
|
||||||
|
@ -262,8 +306,9 @@ in {
|
||||||
// mkContainer "vaultwarden" {}
|
// mkContainer "vaultwarden" {}
|
||||||
// mkContainer "ddclient" {}
|
// mkContainer "ddclient" {}
|
||||||
// mkContainer "ollama" {}
|
// mkContainer "ollama" {}
|
||||||
// mkContainer "ttrss" {}
|
#// mkContainer "ttrss" {}
|
||||||
// mkContainer "yourspotify" {}
|
// mkContainer "yourspotify" {}
|
||||||
|
// mkContainer "netbird" {}
|
||||||
// mkContainer "kanidm" {}
|
// mkContainer "kanidm" {}
|
||||||
// mkContainer "nextcloud" {
|
// mkContainer "nextcloud" {
|
||||||
enablePanzer = true;
|
enablePanzer = true;
|
||||||
|
|
Binary file not shown.
1
hosts/elisabeth/secrets/netbird/host.pub
Normal file
1
hosts/elisabeth/secrets/netbird/host.pub
Normal file
|
@ -0,0 +1 @@
|
||||||
|
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIF0+o9G3hA/5PbaxVy+EoOOJw5cHKu3p5yjAaHDHFQ8Q
|
107
modules/netbird-dashboard.nix
Normal file
107
modules/netbird-dashboard.nix
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
inherit
|
||||||
|
(lib)
|
||||||
|
mkPackageOption
|
||||||
|
mkIf
|
||||||
|
mkEnableOption
|
||||||
|
mkOption
|
||||||
|
types
|
||||||
|
isBool
|
||||||
|
boolToString
|
||||||
|
;
|
||||||
|
|
||||||
|
toStringEnv = value:
|
||||||
|
if isBool value
|
||||||
|
then boolToString value
|
||||||
|
else toString value;
|
||||||
|
cfg = config.services.netbird-dashboard;
|
||||||
|
in {
|
||||||
|
options.services.netbird-dashboard = {
|
||||||
|
enable = mkEnableOption "the static netbird dashboard frontend";
|
||||||
|
package = mkPackageOption pkgs "netbird-dashboard" {};
|
||||||
|
enableNginx = mkEnableOption "Nginx as a webserver serving the backend";
|
||||||
|
domain = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "The domain under which the dashboard runs.";
|
||||||
|
default = "localhost";
|
||||||
|
};
|
||||||
|
settings = mkOption {
|
||||||
|
type = types.submodule {
|
||||||
|
freeformType = types.attrsOf (types.oneOf [types.str types.bool]);
|
||||||
|
config = {
|
||||||
|
#AUTH_AUTHORITY = ""; #${AUTH_AUTHORITY:-https://$AUTH0_DOMAIN}
|
||||||
|
#AUTH_CLIENT_ID = ""; #${AUTH_CLIENT_ID:-$AUTH0_CLIENT_ID}
|
||||||
|
# Due to how the backend and frontend work this secret will be templated into the backend
|
||||||
|
# and then served statically from your website
|
||||||
|
# This enables you to login without the normally needed indirection through the backend
|
||||||
|
# but this also means anyone that can reach your website can
|
||||||
|
# fetch this secret, which is why there is no real need to put it into
|
||||||
|
# special options as its public anyway
|
||||||
|
# As far as I know leaking this secret is just
|
||||||
|
# an information leak as one can fetch some basic app
|
||||||
|
# informations from the IDP
|
||||||
|
# To actually do something one still needs to have login
|
||||||
|
# data and this secret so this being public will not
|
||||||
|
# suffice for anything just decreasing security
|
||||||
|
AUTH_CLIENT_SECRET = ""; #${AUTH_CLIENT_SECRET}
|
||||||
|
AUTH_AUDIENCE = "netbird"; #${AUTH_AUDIENCE:-$AUTH0_AUDIENCE}
|
||||||
|
#AUTH_REDIRECT_URI=${AUTH_REDIRECT_URI}
|
||||||
|
#AUTH_SILENT_REDIRECT_URI=${AUTH_SILENT_REDIRECT_URI}
|
||||||
|
USE_AUTH0 = false; #${USE_AUTH0:-true}
|
||||||
|
AUTH_SUPPORTED_SCOPES = "openid profile email"; #${AUTH_SUPPORTED_SCOPES:-openid profile email api offline_access email_verified}
|
||||||
|
|
||||||
|
NETBIRD_MGMT_API_ENDPOINT = config.services.netbird-server.domain; #$(echo $NETBIRD_MGMT_API_ENDPOINT | sed -E 's/(:80|:443)$//')
|
||||||
|
NETBIRD_MGMT_GRPC_API_ENDPOINT = config.services.netbird-server.domain; #${NETBIRD_MGMT_GRPC_API_ENDPOINT}
|
||||||
|
#NETBIRD_HOTJAR_TRACK_ID=${NETBIRD_HOTJAR_TRACK_ID}
|
||||||
|
#NETBIRD_GOOGLE_ANALYTICS_ID=${NETBIRD_GOOGLE_ANALYTICS_ID}
|
||||||
|
NETBIRD_TOKEN_SOURCE = "idToken";
|
||||||
|
#NETBIRD_DRAG_QUERY_PARAMS=${NETBIRD_DRAG_QUERY_PARAMS:-false}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = let
|
||||||
|
deriv = pkgs.runCommand "template-netbird-dashboard" {} ''
|
||||||
|
cp -r ${cfg.package} ./temp
|
||||||
|
|
||||||
|
|
||||||
|
${
|
||||||
|
lib.concatStringsSep "\n" (lib.mapAttrsToList (name: value: ''export "${name}"="${toStringEnv value}"'') cfg.settings)
|
||||||
|
}
|
||||||
|
|
||||||
|
# replace ENVs in the config
|
||||||
|
ENV_STR="\$\$USE_AUTH0 \$\$AUTH_AUDIENCE \$\$AUTH_AUTHORITY \$\$AUTH_CLIENT_ID \$\$AUTH_CLIENT_SECRET \$\$AUTH_SUPPORTED_SCOPES \$\$NETBIRD_MGMT_API_ENDPOINT \$\$NETBIRD_MGMT_GRPC_API_ENDPOINT \$\$NETBIRD_HOTJAR_TRACK_ID \$\$NETBIRD_GOOGLE_ANALYTICS_ID \$\$AUTH_REDIRECT_URI \$\$AUTH_SILENT_REDIRECT_URI \$\$NETBIRD_TOKEN_SOURCE \$\$NETBIRD_DRAG_QUERY_PARAMS"
|
||||||
|
|
||||||
|
find temp -type d -exec chmod 755 {} \;
|
||||||
|
OIDC_TRUSTED_DOMAINS="./temp/OidcTrustedDomains.js"
|
||||||
|
${pkgs.gettext}/bin/envsubst "$ENV_STR" < "$OIDC_TRUSTED_DOMAINS".tmpl > "$OIDC_TRUSTED_DOMAINS"
|
||||||
|
for f in $(grep -R -l AUTH_SUPPORTED_SCOPES ./); do
|
||||||
|
${pkgs.gettext}/bin/envsubst "$ENV_STR" < "$f" > "$f".copy
|
||||||
|
mv -f "$f".copy "$f"
|
||||||
|
done
|
||||||
|
mkdir -p $out
|
||||||
|
cp -r ./temp/. $out/
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
mkIf cfg.enable
|
||||||
|
{
|
||||||
|
services.nginx = mkIf cfg.enableNginx {
|
||||||
|
enable = true;
|
||||||
|
virtualHosts = {
|
||||||
|
${cfg.domain} = {
|
||||||
|
locations = {
|
||||||
|
"/" = {
|
||||||
|
root = "${deriv}/";
|
||||||
|
tryFiles = "$uri /index.html";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -9,39 +9,54 @@
|
||||||
mkEnableOption
|
mkEnableOption
|
||||||
mkOption
|
mkOption
|
||||||
types
|
types
|
||||||
mkDefault
|
mkPackageOption
|
||||||
mkIf
|
mkIf
|
||||||
;
|
;
|
||||||
cfg = config.services.netbird;
|
cfg = config.services.netbird-server;
|
||||||
|
|
||||||
configFile = formatType.generate config.json cfg.settings;
|
configFile = formatType.generate "config.json" cfg.settings;
|
||||||
|
|
||||||
formatType = pkgs.format.json {};
|
formatType = pkgs.formats.json {};
|
||||||
in {
|
in {
|
||||||
options.services.netbird = {
|
options.services.netbird-server = {
|
||||||
enable = mkEnableOption "netbird, a self hosted wireguard VPN";
|
enable = mkEnableOption "netbird, a self hosted wireguard VPN";
|
||||||
|
package = mkPackageOption pkgs "netbird" {};
|
||||||
domain = mkOption {
|
domain = mkOption {
|
||||||
description = "The domain of your netbird instance";
|
description = "The domain of your netbird instance";
|
||||||
};
|
};
|
||||||
|
port = mkOption {
|
||||||
|
description = "The port the management interface will listen on";
|
||||||
|
type = types.port;
|
||||||
|
default = 3000;
|
||||||
|
};
|
||||||
oidcConfigEndpoint = mkOption {
|
oidcConfigEndpoint = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
example = "https://example.eu.auth0.com/.well-known/openid-configuration";
|
example = "https://example.eu.auth0.com/.well-known/openid-configuration";
|
||||||
description = "The oidc discovery endpoint";
|
description = "The oidc discovery endpoint";
|
||||||
};
|
};
|
||||||
dataDir = mkOption {
|
signalPort = mkOption {
|
||||||
description = "Runtime directory where netbird stores its data";
|
description = "The listening port for the signal protocol";
|
||||||
types = types.path;
|
default = 3001;
|
||||||
default = /var/lib/netbird;
|
type = types.port;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
singleAccountModeDomain = mkOption {
|
||||||
|
description = "Optional domain for single account mode, set to null to disable singleAccountMode";
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
default = "netbird.selfhosted";
|
||||||
|
example = null;
|
||||||
|
};
|
||||||
|
|
||||||
turn = {
|
turn = {
|
||||||
domain = mkOption {
|
domain = mkOption {
|
||||||
description = "The domain under which the TURN server is reachable";
|
description = "The domain under which the TURN server is reachable";
|
||||||
type = types.str;
|
type = types.str;
|
||||||
example = "localhost";
|
example = "localhost";
|
||||||
|
default = cfg.domain;
|
||||||
};
|
};
|
||||||
port = mkOption {
|
port = mkOption {
|
||||||
description = "The port under which the TURN server is reachable";
|
description = "The port under which the TURN server is reachable";
|
||||||
type = types.int;
|
type = types.port;
|
||||||
default = 3478;
|
default = 3478;
|
||||||
};
|
};
|
||||||
userName = mkOption {
|
userName = mkOption {
|
||||||
|
@ -56,15 +71,14 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
settings = mkOption {
|
settings = mkOption {
|
||||||
|
default = {};
|
||||||
type = types.submodule {
|
type = types.submodule {
|
||||||
freeformType = formatType.type;
|
freeformType = formatType.type;
|
||||||
options = {
|
config = {
|
||||||
};
|
|
||||||
config = mkDefault {
|
|
||||||
Stuns = [
|
Stuns = [
|
||||||
{
|
{
|
||||||
Proto = "udp";
|
Proto = "udp";
|
||||||
Uri = "stun:${cfg.turn.domain}:${cfg.turn.domain}";
|
Uri = "turn:${cfg.turn.domain}:${toString cfg.turn.port}";
|
||||||
Username = "";
|
Username = "";
|
||||||
Password = null;
|
Password = null;
|
||||||
}
|
}
|
||||||
|
@ -73,7 +87,7 @@ in {
|
||||||
Turns = [
|
Turns = [
|
||||||
{
|
{
|
||||||
Proto = "udp";
|
Proto = "udp";
|
||||||
Uri = "stun:${cfg.turn.domain}:${cfg.turn.port}";
|
Uri = "stun:${cfg.turn.domain}:${toString cfg.turn.port}";
|
||||||
Username = cfg.turn.userName;
|
Username = cfg.turn.userName;
|
||||||
Password = cfg.turn.password;
|
Password = cfg.turn.password;
|
||||||
}
|
}
|
||||||
|
@ -96,13 +110,13 @@ in {
|
||||||
"0.0.0.0/0"
|
"0.0.0.0/0"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
Datadir = cfg.dataDir;
|
Datadir = "/var/lib/netbird-mgmt";
|
||||||
DataStoreEncryptionKey = lib.trace "uppsi wuppsi ich hab mein netbird unsiccccccher gemacht" "$NETBIRD_DATASTORE_ENC_KEY";
|
DataStoreEncryptionKey = lib.trace "uppsi wuppsi ich hab mein netbird unsiccccccher gemacht" "X4/obyAolDVhjGsz8NDb4TJqgCfwmCA7lOtJFHt9L3w=";
|
||||||
StoreConfig = {
|
StoreConfig = {
|
||||||
Engine = "sqlite";
|
Engine = "sqlite";
|
||||||
};
|
};
|
||||||
HttpConfig = {
|
HttpConfig = {
|
||||||
Address = "0.0.0.0:3000";
|
Address = "0.0.0.0:${toString cfg.port}";
|
||||||
#"AuthIssuer" = "$NETBIRD_AUTH_AUTHORITY";
|
#"AuthIssuer" = "$NETBIRD_AUTH_AUTHORITY";
|
||||||
#"AuthAudience" = "$NETBIRD_AUTH_AUDIENCE";
|
#"AuthAudience" = "$NETBIRD_AUTH_AUDIENCE";
|
||||||
#"AuthKeysLocation" = "$NETBIRD_AUTH_JWT_CERTS";
|
#"AuthKeysLocation" = "$NETBIRD_AUTH_JWT_CERTS";
|
||||||
|
@ -127,144 +141,57 @@ in {
|
||||||
#"KeycloakClientCredentials" = null;
|
#"KeycloakClientCredentials" = null;
|
||||||
#"ZitadelClientCredentials" = null;
|
#"ZitadelClientCredentials" = null;
|
||||||
};
|
};
|
||||||
#DeviceAuthorizationFlow = {
|
DeviceAuthorizationFlow = {
|
||||||
# Provider = "$NETBIRD_AUTH_DEVICE_AUTH_PROVIDER";
|
#Provider = "$NETBIRD_AUTH_DEVICE_AUTH_PROVIDER";
|
||||||
# "ProviderConfig" = {
|
ProviderConfig = {
|
||||||
# "Audience" = "$NETBIRD_AUTH_DEVICE_AUTH_AUDIENCE";
|
Audience = "netbird";
|
||||||
# "AuthorizationEndpoint" = "";
|
#"AuthorizationEndpoint" = "";
|
||||||
# "Domain" = "$NETBIRD_AUTH0_DOMAIN";
|
#"Domain" = "$NETBIRD_AUTH0_DOMAIN";
|
||||||
# "ClientID" = "$NETBIRD_AUTH_DEVICE_AUTH_CLIENT_ID";
|
#"ClientID" = "$NETBIRD_AUTH_DEVICE_AUTH_CLIENT_ID";
|
||||||
# "ClientSecret" = "";
|
#"ClientSecret" = "";
|
||||||
# "TokenEndpoint" = "$NETBIRD_AUTH_TOKEN_ENDPOINT";
|
#"TokenEndpoint" = "$NETBIRD_AUTH_TOKEN_ENDPOINT";
|
||||||
# "DeviceAuthEndpoint" = "$NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT";
|
#"DeviceAuthEndpoint" = "$NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT";
|
||||||
# "Scope" = "$NETBIRD_AUTH_DEVICE_AUTH_SCOPE";
|
Scope = "openid profile email";
|
||||||
# "UseIDToken" = "$NETBIRD_AUTH_DEVICE_AUTH_USE_ID_TOKEN";
|
#"UseIDToken" = "$NETBIRD_AUTH_DEVICE_AUTH_USE_ID_TOKEN";
|
||||||
# "RedirectURLs" = null;
|
#"RedirectURLs" = null;
|
||||||
# };
|
};
|
||||||
#};
|
};
|
||||||
PKCEAuthorizationFlow = {
|
PKCEAuthorizationFlow = {
|
||||||
ProviderConfig = {
|
ProviderConfig = {
|
||||||
#Audience = "$NETBIRD_AUTH_PKCE_AUDIENCE";
|
Audience = "netbird";
|
||||||
ClientID = "netbird";
|
ClientID = "netbird";
|
||||||
ClientSecret = lib.trace "oho bei zo vielen sicherheitzlücken" "$NETBIRD_AUTH_CLIENT_SECRET";
|
ClientSecret = lib.trace "oho bei zo vielen sicherheitzlücken" "";
|
||||||
Domain = "";
|
Domain = "";
|
||||||
#AuthorizationEndpoint = "$NETBIRD_AUTH_PKCE_AUTHORIZATION_ENDPOINT";
|
#AuthorizationEndpoint = "$NETBIRD_AUTH_PKCE_AUTHORIZATION_ENDPOINT";
|
||||||
#TokenEndpoint = "$NETBIRD_AUTH_TOKEN_ENDPOINT";
|
#TokenEndpoint = "$NETBIRD_AUTH_TOKEN_ENDPOINT";
|
||||||
Scope = "openid profile email";
|
Scope = "openid profile email";
|
||||||
RedirectURLs = ["localhost:53000"];
|
RedirectURLs = ["http://localhost:53000"];
|
||||||
UseIDToken = "$NETBIRD_AUTH_PKCE_USE_ID_TOKEN";
|
UseIDToken = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
config =
|
config = mkIf cfg.enable {
|
||||||
mkIf cfg.enable {
|
|
||||||
systemd.services = {
|
systemd.services = {
|
||||||
netbird-setup = {
|
|
||||||
wantedBy = [
|
|
||||||
"netbird-management.service"
|
|
||||||
"netbird-signal.service"
|
|
||||||
"multi-user.target"
|
|
||||||
];
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "oneshot";
|
|
||||||
RuntimeDirectory = "netbird-mgmt";
|
|
||||||
StateDirectory = "netbird-mgmt";
|
|
||||||
WorkingDirectory = cfg.dataDir;
|
|
||||||
EnvironmentFile = [ ];
|
|
||||||
};
|
|
||||||
unitConfig = {
|
|
||||||
StartLimitInterval = 5;
|
|
||||||
StartLimitBurst = 10;
|
|
||||||
};
|
|
||||||
|
|
||||||
path =
|
|
||||||
[
|
|
||||||
pkgs.coreutils
|
|
||||||
pkgs.findutils
|
|
||||||
pkgs.gettext
|
|
||||||
pkgs.gnused
|
|
||||||
# ]
|
|
||||||
# ++ (optionals cfg.setupAutoOidc [
|
|
||||||
# pkgs.curl
|
|
||||||
# pkgs.jq
|
|
||||||
];
|
|
||||||
|
|
||||||
script =
|
|
||||||
''
|
|
||||||
cp ${configFile} ${cfg.dataDir}/management.json
|
|
||||||
''
|
|
||||||
#+ (optionalString cfg.setupAutoOidc ''
|
|
||||||
# mv ${stateDir}/management.json.copy ${stateDir}/management.json
|
|
||||||
# echo "loading OpenID configuration from $NETBIRD_AUTH_OIDC_CONFIGURATION_ENDPOINT to the openid-configuration.json file"
|
|
||||||
# curl "$NETBIRD_AUTH_OIDC_CONFIGURATION_ENDPOINT" -q -o ${stateDir}/openid-configuration.json
|
|
||||||
|
|
||||||
# export NETBIRD_AUTH_AUTHORITY=$(jq -r '.issuer' ${stateDir}/openid-configuration.json)
|
|
||||||
# export NETBIRD_AUTH_JWT_CERTS=$(jq -r '.jwks_uri' ${stateDir}/openid-configuration.json)
|
|
||||||
# export NETBIRD_AUTH_TOKEN_ENDPOINT=$(jq -r '.token_endpoint' ${stateDir}/openid-configuration.json)
|
|
||||||
# export NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT=$(jq -r '.device_authorization_endpoint' ${stateDir}/openid-configuration.json)
|
|
||||||
# export NETBIRD_AUTH_PKCE_AUTHORIZATION_ENDPOINT=$(jq -r '.authorization_endpoint' ${stateDir}/openid-configuration.json)
|
|
||||||
|
|
||||||
# envsubst '$NETBIRD_AUTH_AUTHORITY $NETBIRD_AUTH_JWT_CERTS $NETBIRD_AUTH_TOKEN_ENDPOINT $NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT $NETBIRD_AUTH_PKCE_AUTHORIZATION_ENDPOINT' < ${stateDir}/management.json > ${stateDir}/management.json.copy
|
|
||||||
#'')
|
|
||||||
#+ ''
|
|
||||||
# # Update secrets in management.json
|
|
||||||
# ${builtins.concatStringsSep "\n" (
|
|
||||||
# builtins.attrValues (
|
|
||||||
# builtins.mapAttrs (name: path: "export ${name}=$(cat ${path})") (
|
|
||||||
# filterAttrs (_: p: p != null) cfg.secretFiles
|
|
||||||
# )
|
|
||||||
# )
|
|
||||||
# )}
|
|
||||||
+ ''
|
|
||||||
|
|
||||||
#envsubst '$TURN_PASSWORD $TURN_SECRET $STUN_PASSWORD $AUTH_CLIENT_SECRET $IDP_MGMT_CLIENT_SECRET' < ${cfg.dataDir}/management.json.copy > ${cfg.dataDir}/management.json
|
|
||||||
|
|
||||||
rm -rf ${cfg.dataDir}/web-ui
|
|
||||||
mkdir -p ${cfg.dataDir}/web-ui
|
|
||||||
cp -R ${cfg.dashboard}/* ${cfg.dataDir}/web-ui
|
|
||||||
|
|
||||||
export AUTH_AUTHORITY="$NETBIRD_AUTH_AUTHORITY"
|
|
||||||
export AUTH_CLIENT_ID="$NETBIRD_AUTH_CLIENT_ID"
|
|
||||||
${optionalString (cfg.secretFiles.AUTH_CLIENT_SECRET == null)
|
|
||||||
''export AUTH_CLIENT_SECRET="$NETBIRD_AUTH_CLIENT_SECRET"''}
|
|
||||||
export AUTH_AUDIENCE="$NETBIRD_AUTH_AUDIENCE"
|
|
||||||
export AUTH_REDIRECT_URI="$NETBIRD_AUTH_REDIRECT_URI"
|
|
||||||
export AUTH_SILENT_REDIRECT_URI="$NETBIRD_AUTH_SILENT_REDIRECT_URI"
|
|
||||||
export USE_AUTH0="$NETBIRD_USE_AUTH0"
|
|
||||||
export AUTH_SUPPORTED_SCOPES=$(echo $NETBIRD_AUTH_SUPPORTED_SCOPES | sed -E 's/"//g')
|
|
||||||
|
|
||||||
export NETBIRD_MGMT_API_ENDPOINT=$(echo $NETBIRD_MGMT_API_ENDPOINT | sed -E 's/(:80|:443)$//')
|
|
||||||
|
|
||||||
MAIN_JS=$(find ${cfg.dataDir}/web-ui/static/js/main.*js)
|
|
||||||
OIDC_TRUSTED_DOMAINS=${cfg.dataDir}/web-ui/OidcTrustedDomains.js
|
|
||||||
mv "$MAIN_JS" "$MAIN_JS".copy
|
|
||||||
envsubst '$USE_AUTH0 $AUTH_AUTHORITY $AUTH_CLIENT_ID $AUTH_CLIENT_SECRET $AUTH_SUPPORTED_SCOPES $AUTH_AUDIENCE $NETBIRD_MGMT_API_ENDPOINT $NETBIRD_MGMT_GRPC_API_ENDPOINT $NETBIRD_HOTJAR_TRACK_ID $AUTH_REDIRECT_URI $AUTH_SILENT_REDIRECT_URI $NETBIRD_TOKEN_SOURCE $NETBIRD_DRAG_QUERY_PARAMS' < "$MAIN_JS".copy > "$MAIN_JS"
|
|
||||||
envsubst '$NETBIRD_MGMT_API_ENDPOINT' < "$OIDC_TRUSTED_DOMAINS".tmpl > "$OIDC_TRUSTED_DOMAINS"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
netbird-signal = {
|
netbird-signal = {
|
||||||
after = [ "network.target" ];
|
after = ["network.target"];
|
||||||
wantedBy = [ "netbird-management.service" ];
|
wantedBy = ["netbird-management.service"];
|
||||||
restartTriggers = [
|
restartTriggers = [
|
||||||
settingsFile
|
configFile
|
||||||
managementFile
|
|
||||||
];
|
];
|
||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
ExecStart = ''
|
ExecStart = ''
|
||||||
${cfg.package}/bin/netbird-signal run \
|
${cfg.package}/bin/netbird-signal run \
|
||||||
--port ${builtins.toString cfg.ports.signal} \
|
|
||||||
--log-file console \
|
--log-file console \
|
||||||
--log-level ${cfg.logLevel}
|
--port ${builtins.toString cfg.signalPort}
|
||||||
'';
|
'';
|
||||||
Restart = "always";
|
Restart = "always";
|
||||||
RuntimeDirectory = "netbird-mgmt";
|
RuntimeDirectory = "netbird-mgmt";
|
||||||
StateDirectory = "netbird-mgmt";
|
StateDirectory = "netbird-mgmt";
|
||||||
WorkingDirectory = cfg.dataDir;
|
WorkingDirectory = "/var/lib/netbird-mgmt";
|
||||||
};
|
};
|
||||||
unitConfig = {
|
unitConfig = {
|
||||||
StartLimitInterval = 5;
|
StartLimitInterval = 5;
|
||||||
|
@ -275,42 +202,43 @@ in {
|
||||||
|
|
||||||
netbird-management = {
|
netbird-management = {
|
||||||
description = "The management server for Netbird, a wireguard VPN";
|
description = "The management server for Netbird, a wireguard VPN";
|
||||||
documentation = [ "https://netbird.io/docs/" ];
|
documentation = ["https://netbird.io/docs/"];
|
||||||
after = [
|
after = [
|
||||||
"network.target"
|
"network.target"
|
||||||
"netbird-setup.service"
|
"netbird-setup.service"
|
||||||
];
|
];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = ["multi-user.target"];
|
||||||
wants = [
|
wants = [
|
||||||
"netbird-signal.service"
|
"netbird-signal.service"
|
||||||
"netbird-setup.service"
|
"netbird-setup.service"
|
||||||
];
|
];
|
||||||
restartTriggers = [
|
restartTriggers = [
|
||||||
settingsFile
|
configFile
|
||||||
managementFile
|
|
||||||
];
|
];
|
||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
ExecStart = ''
|
ExecStart = ''
|
||||||
${cfg.package}/bin/netbird-mgmt management \
|
${cfg.package}/bin/netbird-mgmt management \
|
||||||
--config ${stateDir}/management.json \
|
--config ${configFile} \
|
||||||
--datadir ${stateDir}/data \
|
--datadir /var/lib/netbird-mgmt/data \
|
||||||
${optionalString cfg.management.disableAnonymousMetrics "--disable-anonymous-metrics"} \
|
--disable-anonymous-metrics \
|
||||||
${optionalString cfg.management.disableSingleAccountMode "--disable-single-account-mode"} \
|
${
|
||||||
--dns-domain ${cfg.management.dnsDomain} \
|
if cfg.singleAccountModeDomain == null
|
||||||
--single-account-mode-domain ${cfg.management.singleAccountModeDomain} \
|
then "--disable-single-account-mode"
|
||||||
|
else "--single-account-mode-domain ${cfg.singleAccountModeDomain}"
|
||||||
|
} \
|
||||||
--idp-sign-key-refresh-enabled \
|
--idp-sign-key-refresh-enabled \
|
||||||
--port ${builtins.toString cfg.ports.management} \
|
--port ${builtins.toString cfg.port} \
|
||||||
--log-file console \
|
--log-file consolef
|
||||||
--log-level ${cfg.logLevel}
|
|
||||||
'';
|
'';
|
||||||
|
# TODO add extraCOmmandLine option
|
||||||
Restart = "always";
|
Restart = "always";
|
||||||
RuntimeDirectory = "netbird-mgmt";
|
RuntimeDirectory = "netbird-mgmt";
|
||||||
StateDirectory = [
|
StateDirectory = [
|
||||||
"netbird-mgmt"
|
"netbird-mgmt"
|
||||||
"netbird-mgmt/data"
|
"netbird-mgmt/data"
|
||||||
];
|
];
|
||||||
WorkingDirectory = stateDir;
|
WorkingDirectory = "/var/lib/netbird-mgmt";
|
||||||
};
|
};
|
||||||
unitConfig = {
|
unitConfig = {
|
||||||
StartLimitInterval = 5;
|
StartLimitInterval = 5;
|
||||||
|
@ -319,6 +247,5 @@ in {
|
||||||
stopIfChanged = false;
|
stopIfChanged = false;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
})
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,6 +119,8 @@ in {
|
||||||
scopeMaps."immich.access" = ["openid" "email" "profile"];
|
scopeMaps."immich.access" = ["openid" "email" "profile"];
|
||||||
preferShortUsername = true;
|
preferShortUsername = true;
|
||||||
};
|
};
|
||||||
|
groups."netbird.access" = {
|
||||||
|
};
|
||||||
|
|
||||||
groups."forgejo.access" = {
|
groups."forgejo.access" = {
|
||||||
members = ["forgejo.admins"];
|
members = ["forgejo.admins"];
|
||||||
|
|
68
modules/services/netbird.nix
Normal file
68
modules/services/netbird.nix
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
{config, ...}: {
|
||||||
|
imports = [
|
||||||
|
../netbird-server.nix
|
||||||
|
../netbird-dashboard.nix
|
||||||
|
];
|
||||||
|
wireguard.elisabeth = {
|
||||||
|
client.via = "elisabeth";
|
||||||
|
firewallRuleForNode.elisabeth.allowedTCPPorts = [80 3000 3001];
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.firewall.allowedTCPPorts = [80 3000 3001];
|
||||||
|
networking.firewall.allowedUDPPorts = [3478];
|
||||||
|
services.netbird-dashboard = {
|
||||||
|
enable = true;
|
||||||
|
enableNginx = true;
|
||||||
|
domain = "netbird.${config.secrets.secrets.global.domains.web}";
|
||||||
|
settings = {
|
||||||
|
AUTH_AUTHORITY = "https://auth.${config.secrets.secrets.global.domains.web}/oauth2/openid/netbird";
|
||||||
|
AUTH_CLIENT_ID = "netbird";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
services.netbird-server = {
|
||||||
|
enable = true;
|
||||||
|
domain = "netbird.${config.secrets.secrets.global.domains.web}";
|
||||||
|
# TODO remove
|
||||||
|
oidcConfigEndpoint = "https://auth.${config.secrets.secrets.global.domains.web}/oauth2/openid/netbird/.well-known/openid-configuration";
|
||||||
|
singleAccountModeDomain = "netbird.patrick";
|
||||||
|
settings = {
|
||||||
|
HttpConfig = {
|
||||||
|
AuthIssuer = "https://auth.${config.secrets.secrets.global.domains.web}/oauth2/openid/netbird";
|
||||||
|
AuthKeysLocation = "https://auth.${config.secrets.secrets.global.domains.web}/oauth2/openid/netbird/public_key.jwk";
|
||||||
|
};
|
||||||
|
# Seems to be only useful for idp that netbird supports
|
||||||
|
IdpManagerConfig.ClientConfig = {
|
||||||
|
Issuer = "https://auth.${config.secrets.secrets.global.domains.web}/oauth2/openid/netbird";
|
||||||
|
TokenEndpoint = "https://auth.${config.secrets.secrets.global.domains.web}/oauth2/token";
|
||||||
|
};
|
||||||
|
DeviceAuthorizationFlow = {
|
||||||
|
Provider = "none";
|
||||||
|
ProviderConfig = {
|
||||||
|
AuthorizationEndpoint = "https://auth.${config.secrets.secrets.global.domains.web}/ui/oauth2/";
|
||||||
|
ClientID = "netbird";
|
||||||
|
#ClientSecret = "";
|
||||||
|
TokenEndpoint = "https://auth.${config.secrets.secrets.global.domains.web}/oauth2/token";
|
||||||
|
#RedirectURLs = ["http://localhost:53000"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
PKCEAuthorizationFlow.ProviderConfig = {
|
||||||
|
AuthorizationEndpoint = "https://auth.${config.secrets.secrets.global.domains.web}/ui/oauth2/";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
services.coturn = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
realm = "netbird.${config.secrets.secrets.global.domains.web}";
|
||||||
|
lt-cred-mech = true;
|
||||||
|
no-cli = true;
|
||||||
|
|
||||||
|
extraConfig = ''
|
||||||
|
fingerprint
|
||||||
|
|
||||||
|
user=turn:netbird
|
||||||
|
no-software-attribute
|
||||||
|
external-ip=87.170.9.213
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
Binary file not shown.
16
secrets/wireguard/elisabeth/keys/elisabeth-netbird.age
Normal file
16
secrets/wireguard/elisabeth/keys/elisabeth-netbird.age
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
age-encryption.org/v1
|
||||||
|
-> X25519 zghXrLqQhlVqAAbMi1k8gvG5IjG9boIJCyEx63DwwGo
|
||||||
|
/ae8dzj7mPxZdpciA+lLiR6H/WCrIvTkUfaXGP+RZiY
|
||||||
|
-> piv-p256 XTQkUA A4PgmdpN1WmH++JUTIdADZBqDrCQ2N8HP9FzQ7DtyJuU
|
||||||
|
CIzSKNP8YYYfMycueE564094XeKJ9mNEceAuUEnvFFI
|
||||||
|
-> piv-p256 ZFgiIw AgxtRiqyF4Fo6Us/l8vXhWl2tQakCQGwd1Dogf/Wqnyv
|
||||||
|
Gi9O1lFR2hhfkXoC7cmlpT+iHx0DxeDFmuU9i+Gc4Ms
|
||||||
|
-> piv-p256 5vmPtQ AsbmH20Pc58VF7tBnoE5iqzlrsahCDTHkvuyAQ4W5SPy
|
||||||
|
BcJr9QsIDanypSNZ0UWrt0VnJK99LM0FOmCQWc+2rPY
|
||||||
|
-> piv-p256 ZFgiIw A5CT86jvz263c1GoDrtGVBXZx9EZeQwCL2d/tCXGqay3
|
||||||
|
8kHhsuD77fPPLPe8JYTuHNcCtp0VJcdrTg220BVdyGc
|
||||||
|
-> v-"@h-grease sJN %C \ ?mh0`=L
|
||||||
|
FarOmtacPX3pzMNzucQdNxI8MpVZdumJghhEPiukRJxp5+3InvEp7lvBhtZv49i3
|
||||||
|
QPoKNFjUweN6aXA9Vs1cpSQ
|
||||||
|
--- k49nSQRFr22Pc4QtH0WlYQ2/yMpBXSJasmQ97ZcxLkU
|
||||||
|
^sÛø¬hÈÊ<C388>L‚ÜvÕçøí©++'•å8¶{ZŠïÀÑCÆðŽ}ö¯ZúPQ0U‚$¸±²¨þ•:YÀ—õ”ïËÊ1NO
l'
|
1
secrets/wireguard/elisabeth/keys/elisabeth-netbird.pub
Normal file
1
secrets/wireguard/elisabeth/keys/elisabeth-netbird.pub
Normal file
|
@ -0,0 +1 @@
|
||||||
|
yv8nqlqgBxDIf6oYrn01FRKoKnqZPfdenWIFHxfSLiA=
|
|
@ -0,0 +1,16 @@
|
||||||
|
age-encryption.org/v1
|
||||||
|
-> X25519 bq+eQrKzKWG2cvp+7cKzpkN7KEbxf4H8aSOBxOBNeVE
|
||||||
|
uiZloroeAw+q0T9CTGbAg6cdHShGaa5YOVk0iE5FLMM
|
||||||
|
-> piv-p256 XTQkUA A5CqoI0rxRrOyHv6LksBqtzWPapfCLi6IdK3KAUATzJF
|
||||||
|
d3VMdZpw0TjU8kZ6WNLcbvenDD4WWxJp2rEogNnW43o
|
||||||
|
-> piv-p256 ZFgiIw Ah/2IZobkAFu0r0rSHvB9RyQhXh+wk1R9Vlky8J44xib
|
||||||
|
5GXXZuXybVXcrpU8G8bWYwMOjnzdw7X+YjQaQlA1F4E
|
||||||
|
-> piv-p256 5vmPtQ AjmJ3ZgFxcbSbGefvufWZNzo0nOc8vl+4jA7kb5kwSbI
|
||||||
|
2ks2FzxZ/YloeAVCRT/0NEo4hRWzUbknj+pnwtGuEZM
|
||||||
|
-> piv-p256 ZFgiIw ApvFPxETdpXGYLa9srv+pKFHNOGfa7ie8oyOInKDbOqC
|
||||||
|
8rIukUZzrkWdH11pnTYfPd259ql/UGg5/Z6SuNvslUA
|
||||||
|
-> X=N9-grease CPXXj9j! Mf6?oC AuDyAWo z5x1TGOh
|
||||||
|
CYoYan7n
|
||||||
|
--- 9xwTgosTBqh7i3YCpHUhvkYV6bormJ3hYP4WHTwwQk4
|
||||||
|
íIˆy»0Ö[Ûž$ÞŒ‹Ž-¦¨:k@™
Ê}é9 Ÿåµ
|
||||||
|
2òîl'*Ô[Sêr$ÿ*ÅWjüBì,-w£RÒ1ãBý&ø!€.ó@
|
Loading…
Reference in a new issue