When setting the explicit ip of the traefik container in the webproxy network, this resolves the ip of the traefik container changing between restarts.
208 lines
8.4 KiB
Nix
208 lines
8.4 KiB
Nix
{
|
|
pkgs,
|
|
utils,
|
|
config,
|
|
lib,
|
|
...
|
|
}:
|
|
let
|
|
|
|
cfg = config.services.netbird-docker;
|
|
netbirdCfg = config.services.netbird;
|
|
|
|
serverVersion = "0.69.0";
|
|
dashboardVersion = "2.37.1";
|
|
|
|
in {
|
|
|
|
options.services.netbird-docker = {
|
|
enable = lib.mkEnableOption "Netbird Server stack, comprising the dashboard, management API, signal service, relay and STUN server";
|
|
enableLocalAuth = lib.mkEnableOption "local authentication";
|
|
proxy = lib.mkOption {
|
|
description = "Configuration for proxy";
|
|
type = lib.types.submodule {
|
|
options = {
|
|
domain = lib.mkOption {
|
|
description = "Domain the proxy is reachable at. Custom domains will need to add a CNAME record of the wildcard subdomain to this domain.";
|
|
type = lib.types.str;
|
|
};
|
|
token-secret = lib.mkOption {
|
|
description = ''
|
|
Proxy token in env-file notation.
|
|
Name of the environment variable is `NB_PROXY_TOKEN`.
|
|
Create the proxy token after netbird is installed with the following command: docker exec -it netbird-server /go/bin/netbird-server --config /etc/netbird/config.yaml token create --name local
|
|
'';
|
|
type = lib.types.anything;
|
|
};
|
|
};
|
|
};
|
|
};
|
|
secrets = lib.mkOption {
|
|
description = ''
|
|
Secret for combined server in env-file notation.
|
|
Name of the relevant environment variables:
|
|
- NETBIRD_RELAY_AUTH_SECRET - Shared authentication secret for relay
|
|
- NETBIRD_DATASTORE_ENC_KEY - Encryption key for sensitive data
|
|
'';
|
|
type = lib.types.anything;
|
|
};
|
|
};
|
|
|
|
config = lib.mkIf cfg.enable {
|
|
virtualisation.oci-containers.containers = {
|
|
netbird-dashboard = {
|
|
image = "netbirdio/dashboard:v${dashboardVersion}";
|
|
autoStart = true;
|
|
networks = [
|
|
"webproxy"
|
|
];
|
|
environment = {
|
|
NETBIRD_MGMT_API_ENDPOINT = "https://${netbirdCfg.server.management.domain}";
|
|
NETBIRD_MGMT_GRPC_API_ENDPOINT = "https://${netbirdCfg.server.management.domain}";
|
|
AUTH_AUDIENCE="netbird-dashboard";
|
|
AUTH_CLIENT_ID="netbird-dashboard";
|
|
AUTH_CLIENT_SECRET="";
|
|
AUTH_AUTHORITY = "https://${netbirdCfg.server.domain}/oauth2";
|
|
USE_AUTH0="false";
|
|
AUTH_SUPPORTED_SCOPES="openid profile email groups";
|
|
AUTH_REDIRECT_URI="/nb-auth";
|
|
AUTH_SILENT_REDIRECT_URI="/nb-silent-auth";
|
|
NGINX_SSL_PORT="443";
|
|
LETSENCRYPT_DOMAIN="none";
|
|
};
|
|
labels = {
|
|
"traefik.enable" = "true";
|
|
"traefik.http.routers.netbird-dashboard.rule" = "Host(`${netbirdCfg.server.dashboard.domain}`)";
|
|
"traefik.http.routers.netbird-dashboard.entrypoints" = "websecure";
|
|
"traefik.http.routers.netbird-dashboard.tls" = "true";
|
|
"traefik.http.routers.netbird-dashboard.tls.certresolver" = "letsencrypt";
|
|
"traefik.http.routers.netbird-dashboard.service" = "dashboard";
|
|
"traefik.http.routers.netbird-dashboard.priority" = "1";
|
|
"traefik.http.services.dashboard.loadbalancer.server.port" = "80";
|
|
};
|
|
dependsOn = [
|
|
"netbird-server"
|
|
];
|
|
};
|
|
netbird-server = {
|
|
image = "netbirdio/netbird-server:${serverVersion}";
|
|
autoStart = true;
|
|
networks = [
|
|
"webproxy"
|
|
];
|
|
entrypoint = "/bin/sh";
|
|
cmd = [
|
|
"-c"
|
|
''sed -e "s|__AUTH_SECRET__|$NETBIRD_RELAY_AUTH_SECRET|" -e "s|__DATASTORE_ENC_KEY__|$NETBIRD_DATASTORE_ENC_KEY|" /etc/netbird/config.yaml.tmpl > /etc/netbird/config.yaml && /go/bin/netbird-server --config /etc/netbird/config.yaml''
|
|
];
|
|
ports = [
|
|
"3478:3478/udp"
|
|
];
|
|
volumes = let
|
|
server-config = (pkgs.formats.yaml {}).generate "netbird-server-config" {
|
|
server = {
|
|
listenAddress = ":80";
|
|
exposedAddress = "https://${netbirdCfg.server.domain}:443";
|
|
stunPorts = [ 3478 ];
|
|
metricsPort = 9090;
|
|
healthCheckAddress = ":9000";
|
|
logLevel = netbirdCfg.server.management.logLevel;
|
|
logFile = "console";
|
|
authSecret = "__AUTH_SECRET__";
|
|
dataDir = "/var/lib/netbird";
|
|
auth = {
|
|
issuer = "https://${netbirdCfg.server.dashboard.domain}/oauth2";
|
|
localAuthDisabled = !cfg.enableLocalAuth;
|
|
signKeyRefreshEnabled = true;
|
|
dashboardRedirectURIs = [
|
|
"https://${netbirdCfg.server.dashboard.domain}/nb-auth"
|
|
"https://${netbirdCfg.server.dashboard.domain}/nb-silent-auth"
|
|
];
|
|
cliRedirectURIs = [
|
|
"http://localhost:53000"
|
|
];
|
|
};
|
|
reverseProxy.trustedHTTPProxies = [
|
|
"172.18.0.2/32"
|
|
];
|
|
store = {
|
|
engine = "sqlite";
|
|
encryptionKey = "__DATASTORE_ENC_KEY__";
|
|
};
|
|
};
|
|
};
|
|
in [
|
|
"${server-config}:/etc/netbird/config.yaml.tmpl"
|
|
];
|
|
environmentFiles = [
|
|
cfg.secrets.path
|
|
];
|
|
extraOptions = [
|
|
''--mount=type=volume,source=netbird_data,target=/var/lib/netbird,volume-driver=local''
|
|
];
|
|
labels = {
|
|
"traefik.enable" = "true";
|
|
"traefik.http.routers.netbird-grpc.rule" = "Host(`${netbirdCfg.server.signal.domain}`) && (PathPrefix(`/signalexchange.SignalExchange/`) || PathPrefix(`/management.ManagementService/`))";
|
|
"traefik.http.routers.netbird-grpc.entrypoints" = "websecure";
|
|
"traefik.http.routers.netbird-grpc.tls" = "true";
|
|
"traefik.http.routers.netbird-grpc.tls.certresolver" = "letsencrypt";
|
|
"traefik.http.routers.netbird-grpc.service" = "netbird-server-h2c";
|
|
"traefik.http.routers.netbird-grpc.priority" = "100";
|
|
"traefik.http.routers.netbird-backend.rule" = "Host(`${netbirdCfg.server.domain}`) && (PathPrefix(`/relay`) || PathPrefix(`/ws-proxy/`) || PathPrefix(`/api`) || PathPrefix(`/oauth2`))";
|
|
"traefik.http.routers.netbird-backend.entrypoints" = "websecure";
|
|
"traefik.http.routers.netbird-backend.tls" = "true";
|
|
"traefik.http.routers.netbird-backend.tls.certresolver" = "letsencrypt";
|
|
"traefik.http.routers.netbird-backend.service" = "netbird-server";
|
|
"traefik.http.routers.netbird-backend.priority" = "100";
|
|
"traefik.http.services.netbird-server.loadbalancer.server.port" = "80";
|
|
"traefik.http.services.netbird-server-h2c.loadbalancer.server.port" = "80";
|
|
"traefik.http.services.netbird-server-h2c.loadbalancer.server.scheme" = "h2c";
|
|
};
|
|
dependsOn = [
|
|
"traefik"
|
|
];
|
|
};
|
|
netbird-proxy = {
|
|
image = "netbirdio/reverse-proxy:${serverVersion}";
|
|
autoStart = true;
|
|
ports = [
|
|
"51820:51820/udp"
|
|
];
|
|
networks = [
|
|
"webproxy"
|
|
];
|
|
dependsOn = [
|
|
"netbird-server"
|
|
];
|
|
environment = {
|
|
NB_PROXY_MANAGEMENT_ADDRESS="http://netbird-server:80";
|
|
NB_PROXY_ALLOW_INSECURE="true";
|
|
NB_PROXY_DOMAIN = cfg.proxy.domain;
|
|
NB_PROXY_ADDRESS = ":8443";
|
|
NB_PROXY_CERTIFICATE_DIRECTORY = "/certs";
|
|
NB_PROXY_ACME_CERTIFICATES = "true";
|
|
NB_PROXY_ACME_CHALLENGE_TYPE = "tls-alpn-01";
|
|
NB_PROXY_FORWARDED_PROTO = "https";
|
|
NB_PROXY_PROXY_PROTOCOL = "true";
|
|
NB_PROXY_TRUSTED_PROXIES = "172.18.0.2";
|
|
};
|
|
environmentFiles = [
|
|
cfg.proxy.token-secret.path
|
|
];
|
|
extraOptions = [
|
|
''--mount=type=volume,source=netbird_proxy_certs,target=/certs,volume-driver=local''
|
|
];
|
|
labels = {
|
|
"traefik.enable" = "true";
|
|
"traefik.tcp.routers.proxy-passthrough.entrypoints" = "websecure";
|
|
"traefik.tcp.routers.proxy-passthrough.rule" = "HostSNI(`*`)";
|
|
"traefik.tcp.routers.proxy-passthrough.tls.passthrough" = "true";
|
|
"traefik.tcp.routers.proxy-passthrough.service" = "proxy-tls";
|
|
"traefik.tcp.routers.proxy-passthrough.priority" = "1";
|
|
"traefik.tcp.services.proxy-tls.loadbalancer.server.port" = "8443";
|
|
"traefik.tcp.services.proxy-tls.loadbalancer.serverstransport" = "pp-v2@file";
|
|
};
|
|
};
|
|
};
|
|
};
|
|
}
|