繁体   English   中英

使用 Apache 基本身份验证禁用 git 对特定目录的访问

[英]Disabling access for git to specific Directory with Apache Basic Authentication

我的 Apache2 服务器设置了 git,它可以很好地满足 git 请求。 现在我想为此设置基本身份验证,所以不是每个人都可以使用每个目录。 我的目标是只有 ADMIN 组可以访问完整的/var/www/html/git目录,而我的 GITGROUP只能访问/var/www/html/git/subdir目录。 然而,虽然 Apache 要求提供凭据,但通过设置(如下)仍然允许 GITGROUP 访问所有git 目录。 我究竟做错了什么?

SetEnv GIT_PROJECT_ROOT /var/www/html/git
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAlias /git/ /usr/lib/git-core/git-http-backend/
<Directory /usr/lib/git-core>
    Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
    AuthType Basic
    AuthName "Authentication Required"
    AuthUserFile "/etc/apache2/.htpasswd"
    AuthGroupFile "/etc/apache2/groups"
    Require group ADMIN GITGROUP

    Order allow,deny
    Allow from all
</Directory>
<Directory /var/www/html/git>
    AuthType Basic
    AuthName "Authentication Required"
    AuthUserFile "/etc/apache2/.htpasswd"
    AuthGroupFile "/etc/apache2/groups"
    Require group ADMIN
    Options -Indexes

    Order allow,deny
    Allow from all
</Directory>
<Directory /var/www/html/git/subdir>
    AuthType Basic
    AuthName "Authentication Required"
    AuthUserFile "/etc/apache2/.htpasswd"
    AuthGroupFile "/etc/apache2/groups"
    Require group ADMIN GITGROUP
    Options -Indexes

    Order allow,deny
    Allow from all
</Directory>

编辑:

根据@jsvendsgaard 的回答,我为两个指向 git-core 的符号链接创建了两条 ScriptAlias 行。 之后,只需分配正确的 GIT_PROJECT_ROOT:

ScriptAlias /gitdir1/ /var/www/html/gitdir1/git-core/git-http-backend/
ScriptAlias /gitdir2/ /var/www/html/gitdir2/git-core/git-http-backend/
<Directory "/var/www/html/gitdir1/git-core">
    AuthType Basic
    AuthName "Authentication Required"
    AuthUserFile "/etc/apache2/.htpasswd"
    AuthGroupFile "/etc/apache2/groups"
    Require group ADMIN
    Options +ExecCGI -MultiViews -Indexes

    Order allow,deny
    Allow from all
</Directory>
<Directory "/var/www/html/gitdir2/git-core">
    AuthType Basic
    AuthName "Authentication Required"
    AuthUserFile "/etc/apache2/.htpasswd"
    AuthGroupFile "/etc/apache2/groups"
    Require group ADMIN GITGROUP
    Options +ExecCGI -MultiViews -Indexes

    Order allow,deny
    Allow from all
</Directory>
<Location "/gitdir1/">
    SetEnv GIT_PROJECT_ROOT /var/www/html/gitdir1
    SetEnv GIT_HTTP_EXPORT_ALL

    AuthType Basic
    AuthName "Authentication Required"
    AuthUserFile "/etc/apache2/.htpasswd"
    AuthGroupFile "/etc/apache2/groups"
    Require group ADMIN
</Location>
<Location "/gitdir2/">
    SetEnv GIT_PROJECT_ROOT /var/www/html/gitdir2
    SetEnv GIT_HTTP_EXPORT_ALL

    AuthType Basic
    AuthName "Authentication Required"
    AuthUserFile "/etc/apache2/.htpasswd"
    AuthGroupFile "/etc/apache2/groups"
    Require group ADMIN GITGROUP
</Location>

我相信我也有类似的需求。 我能够让我的解决方案在 RedHat 服务器上运行。

使用 Apache 2.4 的解决方案

我发现的问题是 git-http-backend 脚本确实控制了对存储库的所有访问。 此外,ScriptAlias 配置为将所有 /git/ 请求路由到 git-http-backend,而不考虑路径的 rest。 而且,由于您已为 GITGROUP 提供了对该脚本的访问权限,因此该组将有权访问 URL 中以 /git/ 开头的任何存储库。 根据文档,

https://git-scm.com/docs/git-http-backend

git-http-backend 知道每个存储库的位置,因为 Apache 为它提供了一个环境变量。 我怀疑这意味着 git-http-backend 是服务器上唯一直接访问您的存储库的进程,然后将响应返回给 Apache。

我的解决方案增加了一些额外的步骤。 本质上,您将强制对 git-http-backend 的任何访问仅在您已经对存储库的位置进行身份验证之后才会发生,而不是之前。 这是通过在存储库目录本身中放置脚本的链接,然后验证该位置来完成的。

注意:我只使用裸存储库(git init --bare)完成此操作。 我怀疑如果由于某种原因您需要使用非裸存储库,则此解决方案需要进行一些调整(最后的想法):

简而言之:

  1. 在每个存储库中创建一个指向 git-core 的链接(如果您要使用非裸存储库,我怀疑您会遇到问题,请参阅下面的想法)
  2. 使用 ScriptAliasMatch 而不是 ScriptAlias,以便您可以仅将请求与请求的存储库匹配,并将请求定向到符号链接。
  3. 为每个存储库创建一个 <Location> 指令,并为那里的每个站点单独设置 GIT_PROJECT_ROOT 变量。 这是因为 apache 将不再向 git 提供存储库的正确路径。
  4. 为每个符号链接创建一个 <Directory> 指令。 对我来说,这样做的唯一目的是设置目录的选项,例如 -Indexes。 您可以根据需要将其用于其他选项。

细节:

  1. 链接。 如果您的存储库是 /var/www/html/git/subdir,并且您的 git-httpd-backend 在 /usr/libexec/git-core 中,则命令将是:

ln -s /usr/libexec/git-core /var/www/html/git/subdir/git-core

  1. 别名。 这将使用带有两个反向引用的正则表达式,一个 ($1) 获取存储库的路径,另一个 ($2) 获取命令(git-upload-pack 等)。 然后,它会将其别名为您在第一步中创建的符号链接。 在我的正则表达式中,我还确保请求是有效的 git 请求。 它假设对您站点的请求开始看起来像 https://yoursite/git/some_repo.git:
ScriptAliasMatch \
  "(?x)^/git/(.*/)((HEAD | \
    info/refs | \
    objects/(info/[^/]+ | \
    [0-9a-f]{2}/[0-9a-f]{38} | \
    pack/pack-[0-9a-f]{40}\.(pack|idx)) | \
    git-(upload|receive)-pack))$" \
    "/var/www/html/git/$1/git-core/git-http-backend/$2"
  1. 创建 <Location> 指令。 您可以在此处设置 git 存储库的路径,您还可以在此处添加身份验证:
 <Location /git/subdir1.git> SetEnv GIT_PROJECT_ROOT /var/www/html/git/subdir1.git SetEnv GIT_HTTP_EXPORT_ALL AuthType Basic AuthName "Authorization Required"... <the rest of your authentication details here>... </Location> <Location /git/subdir2.git> SetEnv GIT_PROJECT_ROOT /var/www/html/git/subdir2.git SetEnv GIT_HTTP_EXPORT_ALL AuthType Basic AuthName "Authorization Required"... <the rest of your authentication details here>... </Location>
  1. 创建 <Directory> 指令。 对于每个存储库,为您在步骤 A 中创建的符号链接创建一个目录:
 <Directory /var/www/html/git/subdir1.git/git-core> Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch -Indexes Allowoverride None </Directory> <Directory /var/www/html/git/subdir2.git/git-core> Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch -Indexes Allowoverride None </Directory>

如果您不使用裸存储库:

我只在 git 服务器上使用裸存储库,但我认为如果您没有裸存储库,您可能会看到创建此符号链接的问题。 我担心的是有人会以某种方式将您的链接添加到存储库。 我不确定这是否可能,但有几个想法可以解决它:

  1. 为每个链接创建一个 git-ignore,尽管 repo 用户可能能够撤消此操作。
  2. 在存储库目录之外的某个其他目录中创建符号链接。 我现在能想到的唯一问题是,您可能需要在指令中添加第二层身份验证。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM