git push에만 Nginx HTTP 인증

git push에만 Nginx HTTP 인증

Nginx를 사용하여 개인 Git 서버를 호스팅합니다. 누구든지 승인 없이 내 저장소에 복제할 수 있기를 원하지만 커밋을 푸시하려고 하면 승인이 필요합니다.

내 Nginx 구성은 다음과 같습니다.

server {
  listen 443 ssl;
  server_name git.example.com;
  ssl_certificate /fullchain.pem;
  ssl_certificate_key /privkey.pem;

  location ~ ^.*\.git/(HEAD|info/refs|objects/info/.*|git-(upload|recieve)-pack) {
    root /usr/share/nginx/git;

# --- incorrect solution ---

#    if ($1 = git-upload-pack) {
#        auth_basic "Restricted";
#        auth_basic_user_file /usr/share/nginx/htpasswd;
#    }
    client_max_body_size 0;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME /usr/lib/git-core/git-http-backend;
    fastcgi_param GIT_HTTP_EXPORT_ALL "";
    fastcgi_param GIT_PROJECT_ROOT $realpath_root;
    fastcgi_param REMOTE_USER $remote_user;
    fastcgi_param PATH_INFO $uri;
    fastcgi_param unix:/var/fcgiwrap.socket;

  }

내 이해에 따르면 요청이 내 서버로 git push전송됩니다 . git-receive-pack나의 간단한 해결책은 이 접미사를 캡처하여 $1if 문을 사용하는 것이었지만 이것이 ifs의 올바른 사용이 아니라는 것을 빨리 발견했습니다(이페세빌).

내가 달성하려는 목표에 더 적합한 솔루션이 있습니까?

답변1

git은 푸시 시 다른 요청(예: 또는 이와 유사한 요청)을 보낼 수 /path/to/repo.git/path/in/repo/refs?service=git-upload-pack있으며 동일한 비교를 사용하려고 했습니다.

다음과 같이 시도해 보세요.

  # static repo files for faster cloning over https:
  location ~ \.git/objects/(?:[0-9a-f]+/[0-9a-f]+|pack/pack-[0-9a-f]+\.(?:pack|idx))$ {
    root /home/git/repositories/;
  }                                                                                                                                               

  # requests that need to go to git-http-backend:
  location ~ \.git/(?:HEAD|info/refs|objects/info/|git-(?:upload|receive)-pack$) {
    root /home/git/repositories;
    # if upload:
    if ( $uri ~* "git-upload-pack$" ) {
       auth_basic ...
    }
    ...
  }

그러나 작업 시나리오로도 다음과 같은 것을 사용할 수 있습니다.

    # authorize if user name is specified:
    if ( $remote_user != "" ) {
       auth_basic ...
    }

또는 승인 후 다시 작성하는 푸시용 URL(및 위치)이 다를 수도 있습니다. 그러면 당신은 할 수 있습니다원격 구성다른 push-url 사용(사용자 이름 또는 기타 위치 포함):

# with user:
git remote set-url --push origin https://[email protected]/repo/...
# with "rw" location (to force authorization):
git remote set-url --push origin https://git.domail.tld/rw/repo/...

그런데 "if" 지시어는 일부 최상위 정규식 위치만큼 나쁘지 않습니다(특히 특정 위치에만 적용되고 http/server 섹션에서 직접 방해하지 않는 경우).
그러나 실제로 "if" 없이도 이 모든 작업을 수행할 수 있습니다(아래 예에서 위치 이름이 지정됨). 그러나 일부 문제에 대해 디버깅하는 것은 그리 간단하지 않습니다(nginx에 익숙하지 않은 경우).

location ...condGit... {
  root ...;

  location ...condA... {
    ## authorize and supply request to @gitweb:
    auth_basic ...
    try_files "" @gitweb;
  }

  location ...condB... {
    ## authorize and supply request to @gitweb:
    auth_basic ...
    try_files "" @gitweb;
  }

  # send anything else to gitweb if it's not a real file (inside root of gitweb):
  try_files $uri @gitweb;

  location @gitweb {
    # ... single location of fcgi wrapper of git http backend ...
  }
}

관련 정보