私は 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
送信します。私の簡単な解決策は、このサフィックスを でキャプチャして if ステートメントを使用することでしたが、これは if の正しい使用法ではないことがすぐにわかりました (git-receive-pack
$1
イフィスヴィル)。
私が達成しようとしていることに対して、より適切な解決策はあるでしょうか?
答え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(および場所)をプッシュして、認証後に書き換えることもできます。リモートを構成する異なるプッシュ 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 ...
}
}