nixos/cgit: add gitHttpBackend options

This commit is contained in:
Martin Fischer
2025-12-29 18:43:03 +01:00
parent d23fedd87f
commit a722a999d1
3 changed files with 95 additions and 6 deletions

View File

@@ -63,6 +63,8 @@ of pulling the upstream container image from Docker Hub. If you want the old beh
- Ethercalc and its associated module have been removed, as the package is unmaintained and cannot be installed from source with npm now.
- `services.cgit` before always had the git-http-backend and its "export all" setting enabled, which sidestepped any access control configured in cgit's settings. Now you have to make a decision and either enable or disable `services.cgit.gitHttpBackend.checkExportOkFiles` (or disable the git-http-backend).
- The Bash implementation of the `nixos-rebuild` program is removed. All switchable systems now use the Python rewrite. Any prior usage of `system.rebuild.enableNg` must now be removed. If you have any outstanding issues with the new implementation, please open an issue on GitHub.
- The `networking.wireless` module has been security hardened: the `wpa_supplicant` daemon now runs under an unprivileged user with restricted access to the system.

View File

@@ -193,6 +193,32 @@ in
type = lib.types.str;
default = "cgit";
};
gitHttpBackend.enable = lib.mkOption {
description = ''
Whether to bypass cgit and use git-http-backend for HTTP clones.
While this enables HTTP clones to use the more efficient smart protocol,
it does not support access control via cgit's settings (e.g. the `ignore` repository setting).
If you want to disallow access to some repositories with this backend,
enable `checkExportOkFiles` and set `strict-export = "git-daemon-export-ok"` in `settings`.
'';
type = lib.types.bool;
default = true;
};
gitHttpBackend.checkExportOkFiles = lib.mkOption {
description = ''
Whether git-http-backend should only export repositories that contain a `git-daemon-export-ok` file.
When the backend is enabled and the check is disabled all repositories can be cloned
irrespective of cgit's settings (e.g. the `ignore` repository setting).
When enabled you must also configure `strict-export = "git-daemon-export-ok"`
in `settings` to make cgit check for the same files.
'';
type = lib.types.bool;
};
};
}
)
@@ -201,10 +227,30 @@ in
};
config = lib.mkIf (lib.any (cfg: cfg.enable) (lib.attrValues cfgs)) {
assertions = lib.mapAttrsToList (vhost: cfg: {
assertion = !cfg.enable || (cfg.scanPath == null) != (cfg.repos == { });
message = "Exactly one of services.cgit.${vhost}.scanPath or services.cgit.${vhost}.repos must be set.";
}) cfgs;
assertions = lib.flatten (
lib.mapAttrsToList (vhost: cfg: [
{
assertion = !cfg.enable || (cfg.scanPath == null) != (cfg.repos == { });
message = "Misconfigured services.cgit.${vhost}: Exactly one of scanPath or repos must be set.";
}
{
assertion =
!cfg.enable
|| !cfg.gitHttpBackend.enable
|| !cfg.gitHttpBackend.checkExportOkFiles
|| cfg.settings.strict-export == "git-daemon-export-ok";
message = "Misconfigured services.cgit.${vhost}: When gitHttpBackend.checkExportOkFiles is true then settings.strict-export must be \"git-daemon-export-ok\".";
}
{
assertion =
!cfg.enable
|| !cfg.gitHttpBackend.enable
|| cfg.settings.strict-export == null
|| cfg.gitHttpBackend.checkExportOkFiles;
message = "Misconfigured services.cgit.${vhost}: settings.strict-export is set but the gitHttpBackend is enabled and checkExportOkFiles is false.";
}
]) cfgs
);
users = lib.mkMerge (
lib.flip lib.mapAttrsToList cfgs (
@@ -259,16 +305,20 @@ in
alias = lib.mkDefault "${cfg.package}/cgit/${fileName}";
}
))
// {
// lib.optionalAttrs cfg.gitHttpBackend.enable {
"~ ${regexLocation cfg}/.+/(info/refs|git-upload-pack)" = {
fastcgiParams = rec {
SCRIPT_FILENAME = "${pkgs.git}/libexec/git-core/git-http-backend";
GIT_HTTP_EXPORT_ALL = "1";
GIT_PROJECT_ROOT = gitProjectRoot name cfg;
HOME = GIT_PROJECT_ROOT;
}
// lib.optionalAttrs (!cfg.gitHttpBackend.checkExportOkFiles) {
GIT_HTTP_EXPORT_ALL = "1";
};
extraConfig = mkFastcgiPass name cfg;
};
}
// {
"${stripLocation cfg}/" = {
fastcgiParams = {
SCRIPT_FILENAME = "${cfg.package}/cgit/cgit.cgi";

View File

@@ -39,6 +39,23 @@ in
":date.txt"
];
};
gitHttpBackend.checkExportOkFiles = false;
};
services.cgit."check.localhost" = {
enable = true;
scanPath = "/tmp/git";
settings = {
strict-export = "git-daemon-export-ok";
};
gitHttpBackend.checkExportOkFiles = true;
};
services.cgit."no-git-http-backend.localhost" = {
enable = true;
scanPath = "/tmp/git";
settings = {
strict-export = "git-daemon-export-ok";
};
gitHttpBackend.enable = false;
};
environment.systemPackages = [ pkgs.git ];
@@ -107,5 +124,25 @@ in
server.fail(
"curl -fsS 'http://localhost/%28c%29git/some-repo/about/' | grep -F 'cgit NixOS Test at'"
)
# EXPORT_ALL is not set with checkExportOkFiles = true
server.succeed("touch /tmp/git/some-repo/git-daemon-export-ok")
server.succeed(
"git clone http://check.localhost/some-repo $(mktemp -d)"
)
server.succeed("rm /tmp/git/some-repo/git-daemon-export-ok")
server.fail(
"git clone http://check.localhost/some-repo $(mktemp -d)"
)
# Disabling the git-http-backend-works
server.succeed("touch /tmp/git/some-repo/git-daemon-export-ok")
server.succeed(
"git clone http://no-git-http-backend.localhost/some-repo $(mktemp -d)"
)
server.succeed("rm /tmp/git/some-repo/git-daemon-export-ok")
server.fail(
"git clone http://no-git-http-backend.localhost/some-repo $(mktemp -d)"
)
'';
}