Compare commits
8 commits
d97a085af5
...
f894c27799
| Author | SHA1 | Date | |
|---|---|---|---|
| f894c27799 | |||
| 11ed5a80d7 | |||
| 4881f836c9 | |||
| 530695d941 | |||
| 04ba2761b5 | |||
| 81f4554dd7 | |||
| f7c4620378 | |||
| d1cfaf7acf |
9 changed files with 260 additions and 19 deletions
8
flake.lock
generated
8
flake.lock
generated
|
|
@ -338,11 +338,11 @@
|
||||||
"secrets": {
|
"secrets": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1777076192,
|
"lastModified": 1777152364,
|
||||||
"narHash": "sha256-N7n2OPN2IRWwL73Cr6mc5nNhucHmMeFas9hQ/NF0bFg=",
|
"narHash": "sha256-yS8TxtPFFf7xIDNbsErZUnTBLn2fnyCcC4On+t3v1Zs=",
|
||||||
"ref": "refs/heads/main",
|
"ref": "refs/heads/main",
|
||||||
"rev": "34ff1c4b0460a2e103a8fec183f53f274dc123ed",
|
"rev": "bfb7da1297d73100a56a044d09792fc6e59357e6",
|
||||||
"revCount": 32,
|
"revCount": 34,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "ssh://git@git.jfreudenberger.de/JuliusFreudenberger/nix-private.git"
|
"url": "ssh://git@git.jfreudenberger.de/JuliusFreudenberger/nix-private.git"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,9 @@
|
||||||
|
|
||||||
specialArgs = {
|
specialArgs = {
|
||||||
inherit inputs outputs;
|
inherit inputs outputs;
|
||||||
|
pkgs-unstable = import nixpkgs-unstable {
|
||||||
|
inherit system;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
modules = [
|
modules = [
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
{ inputs, outputs, config, lib, pkgs, ... }:
|
{ inputs, outputs, config, lib, pkgs, pkgs-unstable, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
imports =
|
imports =
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
../../modules/nix.nix
|
../../modules/nix.nix
|
||||||
../../modules/auto-upgrade.nix
|
../../modules/auto-upgrade.nix
|
||||||
|
../../users/julius/nixos-server.nix
|
||||||
../../modules/locale.nix
|
../../modules/locale.nix
|
||||||
../../modules/server-cli.nix
|
../../modules/server-cli.nix
|
||||||
../../modules/sshd.nix
|
../../modules/sshd.nix
|
||||||
|
|
@ -23,21 +24,29 @@
|
||||||
};
|
};
|
||||||
tmp.useTmpfs = true;
|
tmp.useTmpfs = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
system.autoUpgrade.allowReboot = false;
|
||||||
|
|
||||||
networking.hostName = "busch"; # Define your hostname.
|
networking.hostName = "busch"; # Define your hostname.
|
||||||
users = {
|
|
||||||
users = {
|
services.netbird = {
|
||||||
julius = {
|
package = pkgs-unstable.netbird;
|
||||||
isNormalUser = true;
|
useRoutingFeatures = "both";
|
||||||
uid = 1000;
|
clients.wt0 = {
|
||||||
extraGroups = [ "wheel" "julius" ];
|
hardened = false;
|
||||||
|
login = {
|
||||||
|
enable = true;
|
||||||
|
setupKeyFile = (pkgs.writeText "setupKey" ''
|
||||||
|
A99F5508-D543-40B7-A31A-A8931B1AE246
|
||||||
|
'').outPath;
|
||||||
};
|
};
|
||||||
};
|
port = 51820;
|
||||||
groups = {
|
environment = {
|
||||||
julius = {
|
NB_MANAGEMENT_URL = "https://netbird.jfreudenberger.de";
|
||||||
gid = 1000;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
systemd.services.${config.services.netbird.clients.wt0.service.name}.path = [ pkgs.shadow ];
|
||||||
|
|
||||||
nix.settings = {
|
nix.settings = {
|
||||||
substituters = [
|
substituters = [
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
../../modules/docker.nix
|
../../modules/docker.nix
|
||||||
../../modules/traefik.nix
|
../../modules/traefik.nix
|
||||||
../../modules/pocket-id.nix
|
../../modules/pocket-id.nix
|
||||||
|
../../modules/netbird-docker.nix
|
||||||
../../modules/auto-upgrade.nix
|
../../modules/auto-upgrade.nix
|
||||||
"${inputs.secrets}/modules/opkssh.nix"
|
"${inputs.secrets}/modules/opkssh.nix"
|
||||||
# Include the results of the hardware scan.
|
# Include the results of the hardware scan.
|
||||||
|
|
@ -42,6 +43,24 @@
|
||||||
};
|
};
|
||||||
environmentFile = config.age.secrets.pocket-id.path;
|
environmentFile = config.age.secrets.pocket-id.path;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
netbird-docker = {
|
||||||
|
enable = true;
|
||||||
|
secrets = config.age.secrets.netbird-server;
|
||||||
|
proxy = {
|
||||||
|
domain = "netbird.jfreudenberger.de";
|
||||||
|
token-secret = config.age.secrets.netbird-proxy;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
netbird.server = let
|
||||||
|
domain = "netbird.jfreudenberger.de";
|
||||||
|
in {
|
||||||
|
domain = domain;
|
||||||
|
management.domain = domain;
|
||||||
|
dashboard.domain = domain;
|
||||||
|
signal.domain = domain;
|
||||||
|
management.oidcConfigEndpoint = "https://login.jfreudenberger.de/.well-known/openid-configuration";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.network = {
|
systemd.network = {
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,7 @@
|
||||||
age.secrets = {
|
age.secrets = {
|
||||||
inwx.file = "${inputs.secrets}/secrets/dns-management/inwx";
|
inwx.file = "${inputs.secrets}/secrets/dns-management/inwx";
|
||||||
pocket-id.file = "${inputs.secrets}/secrets/srv03/pocket-id";
|
pocket-id.file = "${inputs.secrets}/secrets/srv03/pocket-id";
|
||||||
|
netbird-server.file = "${inputs.secrets}/secrets/srv03/netbird-server";
|
||||||
|
netbird-proxy.file = "${inputs.secrets}/secrets/srv03/netbird-proxy";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
{
|
{
|
||||||
inputs,
|
inputs,
|
||||||
pkgs,
|
pkgs,
|
||||||
|
lib,
|
||||||
...
|
...
|
||||||
}: {
|
}: {
|
||||||
system.autoUpgrade = {
|
system.autoUpgrade = {
|
||||||
|
|
@ -12,7 +13,7 @@
|
||||||
flake = inputs.self.outPath;
|
flake = inputs.self.outPath;
|
||||||
dates = "02:00";
|
dates = "02:00";
|
||||||
randomizedDelaySec = "45min";
|
randomizedDelaySec = "45min";
|
||||||
allowReboot = true;
|
allowReboot = lib.mkDefault true;
|
||||||
rebootWindow = {
|
rebootWindow = {
|
||||||
lower = "01:00";
|
lower = "01:00";
|
||||||
upper = "05:00";
|
upper = "05:00";
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ in {
|
||||||
};
|
};
|
||||||
extraOptions = [
|
extraOptions = [
|
||||||
''--mount=type=volume,source=dockhand-data,target=/app/data,volume-driver=local''
|
''--mount=type=volume,source=dockhand-data,target=/app/data,volume-driver=local''
|
||||||
''--group-add=${config.ids.gids.docker}''
|
''--group-add=${toString config.ids.gids.docker}''
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
208
modules/netbird-docker.nix
Normal file
208
modules/netbird-docker.nix
Normal file
|
|
@ -0,0 +1,208 @@
|
||||||
|
{
|
||||||
|
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";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -76,6 +76,7 @@ in {
|
||||||
];
|
];
|
||||||
extraOptions = [
|
extraOptions = [
|
||||||
''--mount=type=volume,source=certs,target=/certs,volume-driver=local''
|
''--mount=type=volume,source=certs,target=/certs,volume-driver=local''
|
||||||
|
"--ip=172.18.0.2"
|
||||||
"--add-host=host.docker.internal:host-gateway"
|
"--add-host=host.docker.internal:host-gateway"
|
||||||
"--health-cmd=wget --spider --quiet http://localhost:8080/ping"
|
"--health-cmd=wget --spider --quiet http://localhost:8080/ping"
|
||||||
"--health-interval=10s"
|
"--health-interval=10s"
|
||||||
|
|
@ -130,7 +131,5 @@ in {
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
networking.firewall.extraCommands = "iptables -t nat -I PREROUTING -s 172.18.0.0/16 -d 172.18.0.0/16 -j MASQUERADE";
|
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue