Unverified Commit 8b946679 authored by nixpkgs-ci[bot]'s avatar nixpkgs-ci[bot] Committed by GitHub
Browse files

Merge staging-next into staging

parents e91377d5 c9ad1567
Loading
Loading
Loading
Loading
+7 −13
Original line number Diff line number Diff line
@@ -2539,6 +2539,13 @@
    githubId = 59499799;
    keys = [ { fingerprint = "A0FF 4F26 6B80 0B86 726D  EA5B 3C23 C7BD 9945 2036"; } ];
  };
  averyvigolo = {
    email = "nixpkgs@averyv.me";
    github = "averyvigolo";
    githubId = 26379999;
    name = "Avery Vigolo";
    keys = [ { fingerprint = "9848 B216 BCBE 29BB 1C6A  E0D5 7A4D F5A8 CDBD 49C7"; } ];
  };
  avh4 = {
    email = "gruen0aermel@gmail.com";
    github = "avh4";
@@ -4752,12 +4759,6 @@
    githubId = 848609;
    name = "Michael Bishop";
  };
  clevor = {
    email = "myclevorname@gmail.com";
    github = "myclevorname";
    githubId = 140354451;
    name = "Samuel Connelly";
  };
  clkamp = {
    email = "c@lkamp.de";
    github = "clkamp";
@@ -26644,13 +26645,6 @@
    githubId = 5185341;
    name = "Will Cohen";
  };
  williamvds = {
    email = "nixpkgs@williamvds.me";
    github = "williamvds";
    githubId = 26379999;
    name = "William Vigolo";
    keys = [ { fingerprint = "9848 B216 BCBE 29BB 1C6A  E0D5 7A4D F5A8 CDBD 49C7"; } ];
  };
  willibutz = {
    email = "willibutz@posteo.de";
    github = "WilliButz";
+2 −0
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@
- [LACT](https://github.com/ilya-zlobintsev/LACT), a GPU monitoring and configuration tool, can now be enabled through [services.lact.enable](#opt-services.lact.enable).
  Note that for LACT to work properly on AMD GPU systems, you need to enable [hardware.amdgpu.overdrive.enable](#opt-hardware.amdgpu.overdrive.enable).

- [Broadcast Box](https://github.com/Glimesh/broadcast-box), a WebRTC broadcast server. Available as [services.broadcast-box](options.html#opt-services.broadcast-box.enable).

- [SuiteNumérique Docs](https://github.com/suitenumerique/docs), a collaborative note taking, wiki and documentation web platform and alternative to Notion or Outline. Available as [services.lasuite-docs](#opt-services.lasuite-docs.enable).

## Backward Incompatibilities {#sec-release-25.11-incompatibilities}
+1 −0
Original line number Diff line number Diff line
@@ -1491,6 +1491,7 @@
  ./services/ttys/getty.nix
  ./services/ttys/gpm.nix
  ./services/ttys/kmscon.nix
  ./services/video/broadcast-box.nix
  ./services/video/epgstation/default.nix
  ./services/video/frigate.nix
  ./services/video/go2rtc/default.nix
+1 −1
Original line number Diff line number Diff line
@@ -478,6 +478,6 @@ in

  meta = {
    doc = ./pihole-ftl.md;
    maintainers = with lib.maintainers; [ williamvds ];
    maintainers = with lib.maintainers; [ averyvigolo ];
  };
}
+274 −0
Original line number Diff line number Diff line
{
  lib,
  pkgs,
  config,
  ...
}:
let
  inherit (lib)
    mkIf
    mkEnableOption
    mkPackageOption
    mkOption
    attrNames
    types
    match
    optional
    optionals
    toInt
    last
    splitString
    allUnique
    concatStringsSep
    all
    filter
    mapAttrs
    any
    getExe
    maintainers
    ;
  inherit (cfg) settings;
  cfg = config.services.broadcast-box;

  addressToPort = address: toInt (last (splitString ":" address));
  httpPort = cfg.web.port;
  tcpMuxPort = addressToPort settings.TCP_MUX_ADDRESS;
  httpRedirect = settings.ENABLE_HTTP_REDIRECT or (settings.HTTPS_REDIRECT_PORT != null);

  udpPorts =
    optional (settings.UDP_MUX_PORT != null) settings.UDP_MUX_PORT
    ++ optional (settings.UDP_WHEP_PORT != null) settings.UDP_WHEP_PORT
    ++ optional (settings.UDP_WHIP_PORT != null) settings.UDP_WHIP_PORT;
  tcpPorts = optional (settings.TCP_MUX_ADDRESS != null) tcpMuxPort;
  webPorts = [ httpPort ] ++ optional httpRedirect settings.HTTPS_REDIRECT_PORT;
in
{
  options.services.broadcast-box = {
    enable = mkEnableOption "Broadcast Box";
    package = mkPackageOption pkgs "broadcast-box" { };

    web = {
      host = mkOption {
        type = types.str;
        default = "";
        example = "127.0.0.1";
        description = ''
          Host address the HTTP server listens on. By default the server
          listens on all interfaces.
        '';
      };

      port = mkOption {
        type = types.port;
        default = 8080;
        description = ''
          Port the HTTP server listens on.
        '';
      };

      openFirewall = mkEnableOption ''
        opening the HTTP server port and, if enabled, the HTTPS redirect server
        port in the firewall.
      '';
    };

    openFirewall = mkEnableOption ''
      opening WebRTC traffic ports in the firewall. Randomly selected ports
      will not be opened.
    '';

    settings = mkOption {
      visible = "shallow";

      type = types.submodule {
        freeformType =
          with types;
          attrsOf (
            nullOr (oneOf [
              bool
              int
              str
            ])
          );
        options = {
          TCP_MUX_ADDRESS = mkOption {
            type = with types; nullOr (strMatching ".*:[0-9]+");
            default = null;
          };

          DISABLE_STATUS = mkOption {
            type = types.bool;
            default = true;
          };

          UDP_MUX_PORT = mkOption {
            type = with types; nullOr port;
            default = null;
          };

          UDP_WHEP_PORT = mkOption {
            type = with types; nullOr port;
            default = null;
          };

          UDP_WHIP_PORT = mkOption {
            type = with types; nullOr port;
            default = null;
          };

          ENABLE_HTTP_REDIRECT = mkOption {
            type = types.bool;
            default = false;
          };

          HTTPS_REDIRECT_PORT = mkOption {
            type = with types; nullOr port;
            default = if settings.ENABLE_HTTP_REDIRECT then 80 else null;
          };
        };
      };

      default = {
        DISABLE_STATUS = true;
      };

      example = {
        DISABLE_STATUS = true;
        INCLUDE_PUBLIC_IP_IN_NAT_1_TO_1_IP = true;
        UDP_MUX_PORT = 3000;
      };

      description = ''
        Attribute set of environment variables.

        <https://github.com/Glimesh/broadcast-box#environment-variables>

        :::{.warning}
        The status API exposes stream keys so {env}`DISABLE_STATUS` is enabled
        by default.
        :::
      '';
    };
  };

  config = mkIf cfg.enable {
    assertions = [
      {
        assertion = !(settings ? HTTP_ADDRESS);
        message = ''
          The Broadcast Box `HTTP_ADDRESS` variable should not be used. Instead
          use the `host` and `port` options.
        '';
      }
      {
        assertion = httpRedirect -> settings ? SSL_CERT && settings ? SSL_KEY;
        message = ''
          The Broadcast Box `ENABLE_HTTP_REDIRECT` variable requires `SSL_CERT`
          and `SSL_KEY` to be configured.
        '';
      }
      {
        assertion = httpRedirect -> httpPort == 443;
        message = ''
          Broadcast Box HTTP redirect only works if the HTTP server listen port
          is 443.
        '';
      }
      {
        assertion = allUnique (tcpPorts ++ webPorts);
        message = ''
          Broadcast Box configuration contains duplicate TCP ports.
        '';
      }
      {
        assertion = all (name: (match "[A-Z0-9_]+" name) != null) (attrNames settings);
        message =
          let
            offenders = filter (name: (match "[A-Z0-9_]+" name) == null) (attrNames settings);
          in
          ''
            Broadcast Box `settings` attribute names must be in uppercase snake
            case. Invalid attribute name(s): `${concatStringsSep ", " offenders}`
          '';
      }
    ];

    systemd.services.broadcast-box = {
      description = "Broadcast Box";
      after = [ "network-online.target" ];
      wants = [ "network-online.target" ];
      wantedBy = [ "multi-user.target" ];
      startLimitBurst = 3;
      startLimitIntervalSec = 180;

      environment =
        (mapAttrs (
          _: value:
          if (builtins.typeOf value == "bool") then
            if !value then null else "true"
          else if (builtins.typeOf value == "int") then
            toString value
          else
            value
        ) cfg.settings)
        // {
          APP_ENV = "nixos";
          HTTP_ADDRESS = cfg.web.host + ":" + toString cfg.web.port;
        };

      serviceConfig =
        let
          priviledgedPort = any (p: p > 0 && p < 1024) (udpPorts ++ tcpPorts ++ webPorts);
        in
        {
          ExecStart = "${getExe cfg.package}";
          Restart = "always";
          RestartSec = "10s";

          DynamicUser = true;
          LockPersonality = true;
          NoNewPrivileges = true;
          PrivateUsers = !priviledgedPort;
          PrivateDevices = true;
          PrivateMounts = true;
          PrivateTmp = true;
          ProtectSystem = "strict";
          ProtectHome = true;
          ProtectControlGroups = true;
          ProtectClock = true;
          ProtectProc = "invisible";
          ProtectHostname = true;
          ProtectKernelLogs = true;
          ProtectKernelModules = true;
          ProtectKernelTunables = true;
          ProcSubset = "pid";
          RemoveIPC = true;
          RestrictAddressFamilies = [
            "AF_INET"
            "AF_INET6"
            "AF_NETLINK"
          ];
          RestrictNamespaces = true;
          RestrictRealtime = true;
          RestrictSUIDSGID = true;
          SystemCallArchitectures = "native";
          SystemCallFilter = [
            "@system-service"
            "~@privileged"
          ];
          CapabilityBoundingSet = if priviledgedPort then [ "CAP_NET_BIND_SERVICE" ] else "";
          AmbientCapabilities = mkIf priviledgedPort [ "CAP_NET_BIND_SERVICE" ];
          DeviceAllow = "";
          MemoryDenyWriteExecute = true;
          UMask = "0077";
        };
    };

    networking.firewall = {
      allowedTCPPorts = optionals cfg.openFirewall tcpPorts ++ optionals cfg.web.openFirewall webPorts;
      allowedUDPPorts = optionals cfg.openFirewall udpPorts;
    };
  };

  meta.maintainers = with maintainers; [ JManch ];
}
Loading