Unverified Commit ff2d12d1 authored by Gaétan Lepage's avatar Gaétan Lepage Committed by GitHub
Browse files

nixos/cloudflared: add option for cert.pem and use dynamic user (#383499)

parents 19a251b2 4f644e0b
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -551,6 +551,8 @@

- hddfancontrol has been updated to major release 2. See the [migration guide](https://github.com/desbma/hddfancontrol/tree/master?tab=readme-ov-file#migrating-from-v1x), as there are breaking changes.

- `services.cloudflared` now uses a dynamic user, and its `user` and `group` options have been removed. If the user or group is still necessary, they can be created manually.

- The Home Assistant module has new options {option}`services.home-assistant.blueprints.automation`, `services.home-assistant.blueprints.script`, and {option}`services.home-assistant.blueprints.template` that allow for the declarative installation of [blueprints](https://www.home-assistant.io/docs/blueprint/) into the appropriate configuration directories.

- For matrix homeserver Synapse we are now following the upstream recommendation to enable jemalloc as the memory allocator by default.
+61 −30
Original line number Diff line number Diff line
@@ -7,6 +7,16 @@
let
  cfg = config.services.cloudflared;

  certificateFile = lib.mkOption {
    type = with lib.types; nullOr path;
    description = ''
      Cert.pem file.

      See [Cert.pem](https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/tunnel-useful-terms/#certpem).
    '';
    default = null;
  };

  originRequest = {
    connectTimeout = lib.mkOption {
      type = with lib.types; nullOr str;
@@ -144,20 +154,38 @@ let
  };
in
{
  options.services.cloudflared = {
    enable = lib.mkEnableOption "Cloudflare Tunnel client daemon (formerly Argo Tunnel)";
  imports = [
    (lib.mkRemovedOptionModule
      [
        "services"
        "cloudflared"
        "user"
      ]
      ''
        Cloudflared now uses a dynamic user, and this option no longer has any effect.

    user = lib.mkOption {
      type = lib.types.str;
      default = "cloudflared";
      description = "User account under which Cloudflared runs.";
    };
        If the user is still necessary, please define it manually using users.users.cloudflared.
      ''
    )

    group = lib.mkOption {
      type = lib.types.str;
      default = "cloudflared";
      description = "Group under which cloudflared runs.";
    };
    (lib.mkRemovedOptionModule
      [
        "services"
        "cloudflared"
        "group"
      ]
      ''
        Cloudflared now uses a dynamic user, and this option no longer has any effect.

        If the group is still necessary, please define it manually using users.groups.cloudflared.
      ''
    )
  ];

  options.services.cloudflared = {
    inherit certificateFile;

    enable = lib.mkEnableOption "Cloudflare Tunnel client daemon (formerly Argo Tunnel)";

    package = lib.mkPackageOption pkgs "cloudflared" { };

@@ -170,10 +198,10 @@ in
          { name, ... }:
          {
            options = {
              inherit originRequest;
              inherit certificateFile originRequest;

              credentialsFile = lib.mkOption {
                type = lib.types.str;
                type = lib.types.path;
                description = ''
                  Credential file.

@@ -273,6 +301,12 @@ in
  };

  config = lib.mkIf cfg.enable {
    assertions = lib.mapAttrsToList (name: tunnel: {
      assertion =
        tunnel.ingress == { } || (cfg.certificateFile != null || tunnel.certificateFile != null);
      message = "Cloudflare Tunnel ${name} has a declarative configuration, but no certificate file was defined.";
    }) cfg.tunnels;

    systemd.targets = lib.mapAttrs' (
      name: tunnel:
      lib.nameValuePair "cloudflared-tunnel-${name}" {
@@ -303,7 +337,7 @@ in

        fullConfig = filterConfig {
          tunnel = name;
          "credentials-file" = tunnel.credentialsFile;
          credentials-file = "/run/credentials/cloudflared-tunnel-${name}.service/credentials.json";
          warp-routing = filterConfig tunnel.warp-routing;
          originRequest = filterConfig tunnel.originRequest;
          ingress =
@@ -322,8 +356,9 @@ in
        };

        mkConfigFile = pkgs.writeText "cloudflared.yml" (builtins.toJSON fullConfig);
        certFile = if (tunnel.certificateFile != null) then tunnel.certificateFile else cfg.certificateFile;
      in
      lib.nameValuePair "cloudflared-tunnel-${name}" ({
      lib.nameValuePair "cloudflared-tunnel-${name}" {
        after = [
          "network.target"
          "network-online.target"
@@ -334,24 +369,20 @@ in
        ];
        wantedBy = [ "multi-user.target" ];
        serviceConfig = {
          User = cfg.user;
          Group = cfg.group;
          RuntimeDirectory = "cloudflared-tunnel-${name}";
          RuntimeDirectoryMode = "0400";
          LoadCredential = [
            "credentials.json:${tunnel.credentialsFile}"
          ] ++ (lib.optional (certFile != null) "cert.pem:certFile");

          ExecStart = "${cfg.package}/bin/cloudflared tunnel --config=${mkConfigFile} --no-autoupdate run";
          Restart = "on-failure";
        };
      })
    ) config.services.cloudflared.tunnels;

    users.users = lib.mkIf (cfg.user == "cloudflared") {
      cloudflared = {
        group = cfg.group;
        isSystemUser = true;
      };
          DynamicUser = true;
        };

    users.groups = lib.mkIf (cfg.group == "cloudflared") {
      cloudflared = { };
    };
        environment.TUNNEL_ORIGIN_CERT = lib.mkIf (certFile != null) ''%d/cert.pem'';
      }
    ) config.services.cloudflared.tunnels;
  };

  meta.maintainers = with lib.maintainers; [