5 人の開発者が同じ ssh アカウントを介して git-repository にアクセスできます。そのリポジトリの一部のブランチ ( production, development ) へのプッシュ アクセスを制限する必要があります。git フックを使用して単純なブランチ セキュリティを実装する方法は?
3 に答える
pre-receive または update フックでこれを行うことができます。(ここでの違いは、pre-receive フックはプッシュ全体のみを受け入れまたは拒否できるのに対し、update フックは個々の ref-update を受け入れまたは拒否できることです。) gitolite はこれを「すぐに」サポートすることに注意してください。高レベルの概要については、git bookを参照してください。
まず、GIT では 1 回のプッシュ コマンドで複数のブランチをアップロードできることを指摘しておきます。このような場合、セキュリティ リスクになる可能性があります。これを回避するには、次のようなスクリプトを使用する必要があります (誰もが 1 番目のブランチにプッシュできるが、2 番目のブランチにプッシュできると考えてください... 承認は 1 番目のブランチに対して行われますが、2 番目は?)
while read anotherOldrev anotherNewrev anotherRefname
do
newRefType="$(echo $anotherRefname | awk '{split($0,a,"/"); print a[2]}')"
if test "$newRefType" = "heads"
then
#branch
if test "$refname"
then
#branch, 2nd time, which means another branch
else
#branch, 1st time
oldrev=$anotherOldrev
newrev=$anotherNewrev
refname=$anotherRefname
fi
else
#tag
fi
done
セカンドハンドでは、 pre-receive フックで認証できるかどうかわかりません。取得したすべての情報は、古い参照、新しい参照、および名前であるため... ...しかし、一時的に名前を変更するのは1 つまたは 2 つのコマンド ( http://git-scm.com/book/en/Customizing-Git )
pre-receiveフックによる簡単な解決策:
#!/bin/bash
while read old_rev new_rev ref_name; do
for script in `find $PWD/hooks/pre-receive.d/ -perm -100 -type f`; do
${script} "$old_rev" "$new_rev" "$ref_name"
if [ "$?" -ne 0 ]; then
status=1
fi
done
done
exit ${status}
これはpre-receive.dディレクトリにある必要があるファイルです:
#!/bin/bash
old_rev=$1
new_rev=$2
ref_name=$3
# Secure branches
sec_branches=(refs/heads/production refs/heads/development)
# Authorized users
authorized_users=('John Doe' 'Bob Smith')
# get rev type
zero="0000000000000000000000000000000000000000"
if [ "$new_rev" = "$zero" ]; then
new_rev_type=delete
else
new_rev_type=$(git cat-file -t ${new_rev})
fi
case "$ref_name","$new_rev_type" in
refs/heads/*,commit)
# new commit
case ${sec_branches[@]} in
*${ref_name}*)
# Save committer and author into variables
commit_prefs=$(git log -1 --pretty=format:'%an:%cn' ${new_rev})
IFS=":" read author committer <<< "$commit_prefs"
# if committer and author not in allowed persons - exit
case ${authorized_users[@]} in
*${author}*)
;;
*)
branch_name=`echo ${ref_name:11}`
echo
echo "You're not allowed to push in $branch_name branch" >&2
echo
exit 1
;;
esac
# if committer and author not equal - exit
if [ "$author" != "$committer" ]; then
echo
echo "You're not author of pushed commits. This is prohibited" >&2
echo
exit 1
fi
;;
esac
;;
esac
更新
コメントtorekに記載されているように、これは安全なソリューションではありませんが、事故を防ぐことができます。