···26262727rustPlatform.buildRustPackage rec {
2828 pname = "ripgrep";
2929- version = "12.1.1";
2929+ version = "14.1.1";
30303131 src = fetchFromGitHub {
3232 owner = "BurntSushi";
3333 repo = pname;
3434 rev = version;
3535- hash = "sha256-+s5RBC3XSgb8omTbUNLywZnP6jSxZBKSS1BmXOjRF8M=";
3535+ hash = "sha256-gyWnahj1A+iXUQlQ1O1H1u7K5euYQOld9qWm99Vjaeg=";
3636 };
37373838- cargoHash = "sha256-jtBw4ahSl88L0iuCXxQgZVm1EcboWRJMNtjxLVTtzts=";
3838+ useFetchCargoVendor = true;
3939+ cargoHash = "sha256-9atn5qyBDy4P6iUoHFhg+TV6Ur71fiah4oTJbBMeEy4=";
39404041 meta = {
4142 description = "Fast line-oriented regex search tool, similar to ag and ack";
···6364}
6465```
65666666-Exception: If the application has cargo `git` dependencies, the `cargoHash`
6767-approach will not work by default. In this case, you can set `useFetchCargoVendor = true`
6868-to use an improved fetcher that supports handling `git` dependencies.
6969-7070-```nix
7171-{
7272- useFetchCargoVendor = true;
7373- cargoHash = "sha256-RqPVFovDaD2rW31HyETJfQ0qVwFxoGEvqkIgag3H6KU=";
7474-}
7575-```
7676-7777-If this method still does not work, you can resort to copying the `Cargo.lock` file into nixpkgs
6767+If this method does not work, you can resort to copying the `Cargo.lock` file into nixpkgs
7868and importing it as described in the [next section](#importing-a-cargo.lock-file).
79698070Both types of hashes are permitted when contributing to nixpkgs. The
···119109 hash = "sha256-aDQA4A5mScX9or3Lyiv/5GyAehidnpKKE0grhbP1Ctc=";
120110 };
121111122122- cargoHash = "sha256-tbrTbutUs5aPSV+yE0IBUZAAytgmZV7Eqxia7g+9zRs=";
112112+ useFetchCargoVendor = true;
113113+ cargoHash = "sha256-iDYh52rj1M5Uupvbx2WeDd/jvQZ+2A50V5rp5e2t7q4=";
123114 cargoDepsName = pname;
124115125116 # ...
···443434444435Since network access is not allowed in sandboxed builds, Rust crate
445436dependencies need to be retrieved using a fetcher. `rustPlatform`
446446-provides the `fetchCargoTarball` fetcher, which vendors all
437437+provides the `fetchCargoVendor` fetcher, which vendors all
447438dependencies of a crate. For example, given a source path `src`
448448-containing `Cargo.toml` and `Cargo.lock`, `fetchCargoTarball`
439439+containing `Cargo.toml` and `Cargo.lock`, `fetchCargoVendor`
449440can be used as follows:
450441451442```nix
452443{
453453- cargoDeps = rustPlatform.fetchCargoTarball {
444444+ cargoDeps = rustPlatform.fetchCargoVendor {
454445 inherit src;
455446 hash = "sha256-BoHIN/519Top1NUBjpB/oEMqi86Omt3zTQcXFWqrek0=";
456447 };
···482473```
483474484475If a `Cargo.lock` file is available, you can alternatively use the
485485-`importCargoLock` function. In contrast to `fetchCargoTarball`, this
476476+`importCargoLock` function. In contrast to `fetchCargoVendor`, this
486477function does not require a hash (unless git dependencies are used)
487478and fetches every dependency as a separate fixed-output derivation.
488479`importCargoLock` can be used as follows:
···521512`rustPlatform` provides the following hooks to automate Cargo builds:
522513523514* `cargoSetupHook`: configure Cargo to use dependencies vendored
524524- through `fetchCargoTarball`. This hook uses the `cargoDeps`
525525- environment variable to find the vendored dependencies. If a project
526526- already vendors its dependencies, the variable `cargoVendorDir` can
527527- be used instead. When the `Cargo.toml`/`Cargo.lock` files are not in
528528- `sourceRoot`, then the optional `cargoRoot` is used to specify the
529529- Cargo root directory relative to `sourceRoot`.
515515+ through `fetchCargoVendor` or `importCargoLock`. This hook uses the
516516+ `cargoDeps` environment variable to find the vendored
517517+ dependencies. If a project already vendors its dependencies, the
518518+ variable `cargoVendorDir` can be used instead. When the
519519+ `Cargo.toml`/`Cargo.lock` files are not in `sourceRoot`, then the
520520+ optional `cargoRoot` is used to specify the Cargo root directory
521521+ relative to `sourceRoot`.
530522* `cargoBuildHook`: use Cargo to build a crate. If the crate to be
531523 built is a crate in e.g. a Cargo workspace, the relative path to the
532524 crate to build can be set through the optional `buildAndTestSubdir`
···557549#### Python package using `setuptools-rust` {#python-package-using-setuptools-rust}
558550559551For Python packages using `setuptools-rust`, you can use
560560-`fetchCargoTarball` and `cargoSetupHook` to retrieve and set up Cargo
552552+`fetchCargoVendor` and `cargoSetupHook` to retrieve and set up Cargo
561553dependencies. The build itself is then performed by
562554`buildPythonPackage`.
563555···586578 hash = "sha256-rQ2hRV52naEf6PvRsWVCTN7B1oXAQGmnpJw4iIdhamw=";
587579 };
588580589589- cargoDeps = rustPlatform.fetchCargoTarball {
581581+ cargoDeps = rustPlatform.fetchCargoVendor {
590582 inherit pname version src sourceRoot;
591591- hash = "sha256-miW//pnOmww2i6SOGbkrAIdc/JMDT4FJLqdMFojZeoY=";
583583+ hash = "sha256-RO1m8wEd5Ic2M9q+zFHeCJWhCr4Sv3CEWd08mkxsBec=";
592584 };
593585594586 sourceRoot = "${src.name}/bindings/python";
···609601specify the crate's directory relative to `sourceRoot`. In the
610602following example, the crate is in `src/rust`, as specified in the
611603`cargoRoot` attribute. Note that we also need to specify the correct
612612-path for `fetchCargoTarball`.
604604+path for `fetchCargoVendor`.
613605614606```nix
615607···629621 hash = "sha256-xGDilsjLOnls3MfVbGKnj80KCUCczZxlis5PmHzpNcQ=";
630622 };
631623632632- cargoDeps = rustPlatform.fetchCargoTarball {
624624+ cargoDeps = rustPlatform.fetchCargoVendor {
633625 inherit pname version src;
634626 sourceRoot = "${pname}-${version}/${cargoRoot}";
635635- hash = "sha256-PS562W4L1NimqDV2H0jl5vYhL08H9est/pbIxSdYVfo=";
627627+ hash = "sha256-ctUt8maCjnGddKPf+Ii++wKsAXA1h+JM6zKQNXXwJqQ=";
636628 };
637629638630 cargoRoot = "src/rust";
···644636#### Python package using `maturin` {#python-package-using-maturin}
645637646638Python packages that use [Maturin](https://github.com/PyO3/maturin)
647647-can be built with `fetchCargoTarball`, `cargoSetupHook`, and
639639+can be built with `fetchCargoVendor`, `cargoSetupHook`, and
648640`maturinBuildHook`. For example, the following (partial) derivation
649649-builds the `retworkx` Python package. `fetchCargoTarball` and
641641+builds the `retworkx` Python package. `fetchCargoVendor` and
650642`cargoSetupHook` are used to fetch and set up the crate dependencies.
651643`maturinBuildHook` is used to perform the build.
652644···669661 hash = "sha256-11n30ldg3y3y6qxg3hbj837pnbwjkqw3nxq6frds647mmmprrd20=";
670662 };
671663672672- cargoDeps = rustPlatform.fetchCargoTarball {
664664+ cargoDeps = rustPlatform.fetchCargoVendor {
673665 inherit pname version src;
674674- hash = "sha256-heOBK8qi2nuc/Ib+I/vLzZ1fUUD/G/KTw9d7M4Hz5O0=";
666666+ hash = "sha256-QsPCQhNZKYCAogQriQX6pBYQUDAIUsEdRX/63dAqTzg=";
675667 };
676668677669 nativeBuildInputs = with rustPlatform; [ cargoSetupHook maturinBuildHook ];
···682674683675#### Rust package built with `meson` {#rust-package-built-with-meson}
684676685685-Some projects, especially GNOME applications, are built with the Meson Build System instead of calling Cargo directly. Using `rustPlatform.buildRustPackage` may successfully build the main program, but related files will be missing. Instead, you need to set up Cargo dependencies with `fetchCargoTarball` and `cargoSetupHook` and leave the rest to Meson. `rust` and `cargo` are still needed in `nativeBuildInputs` for Meson to use.
677677+Some projects, especially GNOME applications, are built with the Meson Build System instead of calling Cargo directly. Using `rustPlatform.buildRustPackage` may successfully build the main program, but related files will be missing. Instead, you need to set up Cargo dependencies with `fetchCargoVendor` and `cargoSetupHook` and leave the rest to Meson. `rust` and `cargo` are still needed in `nativeBuildInputs` for Meson to use.
686678687679```nix
688680{ lib
···713705 hash = "sha256-PrNPprSS98yN8b8yw2G6hzTSaoE65VbsM3q7FVB4mds=";
714706 };
715707716716- cargoDeps = rustPlatform.fetchCargoTarball {
708708+ cargoDeps = rustPlatform.fetchCargoVendor {
717709 inherit pname version src;
718718- hash = "sha256-8fa3fa+sFi5H+49B5sr2vYPkp9C9s6CcE0zv4xB8gww=";
710710+ hash = "sha256-eR1ZGtTZQNhofFUEjI7IX16sMKPJmAl7aIFfPJukecg=";
719711 };
720712721713 nativeBuildInputs = [
···998990999991rustPlatform.buildRustPackage rec {
1000992 pname = "ripgrep";
10011001- version = "12.1.1";
993993+ version = "14.1.1";
10029941003995 src = fetchFromGitHub {
1004996 owner = "BurntSushi";
1005997 repo = "ripgrep";
1006998 rev = version;
10071007- hash = "sha256-+s5RBC3XSgb8omTbUNLywZnP6jSxZBKSS1BmXOjRF8M=";
999999+ hash = "sha256-gyWnahj1A+iXUQlQ1O1H1u7K5euYQOld9qWm99Vjaeg=";
10081000 };
1009100110101010- cargoHash = "sha256-l1vL2ZdtDRxSGvP0X/l3nMw8+6WF67KPutJEzUROjg8=";
10021002+ useFetchCargoVendor = true;
10031003+ cargoHash = "sha256-9atn5qyBDy4P6iUoHFhg+TV6Ur71fiah4oTJbBMeEy4=";
1011100410121005 doCheck = false;
10131006
···379379 as before, you can use plugins like `python3Packages.jax-cuda12-plugin`.
380380381381382382+- `services.netbird.tunnels` was renamed to [`services.netbird.clients`](#opt-services.netbird.clients),
383383+ hardened (using dedicated less-privileged users) and significantly extended.
384384+382385<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
383386384387## Other Notable Changes {#sec-release-25.05-notable-changes}
+1-1
nixos/modules/programs/wayland/hyprland.nix
···139139 ] "Nvidia patches are no longer needed")
140140 ];
141141142142- meta.maintainers = with lib.maintainers; [ fufexan ];
142142+ meta.maintainers = lib.teams.hyprland.members;
143143}
···2233## Quickstart {#module-services-netbird-quickstart}
4455-The absolute minimal configuration for the netbird daemon looks like this:
55+The absolute minimal configuration for the Netbird client daemon looks like this:
6677```nix
88{
···1313This will set up a netbird service listening on the port `51820` associated to the
1414`wt0` interface.
15151616-It is strictly equivalent to setting:
1616+Which is equivalent to:
17171818```nix
1919{
2020- services.netbird.tunnels.wt0.stateDir = "netbird";
2020+ services.netbird.clients.wt0 = {
2121+ port = 51820;
2222+ name = "netbird";
2323+ interface = "wt0";
2424+ hardened = false;
2525+ };
2126}
2227```
23282424-The `enable` option is mainly kept for backward compatibility, as defining netbird
2525-tunnels through the `tunnels` option is more expressive.
2929+This will set up a `netbird.service` listening on the port `51820` associated to the
3030+`wt0` interface. There will also be `netbird-wt0` binary installed in addition to `netbird`.
3131+3232+see [clients](#opt-services.netbird.clients) option documentation for more details.
26332734## Multiple connections setup {#module-services-netbird-multiple-connections}
28352929-Using the `services.netbird.tunnels` option, it is also possible to define more than
3636+Using the `services.netbird.clients` option, it is possible to define more than
3037one netbird service running at the same time.
31383232-The following configuration will start a netbird daemon using the interface `wt1` and
3333-the port 51830. Its configuration file will then be located at `/var/lib/netbird-wt1/config.json`.
3939+You must at least define a `port` for the service to listen on, the rest is optional:
34403541```nix
3642{
3737- services.netbird.tunnels = {
3838- wt1 = {
3939- port = 51830;
4040- };
4141- };
4343+ services.netbird.clients.wt1.port = 51830;
4444+ services.netbird.clients.wt2.port = 51831;
4245}
4346```
44474545-To interact with it, you will need to specify the correct daemon address:
4848+see [clients](#opt-services.netbird.clients) option documentation for more details.
46494747-```bash
4848-netbird --daemon-addr unix:///var/run/netbird-wt1/sock ...
4949-```
5050-5151-The address will by default be `unix:///var/run/netbird-<name>`.
5050+## Exposing services internally on the Netbird network {#module-services-netbird-firewall}
52515353-It is also possible to overwrite default options passed to the service, for
5454-example:
5252+You can easily expose services exclusively to Netbird network by combining
5353+[`networking.firewall.interfaces`](#opt-networking.firewall.interfaces) rules
5454+with [`interface`](#opt-services.netbird.clients._name_.interface) names:
55555656```nix
5757{
5858- services.netbird.tunnels.wt1.environment = {
5959- NB_DAEMON_ADDR = "unix:///var/run/toto.sock";
5858+ services.netbird.clients.priv.port = 51819;
5959+ services.netbird.clients.work.port = 51818;
6060+ networking.firewall.interfaces = {
6161+ "${config.services.netbird.clients.priv.interface}" = {
6262+ allowedUDPPorts = [ 1234 ];
6363+ };
6464+ "${config.services.netbird.clients.work.interface}" = {
6565+ allowedTCPPorts = [ 8080 ];
6666+ };
6067 };
6168}
6269```
63706464-This will set the socket to interact with the netbird service to `/var/run/toto.sock`.
7171+### Additional customizations {#module-services-netbird-customization}
7272+7373+Each Netbird client service by default:
7474+7575+- runs in a [hardened](#opt-services.netbird.clients._name_.hardened) mode,
7676+- starts with the system,
7777+- [opens up a firewall](#opt-services.netbird.clients._name_.openFirewall) for direct (without TURN servers)
7878+ peer-to-peer communication,
7979+- can be additionally configured with environment variables,
8080+- automatically determines whether `netbird-ui-<name>` should be available,
8181+8282+[autoStart](#opt-services.netbird.clients._name_.autoStart) allows you to start the client (an actual systemd service)
8383+on demand, for example to connect to work-related or otherwise conflicting network only when required.
8484+See the option description for more information.
8585+8686+[environment](#opt-services.netbird.clients._name_.environment) allows you to pass additional configurations
8787+through environment variables, but special care needs to be taken for overriding config location and
8888+daemon address due [hardened](#opt-services.netbird.clients._name_.hardened) option.
+534-48
nixos/modules/services/networking/netbird.nix
···44 pkgs,
55 ...
66}:
77-87let
98 inherit (lib)
1010- attrNames
99+ attrValues
1010+ concatLists
1111+ concatStringsSep
1212+ escapeShellArgs
1313+ filterAttrs
1114 getExe
1215 literalExpression
1316 maintainers
1717+ makeBinPath
1418 mapAttrs'
1919+ mapAttrsToList
2020+ mkAliasOptionModule
1521 mkDefault
1616- mkEnableOption
1722 mkIf
1823 mkMerge
1924 mkOption
2525+ mkOptionDefault
2026 mkPackageOption
2127 nameValuePair
2228 optional
2929+ optionalAttrs
3030+ optionalString
3131+ toShellVars
3232+ versionAtLeast
2333 versionOlder
2434 ;
25352636 inherit (lib.types)
2737 attrsOf
3838+ bool
3939+ enum
4040+ nullOr
4141+ package
4242+ path
2843 port
2944 str
3045 submodule
3146 ;
32473333- kernel = config.boot.kernelPackages;
4848+ inherit (config.boot) kernelPackages;
4949+ inherit (config.boot.kernelPackages) kernel;
34503551 cfg = config.services.netbird;
5252+5353+ toClientList = fn: map fn (attrValues cfg.clients);
5454+ toClientAttrs = fn: mapAttrs' (_: fn) cfg.clients;
5555+5656+ hardenedClients = filterAttrs (_: client: client.hardened) cfg.clients;
5757+ toHardenedClientList = fn: map fn (attrValues hardenedClients);
5858+ toHardenedClientAttrs = fn: mapAttrs' (_: fn) hardenedClients;
5959+6060+ mkBinName =
6161+ client: name:
6262+ if client.bin.suffix == "" || client.bin.suffix == "netbird" then
6363+ name
6464+ else
6565+ "${name}-${client.bin.suffix}";
6666+6767+ nixosConfig = config;
3668in
3769{
3838- meta.maintainers = with maintainers; [ ];
7070+ meta.maintainers = with maintainers; [
7171+ nazarewk
7272+ ];
3973 meta.doc = ./netbird.md;
40747575+ imports = [
7676+ (mkAliasOptionModule [ "services" "netbird" "tunnels" ] [ "services" "netbird" "clients" ])
7777+ ];
7878+4179 options.services.netbird = {
4242- enable = mkEnableOption "Netbird daemon";
8080+ enable = mkOption {
8181+ type = bool;
8282+ default = false;
8383+ description = ''
8484+ Enables backwards compatible Netbird client service.
8585+8686+ This is strictly equivalent to:
8787+8888+ ```nix
8989+ services.netbird.clients.default = {
9090+ port = 51820;
9191+ name = "netbird";
9292+ systemd.name = "netbird";
9393+ interface = "wt0";
9494+ hardened = false;
9595+ };
9696+ ```
9797+ '';
9898+ };
4399 package = mkPackageOption pkgs "netbird" { };
441004545- tunnels = mkOption {
101101+ ui.enable = mkOption {
102102+ type = bool;
103103+ default = config.services.displayManager.sessionPackages != [ ] || config.services.xserver.enable;
104104+ defaultText = literalExpression ''
105105+ config.services.displayManager.sessionPackages != [ ] || config.services.xserver.enable
106106+ '';
107107+ description = ''
108108+ Controls presence `netbird-ui` wrappers, defaults to presence of graphical sessions.
109109+ '';
110110+ };
111111+ ui.package = mkPackageOption pkgs "netbird-ui" { };
112112+113113+ clients = mkOption {
46114 type = attrsOf (
47115 submodule (
48116 { name, config, ... }:
117117+ let
118118+ client = config;
119119+ in
49120 {
50121 options = {
51122 port = mkOption {
52123 type = port;
5353- default = 51820;
124124+ example = literalExpression "51820";
125125+ description = ''
126126+ Port the Netbird client listens on.
127127+ '';
128128+ };
129129+130130+ name = mkOption {
131131+ type = str;
132132+ default = name;
133133+ description = ''
134134+ Primary name for use (as a suffix) in:
135135+ - systemd service name,
136136+ - hardened user name and group,
137137+ - [systemd `*Directory=`](https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#RuntimeDirectory=) names,
138138+ - desktop application identification,
139139+ '';
140140+ };
141141+142142+ dns-resolver.address = mkOption {
143143+ type = nullOr str;
144144+ default = null;
145145+ example = "127.0.0.123";
146146+ description = ''
147147+ An explicit address that Netbird will serve `*.netbird.cloud.` (usually) entries on.
148148+149149+ Netbird serves DNS on it's own (dynamic) client address by default.
150150+ '';
151151+ };
152152+153153+ dns-resolver.port = mkOption {
154154+ type = port;
155155+ default = 53;
54156 description = ''
5555- Port for the ${name} netbird interface.
157157+ A port to serve DNS entries on when `dns-resolver.address` is enabled.
56158 '';
57159 };
58160161161+ interface = mkOption {
162162+ type = str;
163163+ default = "nb-${client.name}";
164164+ description = ''
165165+ Name of the network interface managed by this client.
166166+ '';
167167+ apply =
168168+ iface:
169169+ lib.throwIfNot (
170170+ builtins.stringLength iface <= 15
171171+ ) "Network interface name must be 15 characters or less" iface;
172172+ };
173173+59174 environment = mkOption {
60175 type = attrsOf str;
61176 defaultText = literalExpression ''
62177 {
6363- NB_CONFIG = "/var/lib/''${stateDir}/config.json";
6464- NB_LOG_FILE = "console";
6565- NB_WIREGUARD_PORT = builtins.toString port;
6666- NB_INTERFACE_NAME = name;
6767- NB_DAMEON_ADDR = "/var/run/''${stateDir}"
178178+ NB_STATE_DIR = client.dir.state;
179179+ NB_CONFIG = "''${client.dir.state}/config.json";
180180+ NB_DAEMON_ADDR = "unix://''${client.dir.runtime}/sock";
181181+ NB_INTERFACE_NAME = client.interface;
182182+ NB_LOG_FILE = mkOptionDefault "console";
183183+ NB_LOG_LEVEL = client.logLevel;
184184+ NB_SERVICE = client.service.name;
185185+ NB_WIREGUARD_PORT = toString client.port;
186186+ } // optionalAttrs (client.dns-resolver.address != null) {
187187+ NB_DNS_RESOLVER_ADDRESS = "''${client.dns-resolver.address}:''${builtins.toString client.dns-resolver.port}";
68188 }
69189 '';
70190 description = ''
···72192 '';
73193 };
741947575- stateDir = mkOption {
195195+ autoStart = mkOption {
196196+ type = bool;
197197+ default = true;
198198+ description = ''
199199+ Start the service with the system.
200200+201201+ As of 2024-02-13 it is not possible to start a Netbird client daemon without immediately
202202+ connecting to the network, but it is [planned for a near future](https://github.com/netbirdio/netbird/projects/2#card-91718018).
203203+ '';
204204+ };
205205+206206+ openFirewall = mkOption {
207207+ type = bool;
208208+ default = true;
209209+ description = ''
210210+ Opens up firewall `port` for communication between Netbird peers directly over LAN or public IP,
211211+ without using (internet-hosted) TURN servers as intermediaries.
212212+ '';
213213+ };
214214+215215+ hardened = mkOption {
216216+ type = bool;
217217+ default = true;
218218+ description = ''
219219+ Hardened service:
220220+ - runs as a dedicated user with minimal set of permissions (see caveats),
221221+ - restricts daemon configuration socket access to dedicated user group
222222+ (you can grant access to it with `users.users."<user>".extraGroups = [ ${client.user.group} ]`),
223223+224224+ Even though the local system resources access is restricted:
225225+ - `CAP_NET_RAW`, `CAP_NET_ADMIN` and `CAP_BPF` still give unlimited network manipulation possibilites,
226226+ - older kernels don't have `CAP_BPF` and use `CAP_SYS_ADMIN` instead,
227227+228228+ Known security features that are not (yet) integrated into the module:
229229+ - 2024-02-14: `rosenpass` is an experimental feature configurable solely
230230+ through `--enable-rosenpass` flag on the `netbird up` command,
231231+ see [the docs](https://docs.netbird.io/how-to/enable-post-quantum-cryptography)
232232+ '';
233233+ };
234234+235235+ logLevel = mkOption {
236236+ type = enum [
237237+ # logrus loglevels
238238+ "panic"
239239+ "fatal"
240240+ "error"
241241+ "warn"
242242+ "warning"
243243+ "info"
244244+ "debug"
245245+ "trace"
246246+ ];
247247+ default = "info";
248248+ description = "Log level of the Netbird daemon.";
249249+ };
250250+251251+ ui.enable = mkOption {
252252+ type = bool;
253253+ default = nixosConfig.services.netbird.ui.enable;
254254+ defaultText = literalExpression ''client.ui.enable'';
255255+ description = ''
256256+ Controls presence of `netbird-ui` wrapper for this Netbird client.
257257+ '';
258258+ };
259259+260260+ wrapper = mkOption {
261261+ type = package;
262262+ internal = true;
263263+ default =
264264+ let
265265+ makeWrapperArgs = concatLists (
266266+ mapAttrsToList (key: value: [
267267+ "--set-default"
268268+ key
269269+ value
270270+ ]) client.environment
271271+ );
272272+ mkBin = mkBinName client;
273273+ in
274274+ pkgs.stdenv.mkDerivation {
275275+ name = "${cfg.package.name}-wrapper-${client.name}";
276276+ meta.mainProgram = mkBin "netbird";
277277+ nativeBuildInputs = with pkgs; [ makeWrapper ];
278278+ phases = [ "installPhase" ];
279279+ installPhase = concatStringsSep "\n" [
280280+ ''
281281+ mkdir -p "$out/bin"
282282+ makeWrapper ${lib.getExe cfg.package} "$out/bin/${mkBin "netbird"}" \
283283+ ${escapeShellArgs makeWrapperArgs}
284284+ ''
285285+ (optionalString cfg.ui.enable ''
286286+ # netbird-ui doesn't support envvars
287287+ makeWrapper ${lib.getExe cfg.ui.package} "$out/bin/${mkBin "netbird-ui"}" \
288288+ --add-flags '--daemon-addr=${client.environment.NB_DAEMON_ADDR}'
289289+290290+ mkdir -p "$out/share/applications"
291291+ substitute ${cfg.ui.package}/share/applications/netbird.desktop \
292292+ "$out/share/applications/${mkBin "netbird"}.desktop" \
293293+ --replace-fail 'Name=Netbird' "Name=Netbird @ ${client.service.name}" \
294294+ --replace-fail '${lib.getExe cfg.ui.package}' "$out/bin/${mkBin "netbird-ui"}"
295295+ '')
296296+ ];
297297+ };
298298+ };
299299+300300+ # see https://github.com/netbirdio/netbird/blob/88747e3e0191abc64f1e8c7ecc65e5e50a1527fd/client/internal/config.go#L49-L82
301301+ config = mkOption {
302302+ type = (pkgs.formats.json { }).type;
303303+ defaultText = literalExpression ''
304304+ {
305305+ DisableAutoConnect = !client.autoStart;
306306+ WgIface = client.interface;
307307+ WgPort = client.port;
308308+ } // optionalAttrs (client.dns-resolver.address != null) {
309309+ CustomDNSAddress = "''${client.dns-resolver.address}:''${builtins.toString client.dns-resolver.port}";
310310+ }
311311+ '';
312312+ description = ''
313313+ Additional configuration that exists before the first start and
314314+ later overrides the existing values in `config.json`.
315315+316316+ It is mostly helpful to manage configuration ignored/not yet implemented
317317+ outside of `netbird up` invocation.
318318+319319+ WARNING: this is not an upstream feature, it could break in the future
320320+ (by having lower priority) after upstream implements an equivalent.
321321+322322+ It is implemented as a `preStart` script which overrides `config.json`
323323+ with content of `/etc/${client.dir.baseName}/config.d/*.json` files.
324324+ This option manages specifically `50-nixos.json` file.
325325+326326+ Consult [the source code](https://github.com/netbirdio/netbird/blob/88747e3e0191abc64f1e8c7ecc65e5e50a1527fd/client/internal/config.go#L49-L82)
327327+ or inspect existing file for a complete list of available configurations.
328328+ '';
329329+ };
330330+331331+ suffixedName = mkOption {
76332 type = str;
7777- default = "netbird-${name}";
333333+ default = if client.name != "netbird" then "netbird-${client.name}" else client.name;
78334 description = ''
7979- Directory storing the netbird configuration.
335335+ A systemd service name to use (without `.service` suffix).
336336+ '';
337337+ };
338338+ dir.baseName = mkOption {
339339+ type = str;
340340+ default = client.suffixedName;
341341+ description = ''
342342+ A systemd service name to use (without `.service` suffix).
343343+ '';
344344+ };
345345+ dir.state = mkOption {
346346+ type = path;
347347+ default = "/var/lib/${client.dir.baseName}";
348348+ description = ''
349349+ A state directory used by Netbird client to store `config.json`, `state.json` & `resolv.conf`.
350350+ '';
351351+ };
352352+ dir.runtime = mkOption {
353353+ type = path;
354354+ default = "/var/run/${client.dir.baseName}";
355355+ description = ''
356356+ A runtime directory used by Netbird client.
357357+ '';
358358+ };
359359+ service.name = mkOption {
360360+ type = str;
361361+ default = client.suffixedName;
362362+ description = ''
363363+ A systemd service name to use (without `.service` suffix).
364364+ '';
365365+ };
366366+ user.name = mkOption {
367367+ type = str;
368368+ default = client.suffixedName;
369369+ description = ''
370370+ A system user name for this client instance.
371371+ '';
372372+ };
373373+ user.group = mkOption {
374374+ type = str;
375375+ default = client.suffixedName;
376376+ description = ''
377377+ A system group name for this client instance.
378378+ '';
379379+ };
380380+ bin.suffix = mkOption {
381381+ type = str;
382382+ default = if client.name != "netbird" then client.name else "";
383383+ description = ''
384384+ A system group name for this client instance.
80385 '';
81386 };
82387 };
833888484- config.environment = builtins.mapAttrs (_: mkDefault) {
8585- NB_CONFIG = "/var/lib/${config.stateDir}/config.json";
8686- NB_LOG_FILE = "console";
8787- NB_WIREGUARD_PORT = builtins.toString config.port;
8888- NB_INTERFACE_NAME = name;
8989- NB_DAEMON_ADDR = "unix:///var/run/${config.stateDir}/sock";
9090- };
389389+ config.environment =
390390+ {
391391+ NB_STATE_DIR = client.dir.state;
392392+ NB_CONFIG = "${client.dir.state}/config.json";
393393+ NB_DAEMON_ADDR = "unix://${client.dir.runtime}/sock";
394394+ NB_INTERFACE_NAME = client.interface;
395395+ NB_LOG_FILE = mkOptionDefault "console";
396396+ NB_LOG_LEVEL = client.logLevel;
397397+ NB_SERVICE = client.service.name;
398398+ NB_WIREGUARD_PORT = toString client.port;
399399+ }
400400+ // optionalAttrs (client.dns-resolver.address != null) {
401401+ NB_DNS_RESOLVER_ADDRESS = "${client.dns-resolver.address}:${builtins.toString client.dns-resolver.port}";
402402+ };
403403+404404+ config.config =
405405+ {
406406+ DisableAutoConnect = !client.autoStart;
407407+ WgIface = client.interface;
408408+ WgPort = client.port;
409409+ }
410410+ // optionalAttrs (client.dns-resolver.address != null) {
411411+ CustomDNSAddress = "${client.dns-resolver.address}:${builtins.toString client.dns-resolver.port}";
412412+ };
91413 }
92414 )
93415 );
94416 default = { };
95417 description = ''
9696- Attribute set of Netbird tunnels, each one will spawn a daemon listening on ...
418418+ Attribute set of Netbird client daemons, by default each one will:
419419+420420+ 1. be manageable using dedicated tooling:
421421+ - `netbird-<name>` script,
422422+ - `Netbird - netbird-<name>` graphical interface when appropriate (see `ui.enable`),
423423+ 2. run as a `netbird-<name>.service`,
424424+ 3. listen for incoming remote connections on the port `51820` (`openFirewall` by default),
425425+ 4. manage the `netbird-<name>` wireguard interface,
426426+ 5. use the `/var/lib/netbird-<name>/config.json` configuration file,
427427+ 6. override `/var/lib/netbird-<name>/config.json` with values from `/etc/netbird-<name>/config.d/*.json`,
428428+ 7. (`hardened`) be locally manageable by `netbird-<name>` system group,
429429+430430+ With following caveats:
431431+432432+ - multiple daemons will interfere with each other's DNS resolution of `netbird.cloud`, but
433433+ should remain fully operational otherwise.
434434+ Setting up custom (non-conflicting) DNS zone is currently possible only when self-hosting.
435435+ '';
436436+ example = lib.literalExpression ''
437437+ {
438438+ services.netbird.clients.wt0.port = 51820;
439439+ services.netbird.clients.personal.port = 51821;
440440+ services.netbird.clients.work1.port = 51822;
441441+ }
97442 '';
98443 };
99444 };
100445101446 config = mkMerge [
102447 (mkIf cfg.enable {
103103- # For backwards compatibility
104104- services.netbird.tunnels.wt0.stateDir = "netbird";
448448+ services.netbird.clients.default = {
449449+ port = mkDefault 51820;
450450+ interface = mkDefault "wt0";
451451+ name = mkDefault "netbird";
452452+ hardened = mkDefault false;
453453+ };
105454 })
455455+ {
456456+ boot.extraModulePackages = optional (
457457+ cfg.clients != { } && (versionOlder kernel.version "5.6")
458458+ ) kernelPackages.wireguard;
106459107107- (mkIf (cfg.tunnels != { }) {
108108- boot.extraModulePackages = optional (versionOlder kernel.kernel.version "5.6") kernel.wireguard;
460460+ environment.systemPackages = toClientList (client: client.wrapper)
461461+ # omitted due to https://github.com/netbirdio/netbird/issues/1562
462462+ #++ optional (cfg.clients != { }) cfg.package
463463+ # omitted due to https://github.com/netbirdio/netbird/issues/1581
464464+ #++ optional (cfg.clients != { } && cfg.ui.enable) cfg.ui.package
465465+ ;
109466110110- environment.systemPackages = [ cfg.package ];
467467+ networking.dhcpcd.denyInterfaces = toClientList (client: client.interface);
468468+ networking.networkmanager.unmanaged = toClientList (client: "interface-name:${client.interface}");
111469112112- networking.dhcpcd.denyInterfaces = attrNames cfg.tunnels;
470470+ networking.firewall.allowedUDPPorts = concatLists (
471471+ toClientList (client: optional client.openFirewall client.port)
472472+ );
113473114474 systemd.network.networks = mkIf config.networking.useNetworkd (
115115- mapAttrs' (
116116- name: _:
117117- nameValuePair "50-netbird-${name}" {
475475+ toClientAttrs (
476476+ client:
477477+ nameValuePair "50-netbird-${client.interface}" {
118478 matchConfig = {
119119- Name = name;
479479+ Name = client.interface;
120480 };
121481 linkConfig = {
122482 Unmanaged = true;
123483 ActivationPolicy = "manual";
124484 };
125485 }
126126- ) cfg.tunnels
486486+ )
487487+ );
488488+489489+ environment.etc = toClientAttrs (
490490+ client:
491491+ nameValuePair "${client.dir.baseName}/config.d/50-nixos.json" {
492492+ text = builtins.toJSON client.config;
493493+ mode = "0444";
494494+ }
127495 );
128496129129- systemd.services = mapAttrs' (
130130- name:
131131- { environment, stateDir, ... }:
132132- nameValuePair "netbird-${name}" {
497497+ systemd.services = toClientAttrs (
498498+ client:
499499+ nameValuePair client.service.name {
133500 description = "A WireGuard-based mesh network that connects your devices into a single private network";
134501135502 documentation = [ "https://netbird.io/docs/" ];
···137504 after = [ "network.target" ];
138505 wantedBy = [ "multi-user.target" ];
139506140140- path = with pkgs; [ openresolv ];
141141-142142- inherit environment;
507507+ path = optional (!config.services.resolved.enable) pkgs.openresolv;
143508144509 serviceConfig = {
145145- ExecStart = "${getExe cfg.package} service run";
510510+ ExecStart = "${getExe client.wrapper} service run";
146511 Restart = "always";
147147- RuntimeDirectory = stateDir;
148148- StateDirectory = stateDir;
512512+513513+ RuntimeDirectory = client.dir.baseName;
514514+ RuntimeDirectoryMode = mkDefault "0755";
515515+ ConfigurationDirectory = client.dir.baseName;
516516+ StateDirectory = client.dir.baseName;
149517 StateDirectoryMode = "0700";
150150- WorkingDirectory = "/var/lib/${stateDir}";
518518+519519+ WorkingDirectory = client.dir.state;
151520 };
152521153522 unitConfig = {
···157526158527 stopIfChanged = false;
159528 }
160160- ) cfg.tunnels;
529529+ );
530530+ }
531531+ # Hardening section
532532+ (mkIf (hardenedClients != { }) {
533533+ users.groups = toHardenedClientAttrs (client: nameValuePair client.user.group { });
534534+ users.users = toHardenedClientAttrs (
535535+ client:
536536+ nameValuePair client.user.name {
537537+ isSystemUser = true;
538538+ home = client.dir.state;
539539+ group = client.user.group;
540540+ }
541541+ );
542542+543543+ systemd.services = toHardenedClientAttrs (
544544+ client:
545545+ nameValuePair client.service.name (
546546+ mkIf client.hardened {
547547+ serviceConfig = {
548548+ RuntimeDirectoryMode = "0750";
549549+550550+ User = client.user.name;
551551+ Group = client.user.group;
552552+553553+ # settings implied by DynamicUser=true, without actully using it,
554554+ # see https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#DynamicUser=
555555+ RemoveIPC = true;
556556+ PrivateTmp = true;
557557+ ProtectSystem = "strict";
558558+ ProtectHome = "yes";
559559+560560+ AmbientCapabilities =
561561+ [
562562+ # see https://man7.org/linux/man-pages/man7/capabilities.7.html
563563+ # see https://docs.netbird.io/how-to/installation#running-net-bird-in-docker
564564+ #
565565+ # seems to work fine without CAP_SYS_ADMIN and CAP_SYS_RESOURCE
566566+ # CAP_NET_BIND_SERVICE could be added to allow binding on low ports, but is not required,
567567+ # see https://github.com/netbirdio/netbird/pull/1513
568568+569569+ # failed creating tunnel interface wt-priv: [operation not permitted
570570+ "CAP_NET_ADMIN"
571571+ # failed to pull up wgInterface [wt-priv]: failed to create ipv4 raw socket: socket: operation not permitted
572572+ "CAP_NET_RAW"
573573+ ]
574574+ # required for eBPF filter, used to be subset of CAP_SYS_ADMIN
575575+ ++ optional (versionAtLeast kernel.version "5.8") "CAP_BPF"
576576+ ++ optional (versionOlder kernel.version "5.8") "CAP_SYS_ADMIN"
577577+ ++ optional (
578578+ client.dns-resolver.address != null && client.dns-resolver.port < 1024
579579+ ) "CAP_NET_BIND_SERVICE";
580580+ };
581581+ }
582582+ )
583583+ );
584584+585585+ # see https://github.com/systemd/systemd/blob/17f3e91e8107b2b29fe25755651b230bbc81a514/src/resolve/org.freedesktop.resolve1.policy#L43-L43
586586+ # see all actions used at https://github.com/netbirdio/netbird/blob/13e7198046a0d73a9cd91bf8e063fafb3d41885c/client/internal/dns/systemd_linux.go#L29-L32
587587+ security.polkit.extraConfig = mkIf config.services.resolved.enable ''
588588+ // systemd-resolved access for Netbird clients
589589+ polkit.addRule(function(action, subject) {
590590+ var actions = [
591591+ "org.freedesktop.resolve1.revert",
592592+ "org.freedesktop.resolve1.set-default-route",
593593+ "org.freedesktop.resolve1.set-dns-servers",
594594+ "org.freedesktop.resolve1.set-domains",
595595+ ];
596596+ var users = ${builtins.toJSON (toHardenedClientList (client: client.user.name))};
597597+598598+ if (actions.indexOf(action.id) >= 0 && users.indexOf(subject.user) >= 0 ) {
599599+ return polkit.Result.YES;
600600+ }
601601+ });
602602+ '';
161603 })
604604+ # migration & temporary fixups section
605605+ {
606606+ systemd.services = toClientAttrs (
607607+ client:
608608+ nameValuePair client.service.name {
609609+ preStart = ''
610610+ set -eEuo pipefail
611611+ ${optionalString (client.logLevel == "trace" || client.logLevel == "debug") "set -x"}
612612+613613+ PATH="${
614614+ makeBinPath (
615615+ with pkgs;
616616+ [
617617+ coreutils
618618+ jq
619619+ diffutils
620620+ ]
621621+ )
622622+ }:$PATH"
623623+ export ${toShellVars client.environment}
624624+625625+ # merge /etc/${client.dir.baseName}/config.d' into "$NB_CONFIG"
626626+ {
627627+ test -e "$NB_CONFIG" || echo -n '{}' > "$NB_CONFIG"
628628+629629+ # merge config.d with "$NB_CONFIG" into "$NB_CONFIG.new"
630630+ jq -sS 'reduce .[] as $i ({}; . * $i)' \
631631+ "$NB_CONFIG" \
632632+ /etc/${client.dir.baseName}/config.d/*.json \
633633+ > "$NB_CONFIG.new"
634634+635635+ echo "Comparing $NB_CONFIG with $NB_CONFIG.new ..."
636636+ if ! diff <(jq -S <"$NB_CONFIG") "$NB_CONFIG.new" ; then
637637+ echo "Updating $NB_CONFIG ..."
638638+ mv "$NB_CONFIG.new" "$NB_CONFIG"
639639+ else
640640+ echo "Files are the same, not doing anything."
641641+ rm "$NB_CONFIG.new"
642642+ fi
643643+ }
644644+ '';
645645+ }
646646+ );
647647+ }
162648 ];
163649}
···4040in
4141stdenv.mkDerivation rec {
4242 pname = "strawberry";
4343- version = "1.2.4";
4343+ version = "1.2.6";
44444545 src = fetchFromGitHub {
4646 owner = "jonaski";
4747 repo = pname;
4848 rev = version;
4949- hash = "sha256-acTFJS8E0hQNbiiOi8DfPyTiUcKjXwg5trk3Q2mYYmQ=";
4949+ hash = "sha256-FfyvSNaO8dE6zz/PNKp/2kJHbauJjmQAhTriRE5lXEk=";
5050 };
51515252 # the big strawberry shown in the context menu is *very* much in your face, so use the grey version instead
···5656 sed 's/^\(s[ug]idperms\) = [0-9]755/\1 = 0755/' -i src/Makefile.am
5757 '';
58585959- # Assume System V `setpgrp (void)', which is the default on GNU variants
6060- # (`AC_FUNC_SETPGRP' is not cross-compilation capable.)
5959+ # `AC_FUNC_SETPGRP' is not cross-compilation capable.
6160 preConfigure = ''
6262- export ac_cv_func_setpgrp_void=yes
6161+ export ac_cv_func_setpgrp_void=${if stdenv.hostPlatform.isBSD then "no" else "yes"}
6362 export shadow_cv_logdir=/var/log
6463 '';
6564
···11+diff --git a/bin_steam.sh b/bin_steam.sh
22+index 49f9d8a..48f4379 100755
33+--- a/bin_steam.sh
44++++ b/bin_steam.sh
55+@@ -297,7 +297,7 @@ fi
66+ # Leave a copy of the bootstrap tarball in ~/.steam so that Steam can
77+ # re-bootstrap itself if required
88+ if ! cmp -s "$LAUNCHSTEAMBOOTSTRAPFILE" "$LAUNCHSTEAMDIR/bootstrap.tar.xz"; then
99+- cp "$LAUNCHSTEAMBOOTSTRAPFILE" "$LAUNCHSTEAMDIR/bootstrap.tar.xz"
1010++ cp -f "$LAUNCHSTEAMBOOTSTRAPFILE" "$LAUNCHSTEAMDIR/bootstrap.tar.xz"
1111+ fi
1212+1313+ # go to the install directory and run the client
+9-2
pkgs/by-name/st/steam-unwrapped/package.nix
···7788stdenv.mkDerivation (finalAttrs: {
99 pname = "steam-unwrapped";
1010- version = "1.0.0.81";
1010+ version = "1.0.0.82";
11111212 src = fetchurl {
1313 # use archive url so the tarball doesn't 404 on a new release
1414 url = "https://repo.steampowered.com/steam/archive/stable/steam_${finalAttrs.version}.tar.gz";
1515- hash = "sha256-Gia5182s4J4E3Ia1EeC5kjJX9mSltsr+b+1eRtEXtPk=";
1515+ hash = "sha256-r6Lx3WJx/StkW6MLjzq0Cv02VONUJBoxy9UQAPfm/Hc=";
1616 };
1717+1818+ patches = [
1919+ # We copy the bootstrap file from the store, where it's read-only,
2020+ # so future attempts to update it with bare "cp" will fail.
2121+ # So, use "cp -f" to force an overwrite.
2222+ ./force-overwrite-bootstrap.patch
2323+ ];
17241825 makeFlags = [
1926 "DESTDIR=$(out)"
···11-{
22- lib,
33- fetchFromGitHub,
44- rustPlatform,
55-}:
66-77-rustPlatform.buildRustPackage rec {
88- pname = "webmetro";
99- version = "unstable-20180426";
1010-1111- src = fetchFromGitHub {
1212- owner = "Tangent128";
1313- repo = pname;
1414- rev = "4f6cc00fe647bd311d00a8a4cb53ab08f20a04f9";
1515- sha256 = "1n2c7ygs8qsd5zgii6fqqcwg427bsij082bg4ijnzkq5630dx651";
1616- };
1717-1818- cargoHash = "sha256-6LfJ5rI7Y+ziEIMxPpKxOS+VSrKuKohEcqIK7xdKhNg=";
1919-2020- meta = with lib; {
2121- description = "Simple relay server for broadcasting a WebM stream";
2222- longDescription = ''
2323- Webmetro is a simple relay server for broadcasting a WebM stream
2424- from one uploader to many downloaders, via HTTP.
2525- The initialization segment is remembered, so that viewers can join
2626- mid-stream. Cluster timestamps are rewritten to be monotonic, so multiple
2727- (compatibly-encoded) webm files can be chained together without
2828- clients needing to reconnect.
2929- '';
3030- license = with licenses; [ mit ];
3131- maintainers = with maintainers; [ leenaars ];
3232- mainProgram = "webmetro";
3333- };
3434-}
···11-diff --git a/src/gllib/vma-iter.c b/src/gllib/vma-iter.c
22-index 6045f21d7..d50a3a398 100644
33---- a/src/gllib/vma-iter.c
44-+++ b/src/gllib/vma-iter.c
55-@@ -1327,7 +1327,7 @@ vma_iterate (vma_iterate_callback_fn callback, void *data)
66- In 64-bit processes, we could use vm_region_64 or mach_vm_region.
77- I choose vm_region_64 because it uses the same types as vm_region,
88- resulting in less conditional code. */
99--# if defined __ppc64__ || defined __x86_64__
1010-+# if defined __aarch64__ || defined __ppc64__ || defined __x86_64__
1111- struct vm_region_basic_info_64 info;
1212- mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT_64;
1313-
···3838 lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) [
3939 # For cross builds, provide answers to the configure time tests.
4040 # These answers are valid on x86_64-linux and aarch64-linux.
4141+ # TODO: provide all valid answers for BSD.
4142 "ac_cv_file__dev_zero=yes"
4242- "ac_cv_func_setpgrp_void=yes"
4343+ "ac_cv_func_setpgrp_void=${if stdenv.hostPlatform.isBSD then "no" else "yes"}"
4344 "apr_cv_tcp_nodelay_with_cork=yes"
4445 "ac_cv_define_PTHREAD_PROCESS_SHARED=yes"
4546 "apr_cv_process_shared_works=yes"
···13131414stdenv.mkDerivation rec {
1515 pname = "adguardhome";
1616- version = "0.107.55";
1616+ version = "0.107.56";
1717 src = sources.${system} or (throw "Source for ${pname} is not available for ${system}");
18181919 installPhase = ''
···132132 auditBlasHook = throw "'auditBlasHook' has been removed since it never worked"; # Added 2024-04-02
133133 aumix = throw "'aumix' has been removed due to lack of maintenance upstream. Consider using 'pamixer' for CLI or 'pavucontrol' for GUI"; # Added 2024-09-14
134134 authy = throw "'authy' has been removed since it reached end of life"; # Added 2024-04-19
135135+ autoadb = throw "'autoadb' has been removed due to lack of maintenance upstream"; # Added 2025-01-25
135136 avldrums-lv2 = throw "'avldrums-lv2' has been renamed to/replaced by 'x42-avldrums'"; # Converted to throw 2024-10-17
136137 avrlibcCross = avrlibc; # Added 2024-09-06
137138 awesome-4-0 = awesome; # Added 2022-05-05
···204205 cargo-espflash = espflash;
205206 cargo-kcov = throw "'cargo-kcov' has been removed due to lack of upstream maintenance"; # Added 2025-01-25
206207 cargo-inspect = throw "'cargo-inspect' has been removed due to lack of upstream maintenance. Upstream recommends cargo-expand."; # Added 2025-01-26
208208+ cargo-web = throw "'cargo-web' has been removed due to lack of upstream maintenance"; # Added 2025-01-26
207209 cawbird = throw "cawbird has been abandoned upstream and is broken anyways due to Twitter closing its API";
208210 certmgr-selfsigned = certmgr; # Added 2023-11-30
209211 cgal_4 = throw "cgal_4 has been removed as it is obsolete use cgal instead"; # Added 2024-12-30
···13751377 temurin-jre-bin-22 = throw "Temurin 22 has been removed as it has reached its end of life"; # Added 2024-09-24
13761378 temurin-bin-22 = throw "Temurin 22 has been removed as it has reached its end of life"; # Added 2024-09-24
13771379 tepl = libgedit-tepl; # Added 2024-04-29
13801380+ termplay = throw "'termplay' has been removed due to lack of maintenance upstream"; # Added 2025-01-25
13781381 testVersion = testers.testVersion; # Added 2022-04-20
13791382 tfplugindocs = terraform-plugin-docs; # Added 2023-11-01
13801383 invalidateFetcherByDrvHash = testers.invalidateFetcherByDrvHash; # Added 2022-05-05
···14701473 virtscreen = throw "'virtscreen' has been removed, as it was broken and unmaintained"; # Added 2024-10-17
14711474 vkBasalt = vkbasalt; # Added 2022-11-22
14721475 vkdt-wayland = vkdt; # Added 2024-04-19
14761476+ void = throw "'void' has been removed due to lack of upstream maintenance"; # Added 2025-01-25
14731477 volnoti = throw "'volnoti' has been removed due to lack of maintenance upstream."; # Added 2024-12-04
14741478 vuze = throw "'vuze' was removed because it is unmaintained upstream and insecure (CVE-2018-13417). BiglyBT is a maintained fork."; # Added 2024-11-22
14751479 inherit (libsForQt5.mauiPackages) vvave; # added 2022-05-17
···14861490 ''; # Add 2023-07-29
14871491 waypoint = throw "waypoint has been removed from nixpkgs as the upstream project was archived"; # Added 2024-04-24
14881492 webkitgtk = lib.warnOnInstantiate "Explicitly set the ABI version of 'webkitgtk'" webkitgtk_4_0;
14931493+ webmetro = throw "'webmetro' has been removed due to lack of upstream maintenance"; # Added 2025-01-25
14891494 wg-bond = throw "'wg-bond' has been removed due to lack of upstream maintenance"; # Added 2025-01-25
14901495 wineWayland = wine-wayland;
14911496 win-virtio = virtio-win; # Added 2023-10-17