mirror of
https://github.com/oddlama/nix-config.git
synced 2025-10-10 23:00:39 +02:00
feat: add netbird client (gateway server and dev machine)
This commit is contained in:
parent
590266c793
commit
8148ce9f37
17 changed files with 600 additions and 18 deletions
|
@ -60,6 +60,8 @@ that most people would have. The configurations are sorted into three categories
|
||||||
🗓️ CalDAV/CardDAV | – | Radicale | [Link](./hosts/ward/guests/radicale.nix) | Contacts, Calender and Tasks synchronization
|
🗓️ CalDAV/CardDAV | – | Radicale | [Link](./hosts/ward/guests/radicale.nix) | Contacts, Calender and Tasks synchronization
|
||||||
📁 NAS | 💎 | Samba | [Link](./hosts/sire/guests/samba.nix) | Network attached storage. 💎 Cross-integration with paperless
|
📁 NAS | 💎 | Samba | [Link](./hosts/sire/guests/samba.nix) | Network attached storage. 💎 Cross-integration with paperless
|
||||||
🧱 Minecraft | 💎 | PaperMC | [Link](./hosts/sire/guests/minecraft.nix) | Minecraft game server. 💎 Autostart on connect, systemd service with background console, automatic backups
|
🧱 Minecraft | 💎 | PaperMC | [Link](./hosts/sire/guests/minecraft.nix) | Minecraft game server. 💎 Autostart on connect, systemd service with background console, automatic backups
|
||||||
|
🛡️ VPN | - | Netbird | [Link](./hosts/ward/guests/netbird.nix) | Internal network gateway and wireguard VPN server with dynamic peer configuration and SSO authentication.
|
||||||
|
📧 Mailserver | 💎 | Stalwart | [Link](./hosts/envoy/stalwart-mail.nix) | Modern mail server setup with custom self-service alias management including Bitwarden integration
|
||||||
📈 Dashboard | – | Grafana | [Link](./hosts/sire/guests/grafana.nix) | Logs and metrics dashboard and alerting
|
📈 Dashboard | – | Grafana | [Link](./hosts/sire/guests/grafana.nix) | Logs and metrics dashboard and alerting
|
||||||
📔 Logs DB | – | Loki | [Link](./hosts/sire/guests/loki.nix) | Central log aggregation service
|
📔 Logs DB | – | Loki | [Link](./hosts/sire/guests/loki.nix) | Central log aggregation service
|
||||||
📔 Logs | – | Promtail | [Link](./modules/promtail.nix) | Log shipping agent
|
📔 Logs | – | Promtail | [Link](./modules/promtail.nix) | Log shipping agent
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
inputs,
|
inputs,
|
||||||
lib,
|
lib,
|
||||||
minimal,
|
minimal,
|
||||||
|
nodes,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
|
@ -74,9 +75,21 @@
|
||||||
# };
|
# };
|
||||||
#};
|
#};
|
||||||
|
|
||||||
nixpkgs.config.permittedInsecurePackages = lib.trace "please remove insecure nix 2.16.2 very fast ok thx bye" [
|
# FIXME: the ui is not directly accessible via environment.systemPackages
|
||||||
"nix-2.16.2"
|
# FIXME: to control it as a user (and to allow SSO) we need to be in the netbird-home group
|
||||||
];
|
services.netbird.ui.enable = true;
|
||||||
|
services.netbird.clients.home = {
|
||||||
|
port = 51820;
|
||||||
|
name = "netbird-home";
|
||||||
|
interface = "wt-home";
|
||||||
|
openFirewall = true;
|
||||||
|
config.ServerSSHAllowed = false;
|
||||||
|
environment = rec {
|
||||||
|
NB_MANAGEMENT_URL = "https://${nodes.sentinel.config.networking.providedDomains.netbird}";
|
||||||
|
NB_ADMIN_URL = NB_MANAGEMENT_URL;
|
||||||
|
NB_HOSTNAME = "home-gateway";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
topology.self.icon = "devices.desktop";
|
topology.self.icon = "devices.desktop";
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,6 +106,7 @@
|
||||||
{}
|
{}
|
||||||
// mkMicrovm "adguardhome"
|
// mkMicrovm "adguardhome"
|
||||||
// mkMicrovm "forgejo"
|
// mkMicrovm "forgejo"
|
||||||
|
// mkMicrovm "home-gateway"
|
||||||
// mkMicrovm "kanidm"
|
// mkMicrovm "kanidm"
|
||||||
// mkMicrovm "netbird"
|
// mkMicrovm "netbird"
|
||||||
// mkMicrovm "radicale"
|
// mkMicrovm "radicale"
|
||||||
|
|
21
hosts/ward/guests/home-gateway.nix
Normal file
21
hosts/ward/guests/home-gateway.nix
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{nodes, ...}: {
|
||||||
|
environment.persistence."/persist".directories = [
|
||||||
|
{
|
||||||
|
directory = "/var/lib/netbird-home";
|
||||||
|
mode = "0700";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
services.netbird.clients.home = {
|
||||||
|
port = 51820;
|
||||||
|
name = "netbird-home";
|
||||||
|
interface = "wt-home";
|
||||||
|
openFirewall = true;
|
||||||
|
config.ServerSSHAllowed = false;
|
||||||
|
environment = rec {
|
||||||
|
NB_MANAGEMENT_URL = "https://${nodes.sentinel.config.networking.providedDomains.netbird}";
|
||||||
|
NB_ADMIN_URL = NB_MANAGEMENT_URL;
|
||||||
|
NB_HOSTNAME = "home-gateway";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
1
hosts/ward/secrets/home-gateway/host.pub
Normal file
1
hosts/ward/secrets/home-gateway/host.pub
Normal file
|
@ -0,0 +1 @@
|
||||||
|
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILlEjX8dXaeZl+ax7YphX9XNr/S9WwKLsgbV7FDjWNzY
|
|
@ -33,5 +33,6 @@
|
||||||
maddy = uidGid 976;
|
maddy = uidGid 976;
|
||||||
minecraft = uidGid 975;
|
minecraft = uidGid 975;
|
||||||
stalwart-mail = uidGid 974;
|
stalwart-mail = uidGid 974;
|
||||||
|
netbird-home = uidGid 973;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
{inputs, ...}: {
|
{inputs, ...}: {
|
||||||
disabledModules = ["services/security/kanidm.nix"];
|
disabledModules = [
|
||||||
|
"services/security/kanidm.nix"
|
||||||
|
"services/networking/netbird.nix"
|
||||||
|
];
|
||||||
|
|
||||||
imports = [
|
imports = [
|
||||||
inputs.agenix-rekey.nixosModules.default
|
inputs.agenix-rekey.nixosModules.default
|
||||||
inputs.agenix.nixosModules.default
|
inputs.agenix.nixosModules.default
|
||||||
|
@ -34,6 +38,7 @@
|
||||||
./distributed-config.nix
|
./distributed-config.nix
|
||||||
./kanidm.nix
|
./kanidm.nix
|
||||||
./meta.nix
|
./meta.nix
|
||||||
|
./netbird-client.nix
|
||||||
./oauth2-proxy.nix
|
./oauth2-proxy.nix
|
||||||
./promtail.nix
|
./promtail.nix
|
||||||
./provided-domains.nix
|
./provided-domains.nix
|
||||||
|
|
513
modules/netbird-client.nix
Normal file
513
modules/netbird-client.nix
Normal file
|
@ -0,0 +1,513 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
inherit
|
||||||
|
(lib)
|
||||||
|
attrValues
|
||||||
|
concatLists
|
||||||
|
concatStringsSep
|
||||||
|
escapeShellArgs
|
||||||
|
filterAttrs
|
||||||
|
getExe
|
||||||
|
literalExpression
|
||||||
|
maintainers
|
||||||
|
makeBinPath
|
||||||
|
mapAttrs'
|
||||||
|
mapAttrsToList
|
||||||
|
mkDefault
|
||||||
|
mkIf
|
||||||
|
mkMerge
|
||||||
|
mkOption
|
||||||
|
mkOptionDefault
|
||||||
|
mkPackageOption
|
||||||
|
mkRemovedOptionModule
|
||||||
|
nameValuePair
|
||||||
|
optional
|
||||||
|
optionalString
|
||||||
|
toShellVars
|
||||||
|
versionAtLeast
|
||||||
|
versionOlder
|
||||||
|
;
|
||||||
|
|
||||||
|
inherit
|
||||||
|
(lib.types)
|
||||||
|
attrsOf
|
||||||
|
bool
|
||||||
|
enum
|
||||||
|
package
|
||||||
|
port
|
||||||
|
str
|
||||||
|
submodule
|
||||||
|
;
|
||||||
|
|
||||||
|
inherit (config.boot) kernelPackages;
|
||||||
|
inherit (config.boot.kernelPackages) kernel;
|
||||||
|
|
||||||
|
cfg = config.services.netbird;
|
||||||
|
|
||||||
|
toClientList = fn: map fn (attrValues cfg.clients);
|
||||||
|
toClientAttrs = fn: mapAttrs' (_: fn) cfg.clients;
|
||||||
|
|
||||||
|
hardenedClients = filterAttrs (_: client: client.hardened) cfg.clients;
|
||||||
|
toHardenedClientList = fn: map fn (attrValues hardenedClients);
|
||||||
|
toHardenedClientAttrs = fn: mapAttrs' (_: fn) hardenedClients;
|
||||||
|
in {
|
||||||
|
meta.maintainers = with maintainers; [
|
||||||
|
misuzu
|
||||||
|
thubrecht
|
||||||
|
nazarewk
|
||||||
|
];
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
(mkRemovedOptionModule ["services" "netbird" "tunnels"]
|
||||||
|
"The option `services.netbird.tunnels` has been renamed to `services.netbird.clients`")
|
||||||
|
];
|
||||||
|
|
||||||
|
options.services.netbird = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Enables backwards compatible Netbird client service.
|
||||||
|
|
||||||
|
This is strictly equivalent to:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
services.netbird.clients.wt0 = {
|
||||||
|
port = 51820;
|
||||||
|
name = "netbird";
|
||||||
|
interface = "wt0";
|
||||||
|
hardened = false;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
package = mkPackageOption pkgs "netbird" {};
|
||||||
|
|
||||||
|
ui.enable = mkOption {
|
||||||
|
type = bool;
|
||||||
|
default = config.services.displayManager.sessionPackages != [];
|
||||||
|
defaultText = literalExpression ''config.services.displayManager.sessionPackages != [ ]'';
|
||||||
|
description = ''
|
||||||
|
Controls presence `netbird-ui` wrappers, defaults to presence of graphical sessions.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
ui.package = mkPackageOption pkgs "netbird-ui" {};
|
||||||
|
|
||||||
|
clients = mkOption {
|
||||||
|
type = attrsOf (
|
||||||
|
submodule (
|
||||||
|
{
|
||||||
|
name,
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}: {
|
||||||
|
options = {
|
||||||
|
port = mkOption {
|
||||||
|
type = port;
|
||||||
|
example = literalExpression "51820";
|
||||||
|
description = ''
|
||||||
|
Port the Netbird client listens on.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
name = mkOption {
|
||||||
|
type = str;
|
||||||
|
default = "netbird-${name}";
|
||||||
|
description = ''
|
||||||
|
Primary name for use in:
|
||||||
|
- systemd service name,
|
||||||
|
- hardened user name and group,
|
||||||
|
- [systemd `*Directory=`](https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#RuntimeDirectory=) names,
|
||||||
|
- desktop application identification,
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
interface = mkOption {
|
||||||
|
type = str;
|
||||||
|
default = "netbird-${name}";
|
||||||
|
description = ''
|
||||||
|
Name of the network interface managed by this client.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
environment = mkOption {
|
||||||
|
type = attrsOf str;
|
||||||
|
defaultText = literalExpression ''
|
||||||
|
{
|
||||||
|
NB_CONFIG = "/var/lib/''${config.name}/config.json";
|
||||||
|
NB_DAEMON_ADDR = "unix:///var/run/''${config.name}/sock";
|
||||||
|
NB_INTERFACE_NAME = config.interface;
|
||||||
|
NB_LOG_FILE = mkOptionDefault "console";
|
||||||
|
NB_LOG_LEVEL = config.logLevel;
|
||||||
|
NB_SERVICE = config.name;
|
||||||
|
NB_WIREGUARD_PORT = toString config.port;
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
Environment for the netbird service, used to pass configuration options.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
autoStart = mkOption {
|
||||||
|
type = bool;
|
||||||
|
default = true;
|
||||||
|
description = ''
|
||||||
|
Start the service with the system.
|
||||||
|
|
||||||
|
As of 2024-02-13 it is not possible to start a Netbird client daemon without immediately
|
||||||
|
connecting to the network, but it is [planned for a near future](https://github.com/netbirdio/netbird/projects/2#card-91718018).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
openFirewall = mkOption {
|
||||||
|
type = bool;
|
||||||
|
default = true;
|
||||||
|
description = ''
|
||||||
|
Opens up firewall `port` for communication between Netbird peers directly over LAN or public IP,
|
||||||
|
without using (internet-hosted) TURN servers as intermediaries.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
hardened = mkOption {
|
||||||
|
type = bool;
|
||||||
|
default = true;
|
||||||
|
description = ''
|
||||||
|
Hardened service:
|
||||||
|
- runs as a dedicated user with minimal set of permissions (see caveats),
|
||||||
|
- restricts daemon configuration socket access to dedicated user group
|
||||||
|
(you can grant access to it with `users.users."<user>".extraGroups = [ "netbird-${name}" ]`),
|
||||||
|
|
||||||
|
Even though the local system resources access is restricted:
|
||||||
|
- `CAP_NET_RAW`, `CAP_NET_ADMIN` and `CAP_BPF` still give unlimited network manipulation possibilites,
|
||||||
|
- older kernels don't have `CAP_BPF` and use `CAP_SYS_ADMIN` instead,
|
||||||
|
|
||||||
|
Known security features that are not (yet) integrated into the module:
|
||||||
|
- 2024-02-14: `rosenpass` is an experimental feature configurable solely
|
||||||
|
through `--enable-rosenpass` flag on the `netbird up` command,
|
||||||
|
see [the docs](https://docs.netbird.io/how-to/enable-post-quantum-cryptography)
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
logLevel = mkOption {
|
||||||
|
type = enum [
|
||||||
|
# logrus loglevels
|
||||||
|
"panic"
|
||||||
|
"fatal"
|
||||||
|
"error"
|
||||||
|
"warn"
|
||||||
|
"warning"
|
||||||
|
"info"
|
||||||
|
"debug"
|
||||||
|
"trace"
|
||||||
|
];
|
||||||
|
default = "info";
|
||||||
|
description = "Log level of the Netbird daemon.";
|
||||||
|
};
|
||||||
|
|
||||||
|
wrapper = mkOption {
|
||||||
|
type = package;
|
||||||
|
internal = true;
|
||||||
|
default = let
|
||||||
|
makeWrapperArgs = concatLists (
|
||||||
|
mapAttrsToList
|
||||||
|
(key: value: ["--set-default" key value])
|
||||||
|
config.environment
|
||||||
|
);
|
||||||
|
in
|
||||||
|
pkgs.stdenv.mkDerivation {
|
||||||
|
name = "${cfg.package.name}-wrapper-${name}";
|
||||||
|
meta.mainProgram = "netbird-${name}";
|
||||||
|
nativeBuildInputs = with pkgs; [makeWrapper];
|
||||||
|
phases = ["installPhase"];
|
||||||
|
installPhase = concatStringsSep "\n" [
|
||||||
|
''
|
||||||
|
mkdir -p "$out/bin"
|
||||||
|
makeWrapper ${lib.getExe cfg.package} "$out/bin/netbird-${name}" \
|
||||||
|
${escapeShellArgs makeWrapperArgs}
|
||||||
|
''
|
||||||
|
(optionalString cfg.ui.enable ''
|
||||||
|
# netbird-ui doesn't support envvars
|
||||||
|
makeWrapper ${lib.getExe cfg.ui.package}-ui "$out/bin/netbird-ui-${name}" \
|
||||||
|
--add-flags '--daemon-addr=${config.environment.NB_DAEMON_ADDR}'
|
||||||
|
|
||||||
|
mkdir -p "$out/share/applications"
|
||||||
|
substitute ${cfg.ui.package}/share/applications/netbird.desktop \
|
||||||
|
"$out/share/applications/netbird-${name}.desktop" \
|
||||||
|
--replace-fail 'Name=Netbird' "Name=Netbird @ ${config.name}" \
|
||||||
|
--replace-fail '${lib.getExe cfg.ui.package}-ui' "$out/bin/netbird-ui-${name}"
|
||||||
|
'')
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# see https://github.com/netbirdio/netbird/blob/88747e3e0191abc64f1e8c7ecc65e5e50a1527fd/client/internal/config.go#L49-L82
|
||||||
|
config = mkOption {
|
||||||
|
inherit (pkgs.formats.json {}) type;
|
||||||
|
defaultText = literalExpression ''
|
||||||
|
{
|
||||||
|
DisableAutoConnect = !config.autoStart;
|
||||||
|
WgIface = config.interface;
|
||||||
|
WgPort = config.port;
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
description = ''
|
||||||
|
Additional configuration that exists before the first start and
|
||||||
|
later overrides the existing values in `config.json`.
|
||||||
|
|
||||||
|
It is mostly helpful to manage configuration ignored/not yet implemented
|
||||||
|
outside of `netbird up` invocation.
|
||||||
|
|
||||||
|
WARNING: this is not an upstream feature, it could break in the future
|
||||||
|
(by having lower priority) after upstream implements an equivalent.
|
||||||
|
|
||||||
|
It is implemented as a `preStart` script which overrides `config.json`
|
||||||
|
with content of `/etc/netbird-${name}/config.d/*.json` files.
|
||||||
|
This option manages specifically `50-nixos.json` file.
|
||||||
|
|
||||||
|
Consult [the source code](https://github.com/netbirdio/netbird/blob/88747e3e0191abc64f1e8c7ecc65e5e50a1527fd/client/internal/config.go#L49-L82)
|
||||||
|
or inspect existing file for a complete list of available configurations.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config.environment = {
|
||||||
|
NB_CONFIG = "/var/lib/${config.name}/config.json";
|
||||||
|
NB_DAEMON_ADDR = "unix:///var/run/${config.name}/sock";
|
||||||
|
NB_INTERFACE_NAME = config.interface;
|
||||||
|
NB_LOG_FILE = mkOptionDefault "console";
|
||||||
|
NB_LOG_LEVEL = config.logLevel;
|
||||||
|
NB_SERVICE = config.name;
|
||||||
|
NB_WIREGUARD_PORT = toString config.port;
|
||||||
|
};
|
||||||
|
|
||||||
|
config.config = {
|
||||||
|
DisableAutoConnect = !config.autoStart;
|
||||||
|
WgIface = config.interface;
|
||||||
|
WgPort = config.port;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
default = {};
|
||||||
|
description = ''
|
||||||
|
Attribute set of Netbird client daemons, by default each one will:
|
||||||
|
|
||||||
|
1. be manageable using dedicated tooling:
|
||||||
|
- `netbird-<name>` script,
|
||||||
|
- `Netbird - netbird-<name>` graphical interface when appropriate (see `ui.enable`),
|
||||||
|
2. run as a `netbird-<name>.service`,
|
||||||
|
3. listen for incoming remote connections on the port `51830` (`openFirewall` by default),
|
||||||
|
4. manage the `netbird-<name>` wireguard interface,
|
||||||
|
5. use the `/var/lib/netbird-<name>/config.json` configuration file,
|
||||||
|
6. override `/var/lib/netbird-<name>/config.json` with values from `/etc/netbird-<name>/config.d/*.json`,
|
||||||
|
7. (`hardened`) be locally manageable by `netbird-<name>` system group,
|
||||||
|
|
||||||
|
With following caveats:
|
||||||
|
|
||||||
|
- multiple daemons will interfere with each other's DNS resolution of `netbird.cloud`, but
|
||||||
|
should remain fully operational otherwise.
|
||||||
|
Setting up custom (non-conflicting) DNS zone is currently possible only when self-hosting.
|
||||||
|
'';
|
||||||
|
example = lib.literalExpression ''
|
||||||
|
{
|
||||||
|
services.netbird.clients.wt0.port = 51820;
|
||||||
|
services.netbird.clients.personal.port = 51821;
|
||||||
|
services.netbird.clients.work1.port = 51822;
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkMerge [
|
||||||
|
(mkIf cfg.enable (
|
||||||
|
let
|
||||||
|
name = "wt0";
|
||||||
|
client = cfg.clients."${name}";
|
||||||
|
in {
|
||||||
|
services.netbird.clients."${name}" = {
|
||||||
|
port = mkDefault 51820;
|
||||||
|
name = mkDefault "netbird";
|
||||||
|
interface = mkDefault "wt0";
|
||||||
|
hardened = mkDefault false;
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.systemPackages = [
|
||||||
|
(lib.hiPrio (pkgs.runCommand "${name}-as-default" {} ''
|
||||||
|
mkdir -p "$out/bin"
|
||||||
|
for binary in netbird ${optionalString cfg.ui.enable "netbird-ui"} ; do
|
||||||
|
ln -s "${client.wrapper}/bin/$binary-${name}" "$out/bin/$binary"
|
||||||
|
done
|
||||||
|
''))
|
||||||
|
];
|
||||||
|
}
|
||||||
|
))
|
||||||
|
{
|
||||||
|
boot.extraModulePackages =
|
||||||
|
optional
|
||||||
|
(cfg.clients != {} && (versionOlder kernel.version "5.6"))
|
||||||
|
kernelPackages.wireguard;
|
||||||
|
|
||||||
|
environment.systemPackages =
|
||||||
|
toClientList (client: client.wrapper)
|
||||||
|
# omitted due to https://github.com/netbirdio/netbird/issues/1562
|
||||||
|
#++ optional (cfg.clients != { }) cfg.package
|
||||||
|
# omitted due to https://github.com/netbirdio/netbird/issues/1581
|
||||||
|
#++ optional (cfg.clients != { } && cfg.ui.enable) cfg.ui.package
|
||||||
|
;
|
||||||
|
|
||||||
|
networking.dhcpcd.denyInterfaces = toClientList (client: client.interface);
|
||||||
|
networking.networkmanager.unmanaged = toClientList (client: "interface-name:${client.interface}");
|
||||||
|
|
||||||
|
networking.firewall.allowedUDPPorts = concatLists (toClientList (client: optional client.openFirewall client.port));
|
||||||
|
|
||||||
|
systemd.network.networks = mkIf config.networking.useNetworkd (toClientAttrs (
|
||||||
|
client:
|
||||||
|
nameValuePair "50-netbird-${client.interface}" {
|
||||||
|
matchConfig = {
|
||||||
|
Name = client.interface;
|
||||||
|
};
|
||||||
|
linkConfig = {
|
||||||
|
Unmanaged = true;
|
||||||
|
ActivationPolicy = "manual";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
|
environment.etc = toClientAttrs (client:
|
||||||
|
nameValuePair "${client.name}/config.d/50-nixos.json" {
|
||||||
|
text = builtins.toJSON client.config;
|
||||||
|
mode = "0444";
|
||||||
|
});
|
||||||
|
|
||||||
|
systemd.services = toClientAttrs (client:
|
||||||
|
nameValuePair client.name {
|
||||||
|
description = "A WireGuard-based mesh network that connects your devices into a single private network";
|
||||||
|
|
||||||
|
documentation = ["https://netbird.io/docs/"];
|
||||||
|
|
||||||
|
after = ["network.target"];
|
||||||
|
wantedBy = ["multi-user.target"];
|
||||||
|
|
||||||
|
path = optional (!config.services.resolved.enable) pkgs.openresolv;
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = "${getExe client.wrapper} service run";
|
||||||
|
Restart = "always";
|
||||||
|
|
||||||
|
RuntimeDirectory = client.name;
|
||||||
|
RuntimeDirectoryMode = mkDefault "0755";
|
||||||
|
ConfigurationDirectory = client.name;
|
||||||
|
StateDirectory = client.name;
|
||||||
|
StateDirectoryMode = "0700";
|
||||||
|
|
||||||
|
WorkingDirectory = "/var/lib/${client.name}";
|
||||||
|
};
|
||||||
|
|
||||||
|
unitConfig = {
|
||||||
|
StartLimitInterval = 5;
|
||||||
|
StartLimitBurst = 10;
|
||||||
|
};
|
||||||
|
|
||||||
|
stopIfChanged = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
# Hardening section
|
||||||
|
(mkIf (hardenedClients != {}) {
|
||||||
|
users.groups = toHardenedClientAttrs (client: nameValuePair client.name {});
|
||||||
|
users.users = toHardenedClientAttrs (client:
|
||||||
|
nameValuePair client.name {
|
||||||
|
isSystemUser = true;
|
||||||
|
home = "/var/lib/${client.name}";
|
||||||
|
group = client.name;
|
||||||
|
});
|
||||||
|
|
||||||
|
systemd.services = toHardenedClientAttrs (client:
|
||||||
|
nameValuePair client.name (mkIf client.hardened {
|
||||||
|
serviceConfig = {
|
||||||
|
RuntimeDirectoryMode = "0750";
|
||||||
|
|
||||||
|
User = client.name;
|
||||||
|
Group = client.name;
|
||||||
|
|
||||||
|
# settings implied by DynamicUser=true, without actully using it,
|
||||||
|
# see https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#DynamicUser=
|
||||||
|
RemoveIPC = true;
|
||||||
|
PrivateTmp = true;
|
||||||
|
ProtectSystem = "strict";
|
||||||
|
ProtectHome = "yes";
|
||||||
|
|
||||||
|
AmbientCapabilities =
|
||||||
|
[
|
||||||
|
# see https://man7.org/linux/man-pages/man7/capabilities.7.html
|
||||||
|
# see https://docs.netbird.io/how-to/installation#running-net-bird-in-docker
|
||||||
|
#
|
||||||
|
# seems to work fine without CAP_SYS_ADMIN and CAP_SYS_RESOURCE
|
||||||
|
# CAP_NET_BIND_SERVICE could be added to allow binding on low ports, but is not required,
|
||||||
|
# see https://github.com/netbirdio/netbird/pull/1513
|
||||||
|
|
||||||
|
# failed creating tunnel interface wt-priv: [operation not permitted
|
||||||
|
"CAP_NET_ADMIN"
|
||||||
|
# failed to pull up wgInterface [wt-priv]: failed to create ipv4 raw socket: socket: operation not permitted
|
||||||
|
"CAP_NET_RAW"
|
||||||
|
]
|
||||||
|
# required for eBPF filter, used to be subset of CAP_SYS_ADMIN
|
||||||
|
++ optional (versionAtLeast kernel.version "5.8") "CAP_BPF"
|
||||||
|
++ optional (versionOlder kernel.version "5.8") "CAP_SYS_ADMIN";
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
|
||||||
|
# see https://github.com/systemd/systemd/blob/17f3e91e8107b2b29fe25755651b230bbc81a514/src/resolve/org.freedesktop.resolve1.policy#L43-L43
|
||||||
|
security.polkit.extraConfig = mkIf config.services.resolved.enable ''
|
||||||
|
// systemd-resolved access for Netbird clients
|
||||||
|
polkit.addRule(function(action, subject) {
|
||||||
|
var actions = [
|
||||||
|
"org.freedesktop.resolve1.set-dns-servers",
|
||||||
|
"org.freedesktop.resolve1.set-domains",
|
||||||
|
];
|
||||||
|
var users = ${builtins.toJSON (toHardenedClientList (client: client.name))};
|
||||||
|
|
||||||
|
if (actions.indexOf(action.id) >= 0 && users.indexOf(subject.user) >= 0 ) {
|
||||||
|
return polkit.Result.YES;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
'';
|
||||||
|
})
|
||||||
|
# migration & temporary fixups section
|
||||||
|
{
|
||||||
|
systemd.services = toClientAttrs (client:
|
||||||
|
nameValuePair client.name {
|
||||||
|
preStart = ''
|
||||||
|
set -eEuo pipefail
|
||||||
|
${optionalString (client.logLevel == "trace" || client.logLevel == "debug") "set -x"}
|
||||||
|
|
||||||
|
PATH="${makeBinPath (with pkgs; [coreutils jq diffutils])}:$PATH"
|
||||||
|
export ${toShellVars client.environment}
|
||||||
|
|
||||||
|
# merge /etc/${client.name}/config.d' into "$NB_CONFIG"
|
||||||
|
{
|
||||||
|
test -e "$NB_CONFIG" || echo -n '{}' > "$NB_CONFIG"
|
||||||
|
|
||||||
|
# merge config.d with "$NB_CONFIG" into "$NB_CONFIG.new"
|
||||||
|
jq -sS 'reduce .[] as $i ({}; . * $i)' \
|
||||||
|
"$NB_CONFIG" \
|
||||||
|
/etc/${client.name}/config.d/*.json \
|
||||||
|
> "$NB_CONFIG.new"
|
||||||
|
|
||||||
|
echo "Comparing $NB_CONFIG with $NB_CONFIG.new ..."
|
||||||
|
if ! diff <(jq -S <"$NB_CONFIG") "$NB_CONFIG.new" ; then
|
||||||
|
echo "Updating $NB_CONFIG ..."
|
||||||
|
mv "$NB_CONFIG.new" "$NB_CONFIG"
|
||||||
|
else
|
||||||
|
echo "Files are the same, not doing anything."
|
||||||
|
rm "$NB_CONFIG.new"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
|
@ -7,7 +7,10 @@
|
||||||
autoRepeatDelay = 235;
|
autoRepeatDelay = 235;
|
||||||
autoRepeatInterval = 60;
|
autoRepeatInterval = 60;
|
||||||
videoDrivers = ["modesetting"];
|
videoDrivers = ["modesetting"];
|
||||||
libinput = {
|
xkb.layout = "de";
|
||||||
|
xkb.variant = "nodeadkeys";
|
||||||
|
};
|
||||||
|
services.libinput = {
|
||||||
enable = true;
|
enable = true;
|
||||||
mouse = {
|
mouse = {
|
||||||
accelProfile = "flat";
|
accelProfile = "flat";
|
||||||
|
@ -21,9 +24,6 @@
|
||||||
# disableWhileTyping = true;
|
# disableWhileTyping = true;
|
||||||
# };
|
# };
|
||||||
};
|
};
|
||||||
xkb.layout = "de";
|
|
||||||
xkb.variant = "nodeadkeys";
|
|
||||||
};
|
|
||||||
services.autorandr.enable = true;
|
services.autorandr.enable = true;
|
||||||
|
|
||||||
# Enable for Xorg debugging
|
# Enable for Xorg debugging
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,10 @@
|
||||||
|
age-encryption.org/v1
|
||||||
|
-> X25519 v3+XpEnInoSpWE3VkLNhHNUNQh3PxhSuBm+p3j6MJ34
|
||||||
|
+SQHfnlhgb1CCMkYwV/rHVuXSO+DcE8+vYLUPJfwoag
|
||||||
|
-> piv-p256 xqSe8Q A2NE5AmI0n5mSg0r/FFoZiNY17BY6fAEZBi+3J9bxKaw
|
||||||
|
a2pLqvnKezIzqL+B3gXSwabbNICIeFNujhOvNsmTPnU
|
||||||
|
-> OH012L^s-grease ~]V: {3[|q
|
||||||
|
HhrT/eZtP08VJEo2pNrzB+lDqnr+3GxzMo+BbaA
|
||||||
|
--- wYiApYLclfL5UFkVivNclukunmyxJEKbJfF89NUbgnE
|
||||||
|
űË殿ŚslÓNňFĆW©�Ť·hv$äXŮf óQ@ЇĺxµĺpIYѸ̸“:-M€pA÷×
|
||||||
|
ć^Rg®Ëíć™)Qüô$eóˇ98wF
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,7 @@
|
||||||
|
age-encryption.org/v1
|
||||||
|
-> ssh-ed25519 1tdZKQ x15cWg4EVxPkDFiC/LX0ZkxemeZ/kBNoFb3jiJlZVk4
|
||||||
|
vynUKyQr3lLcF9tlD6PgEl7VYwWVD7IAW7pHOK2MPow
|
||||||
|
-> Z[gKR-grease m 8Dw~,5" c@@SK%(= ED
|
||||||
|
biT3jfJ3Ay60Mw
|
||||||
|
--- YYo/rkngwrmOVNw4JujU1PURW20kJZ4LHPTfLaX/5+k
|
||||||
|
4–âcœúwÜ7óó‰@Í úsÑìÒ~Ð�¶?cŒ»=aÁ§3•ŒF{¶9MkÝ+&zLëþ`¦x]=LÆ›A̶lŸnŠ!Â4Ë
|
Binary file not shown.
|
@ -0,0 +1,8 @@
|
||||||
|
age-encryption.org/v1
|
||||||
|
-> ssh-ed25519 AIXmkg HkcSDJOMqSmGcZRWPrztDY/DmPemcu+dXLVzoKJmGVA
|
||||||
|
FMS5I9fpG7epGW6FU+gXB5ZmVrma2iJTO/FlfReJrx0
|
||||||
|
-> >CWFj-grease AQ(U
|
||||||
|
0Sq4jSIQVX6OUzyWZZhnYHgxHEzDb0Lt+U1wl9dVWK2mODpOMfx/Q3OihTVALOHf
|
||||||
|
3I1huPPQy+ZYlErp
|
||||||
|
--- QnFS37Svotfos23OvMLBVE2NjMqdKCAihbg6OIFhcaA
|
||||||
|
戯゚fP)��Kセ|Mbァシチコニp;売/��?喫"TスVチ$滅=エX漉カ爍いHラF���'ス�ヨ姆I��%ゥヌⅢヘ栁
|
Loading…
Add table
Add a link
Reference in a new issue