Gitosis

2018-07-10 17:13 更新

Gitosis

把所有用戶的公鑰保存在 authorized_keys 文件的做法,只能湊和一陣子,當(dāng)用戶數(shù)量達(dá)到幾百人的規(guī)模時(shí),管理起來就會(huì)十分痛苦。每次改刪用戶都必須登錄服務(wù)器不去說,這種做法還缺少必要的權(quán)限管理 — 每個(gè)人都對(duì)所有項(xiàng)目擁有完整的讀寫權(quán)限。

幸好我們還可以選擇應(yīng)用廣泛的 Gitosis 項(xiàng)目。簡單地說,Gitosis 就是一套用來管理 authorized_keys 文件和實(shí)現(xiàn)簡單連接限制的腳本。有趣的是,用來添加用戶和設(shè)定權(quán)限的并非通過網(wǎng)頁程序,而只是管理一個(gè)特殊的 Git 倉庫。你只需要在這個(gè)特殊倉庫內(nèi)做好相應(yīng)的設(shè)定,然后推送到服務(wù)器上,Gitosis 就會(huì)隨之改變運(yùn)行策略,聽起來就很酷,對(duì)吧?

Gitosis 的安裝算不上傻瓜化,但也不算太難。用 Linux 服務(wù)器架設(shè)起來最簡單 — 以下例子中,我們使用裝有 Ubuntu 8.10 系統(tǒng)的服務(wù)器。

Gitosis 的工作依賴于某些 Python 工具,所以首先要安裝 Python 的 setuptools 包,在 Ubuntu 上稱為 python-setuptools:

$ apt-get install python-setuptools

接下來,從 Gitosis 項(xiàng)目主頁克隆并安裝:

$ git clone https://github.com/tv42/gitosis.git
$ cd gitosis
$ sudo python setup.py install

這會(huì)安裝幾個(gè)供 Gitosis 使用的工具。默認(rèn) Gitosis 會(huì)把 /home/git 作為存儲(chǔ)所有 Git 倉庫的根目錄,這沒什么不好,不過我們之前已經(jīng)把項(xiàng)目倉庫都放在 /opt/git 里面了,所以為方便起見,我們可以做一個(gè)符號(hào)連接,直接劃轉(zhuǎn)過去,而不必重新配置:

$ ln -s /opt/git /home/git/repositories

Gitosis 將會(huì)幫我們管理用戶公鑰,所以先把當(dāng)前控制文件改名備份,以便稍后重新添加,準(zhǔn)備好讓 Gitosis 自動(dòng)管理 authorized_keys 文件:

$ mv /home/git/.ssh/authorized_keys /home/git/.ssh/ak.bak

接下來,如果之前把 git 用戶的登錄 shell 改為 git-shell 命令的話,先恢復(fù) 'git' 用戶的登錄 shell。改過之后,大家仍然無法通過該帳號(hào)登錄(譯注:因?yàn)?nbsp;authorized_keys 文件已經(jīng)沒有了。),不過不用擔(dān)心,這會(huì)交給 Gitosis 來實(shí)現(xiàn)。所以現(xiàn)在先打開 /etc/passwd 文件,把這行:

git:x:1000:1000::/home/git:/usr/bin/git-shell

改回:

git:x:1000:1000::/home/git:/bin/sh

好了,現(xiàn)在可以初始化 Gitosis 了。你可以用自己的公鑰執(zhí)行 gitosis-init 命令,要是公鑰不在服務(wù)器上,先臨時(shí)復(fù)制一份:

$ sudo -H -u git gitosis-init < /tmp/id_dsa.pub
Initialized empty Git repository in /opt/git/gitosis-admin.git/
Reinitialized existing Git repository in /opt/git/gitosis-admin.git/

這樣該公鑰的擁有者就能修改用于配置 Gitosis 的那個(gè)特殊 Git 倉庫了。接下來,需要手工對(duì)該倉庫中的 post-update 腳本加上可執(zhí)行權(quán)限:

$ sudo chmod 755 /opt/git/gitosis-admin.git/hooks/post-update

基本上就算是好了。如果設(shè)定過程沒出什么差錯(cuò),現(xiàn)在可以試一下用初始化 Gitosis 的公鑰的擁有者身份 SSH 登錄服務(wù)器,應(yīng)該會(huì)看到類似下面這樣:

$ ssh git@gitserver
PTY allocation request failed on channel 0
ERROR:gitosis.serve.main:Need SSH_ORIGINAL_COMMAND in environment.
  Connection to gitserver closed.

說明 Gitosis 認(rèn)出了該用戶的身份,但由于沒有運(yùn)行任何 Git 命令,所以它切斷了連接。那么,現(xiàn)在運(yùn)行一個(gè)實(shí)際的 Git 命令 — 克隆 Gitosis 的控制倉庫:

# 在你本地計(jì)算機(jī)上
$ git clone git@gitserver:gitosis-admin.git

這會(huì)得到一個(gè)名為 gitosis-admin 的工作目錄,主要由兩部分組成:

$ cd gitosis-admin
$ find .
./gitosis.conf
./keydir
./keydir/scott.pub

gitosis.conf 文件是用來設(shè)置用戶、倉庫和權(quán)限的控制文件。keydir 目錄則是保存所有具有訪問權(quán)限用戶公鑰的地方— 每人一個(gè)。在 keydir 里的文件名(比如上面的 scott.pub)應(yīng)該跟你的不一樣 — Gitosis 會(huì)自動(dòng)從使用 gitosis-init 腳本導(dǎo)入的公鑰尾部的描述中獲取該名字。

看一下 gitosis.conf 文件的內(nèi)容,它應(yīng)該只包含與剛剛克隆的 gitosis-admin 相關(guān)的信息:

$ cat gitosis.conf
[gitosis]

[group gitosis-admin]
members = scott
writable = gitosis-admin

它顯示用戶 scott — 初始化 Gitosis 公鑰的擁有者 — 是唯一能管理 gitosis-admin 項(xiàng)目的人。

現(xiàn)在我們來添加一個(gè)新項(xiàng)目。為此我們要建立一個(gè)名為 mobile 的新段落,在其中羅列手機(jī)開發(fā)團(tuán)隊(duì)的開發(fā)者,以及他們擁有寫權(quán)限的項(xiàng)目。由于 'scott' 是系統(tǒng)中的唯一用戶,我們把他設(shè)為唯一用戶,并允許他讀寫名為 iphone_project 的新項(xiàng)目:

[group mobile]
members = scott
writable = iphone_project

修改完之后,提交 gitosis-admin 里的改動(dòng),并推送到服務(wù)器使其生效:

$ git commit -am 'add iphone_project and mobile group'
[master 8962da8] add iphone_project and mobile group
 1 file changed, 4 insertions(+)
$ git push origin master
Counting objects: 5, done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 272 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To git@gitserver:gitosis-admin.git
   fb27aec..8962da8  master -> master

在新工程 iphone_project 里首次推送數(shù)據(jù)到服務(wù)器前,得先設(shè)定該服務(wù)器地址為遠(yuǎn)程倉庫。但你不用事先到服務(wù)器上手工創(chuàng)建該項(xiàng)目的裸倉庫— Gitosis 會(huì)在第一次遇到推送時(shí)自動(dòng)創(chuàng)建:

$ git remote add origin git@gitserver:iphone_project.git
$ git push origin master
Initialized empty Git repository in /opt/git/iphone_project.git/
Counting objects: 3, done.
Writing objects: 100% (3/3), 230 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To git@gitserver:iphone_project.git
 * [new branch]      master -> master

請注意,這里不用指明完整路徑(實(shí)際上,如果加上反而沒用),只需要一個(gè)冒號(hào)加項(xiàng)目名字即可 — Gitosis 會(huì)自動(dòng)幫你映射到實(shí)際位置。

要和朋友們在一個(gè)項(xiàng)目上協(xié)同工作,就得重新添加他們的公鑰。不過這次不用在服務(wù)器上一個(gè)一個(gè)手工添加到 ~/.ssh/authorized_keys 文件末端,而只需管理 keydir 目錄中的公鑰文件。文件的命名將決定在 gitosis.conf 中對(duì)用戶的標(biāo)識(shí)?,F(xiàn)在我們?yōu)?John,Josie 和 Jessica 添加公鑰:

$ cp /tmp/id_rsa.john.pub keydir/john.pub
$ cp /tmp/id_rsa.josie.pub keydir/josie.pub
$ cp /tmp/id_rsa.jessica.pub keydir/jessica.pub

然后把他們都加進(jìn) 'mobile' 團(tuán)隊(duì),讓他們對(duì) iphone_project 具有讀寫權(quán)限:

[group mobile]
members = scott john josie jessica
writable = iphone_project

如果你提交并推送這個(gè)修改,四個(gè)用戶將同時(shí)具有該項(xiàng)目的讀寫權(quán)限。

Gitosis 也具有簡單的訪問控制功能。如果想讓 John 只有讀權(quán)限,可以這樣做:

[group mobile]
members = scott josie jessica
writable = iphone_project

[group mobile_ro]
members = john
readonly = iphone_project

現(xiàn)在 John 可以克隆和獲取更新,但 Gitosis 不會(huì)允許他向項(xiàng)目推送任何內(nèi)容。像這樣的組可以隨意創(chuàng)建,多少不限,每個(gè)都可以包含若干不同的用戶和項(xiàng)目。甚至還可以指定某個(gè)組為成員之一(在組名前加上 @ 前綴),自動(dòng)繼承該組的成員:

[group mobile_committers]
members = scott josie jessica

[group mobile]
members   = @mobile_committers
writable  = iphone_project

[group mobile_2]
members   = @mobile_committers john
writable  = another_iphone_project

如果遇到意外問題,試試看把 loglevel=DEBUG 加到 [gitosis] 的段落(譯注:把日志設(shè)置為調(diào)試級(jí)別,記錄更詳細(xì)的運(yùn)行信息。)。如果一不小心搞錯(cuò)了配置,失去了推送權(quán)限,也可以手工修改服務(wù)器上的 /home/git/.gitosis.conf 文件 — Gitosis 實(shí)際是從該文件讀取信息的。它在得到推送數(shù)據(jù)時(shí),會(huì)把新的 gitosis.conf 存到該路徑上。所以如果你手工編輯該文件的話,它會(huì)一直保持到下次向 gitosis-admin 推送新版本的配置內(nèi)容為止。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)