簡體   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