WIP: netbird
This commit is contained in:
parent
a2fc99bd6c
commit
86593e3b7d
324
modules/netbird-server.nix
Normal file
324
modules/netbird-server.nix
Normal file
|
@ -0,0 +1,324 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit
|
||||
(lib)
|
||||
mkEnableOption
|
||||
mkOption
|
||||
types
|
||||
mkDefault
|
||||
mkIf
|
||||
;
|
||||
cfg = config.services.netbird;
|
||||
|
||||
configFile = formatType.generate config.json cfg.settings;
|
||||
|
||||
formatType = pkgs.format.json {};
|
||||
in {
|
||||
options.services.netbird = {
|
||||
enable = mkEnableOption "netbird, a self hosted wireguard VPN";
|
||||
domain = mkOption {
|
||||
description = "The domain of your netbird instance";
|
||||
};
|
||||
oidcConfigEndpoint = mkOption {
|
||||
type = types.str;
|
||||
example = "https://example.eu.auth0.com/.well-known/openid-configuration";
|
||||
description = "The oidc discovery endpoint";
|
||||
};
|
||||
dataDir = mkOption {
|
||||
description = "Runtime directory where netbird stores its data";
|
||||
types = types.path;
|
||||
default = /var/lib/netbird;
|
||||
};
|
||||
turn = {
|
||||
domain = mkOption {
|
||||
description = "The domain under which the TURN server is reachable";
|
||||
type = types.str;
|
||||
example = "localhost";
|
||||
};
|
||||
port = mkOption {
|
||||
description = "The port under which the TURN server is reachable";
|
||||
type = types.int;
|
||||
default = 3478;
|
||||
};
|
||||
userName = mkOption {
|
||||
description = "The Username for logging into your turn server";
|
||||
type = types.str;
|
||||
default = "netbird";
|
||||
};
|
||||
password = mkOption {
|
||||
description = "The password for logging into your turn server";
|
||||
type = types.str;
|
||||
default = lib.trace "should not be part of the final config" "netbird";
|
||||
};
|
||||
};
|
||||
settings = mkOption {
|
||||
type = types.submodule {
|
||||
freeformType = formatType.type;
|
||||
options = {
|
||||
};
|
||||
config = mkDefault {
|
||||
Stuns = [
|
||||
{
|
||||
Proto = "udp";
|
||||
Uri = "stun:${cfg.turn.domain}:${cfg.turn.domain}";
|
||||
Username = "";
|
||||
Password = null;
|
||||
}
|
||||
];
|
||||
TURNConfig = {
|
||||
Turns = [
|
||||
{
|
||||
Proto = "udp";
|
||||
Uri = "stun:${cfg.turn.domain}:${cfg.turn.port}";
|
||||
Username = cfg.turn.userName;
|
||||
Password = cfg.turn.password;
|
||||
}
|
||||
];
|
||||
CredentialsTTL = "12h";
|
||||
Secret = lib.trace "this should probably be an option as well" "secret";
|
||||
TimeBasedCredentials = false;
|
||||
};
|
||||
|
||||
Signal = {
|
||||
Proto = "https";
|
||||
URI = "${cfg.domain}:443";
|
||||
Username = "";
|
||||
Password = null;
|
||||
};
|
||||
ReverseProxy = {
|
||||
TrustedHTTPProxies = [];
|
||||
TrustedHTTPProxiesCount = 0;
|
||||
TrustedPeers = [
|
||||
"0.0.0.0/0"
|
||||
];
|
||||
};
|
||||
Datadir = cfg.dataDir;
|
||||
DataStoreEncryptionKey = lib.trace "uppsi wuppsi ich hab mein netbird unsiccccccher gemacht" "$NETBIRD_DATASTORE_ENC_KEY";
|
||||
StoreConfig = {
|
||||
Engine = "sqlite";
|
||||
};
|
||||
HttpConfig = {
|
||||
Address = "0.0.0.0:3000";
|
||||
#"AuthIssuer" = "$NETBIRD_AUTH_AUTHORITY";
|
||||
#"AuthAudience" = "$NETBIRD_AUTH_AUDIENCE";
|
||||
#"AuthKeysLocation" = "$NETBIRD_AUTH_JWT_CERTS";
|
||||
AuthUserIDClaim = "sub";
|
||||
#"CertFile" = "$NETBIRD_MGMT_API_CERT_FILE";
|
||||
#"CertKey" = "$NETBIRD_MGMT_API_CERT_KEY_FILE";
|
||||
#"IdpSignKeyRefreshEnabled" = "$NETBIRD_MGMT_IDP_SIGNKEY_REFRESH";
|
||||
OIDCConfigEndpoint = cfg.oidcConfigEndpoint;
|
||||
};
|
||||
IdpManagerConfig = {
|
||||
ManagerType = "none";
|
||||
ClientConfig = {
|
||||
#"Issuer" = "$NETBIRD_AUTH_AUTHORITY";
|
||||
#TokenEndpoint = "$NETBIRD_AUTH_TOKEN_ENDPOINT";
|
||||
ClientID = "netbird-manager";
|
||||
ClientSecret = lib.trace "oho wer stiehlt meine zugäneg zuerts" "$NETBIRD_IDP_MGMT_CLIENT_SECRET";
|
||||
GrantType = "client_credentials";
|
||||
};
|
||||
#"ExtraConfig" = "$NETBIRD_IDP_MGMT_EXTRA_CONFIG";
|
||||
#"Auth0ClientCredentials" = null;
|
||||
#"AzureClientCredentials" = null;
|
||||
#"KeycloakClientCredentials" = null;
|
||||
#"ZitadelClientCredentials" = null;
|
||||
};
|
||||
#DeviceAuthorizationFlow = {
|
||||
# Provider = "$NETBIRD_AUTH_DEVICE_AUTH_PROVIDER";
|
||||
# "ProviderConfig" = {
|
||||
# "Audience" = "$NETBIRD_AUTH_DEVICE_AUTH_AUDIENCE";
|
||||
# "AuthorizationEndpoint" = "";
|
||||
# "Domain" = "$NETBIRD_AUTH0_DOMAIN";
|
||||
# "ClientID" = "$NETBIRD_AUTH_DEVICE_AUTH_CLIENT_ID";
|
||||
# "ClientSecret" = "";
|
||||
# "TokenEndpoint" = "$NETBIRD_AUTH_TOKEN_ENDPOINT";
|
||||
# "DeviceAuthEndpoint" = "$NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT";
|
||||
# "Scope" = "$NETBIRD_AUTH_DEVICE_AUTH_SCOPE";
|
||||
# "UseIDToken" = "$NETBIRD_AUTH_DEVICE_AUTH_USE_ID_TOKEN";
|
||||
# "RedirectURLs" = null;
|
||||
# };
|
||||
#};
|
||||
PKCEAuthorizationFlow = {
|
||||
ProviderConfig = {
|
||||
#Audience = "$NETBIRD_AUTH_PKCE_AUDIENCE";
|
||||
ClientID = "netbird";
|
||||
ClientSecret = lib.trace "oho bei zo vielen sicherheitzlücken" "$NETBIRD_AUTH_CLIENT_SECRET";
|
||||
Domain = "";
|
||||
#AuthorizationEndpoint = "$NETBIRD_AUTH_PKCE_AUTHORIZATION_ENDPOINT";
|
||||
#TokenEndpoint = "$NETBIRD_AUTH_TOKEN_ENDPOINT";
|
||||
Scope = "openid profile email";
|
||||
RedirectURLs = ["localhost:53000"];
|
||||
UseIDToken = "$NETBIRD_AUTH_PKCE_USE_ID_TOKEN";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
config =
|
||||
mkIf cfg.enable {
|
||||
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 = {
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "netbird-management.service" ];
|
||||
restartTriggers = [
|
||||
settingsFile
|
||||
managementFile
|
||||
];
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
${cfg.package}/bin/netbird-signal run \
|
||||
--port ${builtins.toString cfg.ports.signal} \
|
||||
--log-file console \
|
||||
--log-level ${cfg.logLevel}
|
||||
'';
|
||||
Restart = "always";
|
||||
RuntimeDirectory = "netbird-mgmt";
|
||||
StateDirectory = "netbird-mgmt";
|
||||
WorkingDirectory = cfg.dataDir;
|
||||
};
|
||||
unitConfig = {
|
||||
StartLimitInterval = 5;
|
||||
StartLimitBurst = 10;
|
||||
};
|
||||
stopIfChanged = false;
|
||||
};
|
||||
|
||||
netbird-management = {
|
||||
description = "The management server for Netbird, a wireguard VPN";
|
||||
documentation = [ "https://netbird.io/docs/" ];
|
||||
after = [
|
||||
"network.target"
|
||||
"netbird-setup.service"
|
||||
];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
wants = [
|
||||
"netbird-signal.service"
|
||||
"netbird-setup.service"
|
||||
];
|
||||
restartTriggers = [
|
||||
settingsFile
|
||||
managementFile
|
||||
];
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = ''
|
||||
${cfg.package}/bin/netbird-mgmt management \
|
||||
--config ${stateDir}/management.json \
|
||||
--datadir ${stateDir}/data \
|
||||
${optionalString cfg.management.disableAnonymousMetrics "--disable-anonymous-metrics"} \
|
||||
${optionalString cfg.management.disableSingleAccountMode "--disable-single-account-mode"} \
|
||||
--dns-domain ${cfg.management.dnsDomain} \
|
||||
--single-account-mode-domain ${cfg.management.singleAccountModeDomain} \
|
||||
--idp-sign-key-refresh-enabled \
|
||||
--port ${builtins.toString cfg.ports.management} \
|
||||
--log-file console \
|
||||
--log-level ${cfg.logLevel}
|
||||
'';
|
||||
Restart = "always";
|
||||
RuntimeDirectory = "netbird-mgmt";
|
||||
StateDirectory = [
|
||||
"netbird-mgmt"
|
||||
"netbird-mgmt/data"
|
||||
];
|
||||
WorkingDirectory = stateDir;
|
||||
};
|
||||
unitConfig = {
|
||||
StartLimitInterval = 5;
|
||||
StartLimitBurst = 10;
|
||||
};
|
||||
stopIfChanged = false;
|
||||
};
|
||||
};
|
||||
})
|
||||
};
|
||||
}
|
Loading…
Reference in a new issue