<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hant-TW">
	<id>https://jiva.dila.edu.tw/index.php?action=history&amp;feed=atom&amp;title=Pro_Git_4.7_%E6%AC%8A%E9%99%90%E7%AE%A1%E7%90%86%E5%99%A8_Gitosis</id>
	<title>Pro Git 4.7 權限管理器 Gitosis - 修訂歷史</title>
	<link rel="self" type="application/atom+xml" href="https://jiva.dila.edu.tw/index.php?action=history&amp;feed=atom&amp;title=Pro_Git_4.7_%E6%AC%8A%E9%99%90%E7%AE%A1%E7%90%86%E5%99%A8_Gitosis"/>
	<link rel="alternate" type="text/html" href="https://jiva.dila.edu.tw/index.php?title=Pro_Git_4.7_%E6%AC%8A%E9%99%90%E7%AE%A1%E7%90%86%E5%99%A8_Gitosis&amp;action=history"/>
	<updated>2026-05-05T21:17:02Z</updated>
	<subtitle>本 Wiki 上此頁面的修訂歷史</subtitle>
	<generator>MediaWiki 1.39.1</generator>
	<entry>
		<id>https://jiva.dila.edu.tw/index.php?title=Pro_Git_4.7_%E6%AC%8A%E9%99%90%E7%AE%A1%E7%90%86%E5%99%A8_Gitosis&amp;diff=550&amp;oldid=prev</id>
		<title>imported&gt;Ray：​新頁面: 把所有用戶的公開金鑰保存在 authorized_keys 檔的做法只能暫時奏效。當用戶數量到了幾百人的時候，它會變成一種痛苦。每一次都必須進入伺...</title>
		<link rel="alternate" type="text/html" href="https://jiva.dila.edu.tw/index.php?title=Pro_Git_4.7_%E6%AC%8A%E9%99%90%E7%AE%A1%E7%90%86%E5%99%A8_Gitosis&amp;diff=550&amp;oldid=prev"/>
		<updated>2011-05-30T08:56:23Z</updated>

		<summary type="html">&lt;p&gt;新頁面: 把所有用戶的公開金鑰保存在 authorized_keys 檔的做法只能暫時奏效。當用戶數量到了幾百人的時候，它會變成一種痛苦。每一次都必須進入伺...&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新頁面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;把所有用戶的公開金鑰保存在 authorized_keys 檔的做法只能暫時奏效。當用戶數量到了幾百人的時候，它會變成一種痛苦。每一次都必須進入伺服器的 shell，而且缺少對連接的限制——檔裡的每個人都對所有專案擁有讀寫許可權。&lt;br /&gt;
&lt;br /&gt;
現在，是時候向廣泛使用的軟體 Gitosis 求救了。Gitosis 簡單的說就是一套用來管理 authorized_keys 檔和實現簡單連接限制的腳本。最有意思的是，該軟體用來添加使用者和設定許可權的介面不是網頁，而是一個特殊的 Git 倉庫。你只需要設定好某個項目；然後推送，Gitosis 就會隨之改變伺服器設定，酷吧？&lt;br /&gt;
&lt;br /&gt;
Gitosis 的安裝算不上傻瓜化，不過也不算太難。用 Linux 伺服器架設起來最簡單——以下例子中的伺服器使用 Ubuntu 8.10 系統。&lt;br /&gt;
&lt;br /&gt;
Gitosis 需要使用部分 Python 工具，所以首先要安裝 Python 的 setuptools 包，在 Ubuntu 中名為 python-setuptools：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
$ apt-get install python-setuptools&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
接下來，從專案主頁克隆和安裝 Gitosis：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
$ git clone git://eagain.net/gitosis.git&lt;br /&gt;
$ cd gitosis&lt;br /&gt;
$ sudo python setup.py install&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
這會安裝幾個 Gitosis 用的可執行檔。現在，Gitosis 想把它的倉庫放在 /home/git，倒也可以。不過我們的倉庫已經建立在 /opt/git 了，這時可以創建一個檔連接，而不用從頭開始重新配置：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
$ ln -s /opt/git /home/git/repositories&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Gitosis 將為我們管理公開金鑰，所以當前的檔需要刪除，以後再重新添加公開金鑰，並且讓 Gitosis 自動控制 authorized_keys 檔。現在，把 authorized_keys檔移走：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
$ mv /home/git/.ssh/authorized_keys /home/git/.ssh/ak.bak&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
然後恢復 ‘git’ 用戶的 shell，假設之前把它改成了 git-shell 命令。其他人仍然不能通過它來登錄系統，不過這次有 Gitosis 幫我們實現。所以現在把 /etc/passwd 檔的這一行&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
git:x:1000:1000::/home/git:/usr/bin/git-shell&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
恢復成:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
git:x:1000:1000::/home/git:/bin/sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
現在就可以初始化 Gitosis 了。需要通過自己的公開金鑰來運行 gitosis-init。如果公開金鑰不在伺服器上，則必須複製一份：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
$ sudo -H -u git gitosis-init &amp;lt; /tmp/id_dsa.pub&lt;br /&gt;
Initialized empty Git repository in /opt/git/gitosis-admin.git/&lt;br /&gt;
Reinitialized existing Git repository in /opt/git/gitosis-admin.git/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
這樣該公開金鑰的擁有者就能修改包含著 Gitosis 設置的那個 Git 倉庫了。然後手動將這個新的控制倉庫中的 post-update 腳本加上執行許可權。&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
$ sudo chmod 755 /opt/git/gitosis-admin.git/hooks/post-update&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
萬事俱備了。如果設定過程沒出什麼差錯，現在可以試一下用初始化 Gitosis 公開金鑰的擁有者身份 SSH 進伺服器。看到的結果應該和下面類似：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
$ ssh git@gitserver&lt;br /&gt;
PTY allocation request failed on channel 0&lt;br /&gt;
fatal: unrecognized command 'gitosis-serve schacon@quaternion'&lt;br /&gt;
  Connection to gitserver closed.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
說明 Gitosis 認出了該用戶的身份，但由於沒有運行任何 Git 命令所以它切斷了連接。所以，現在運行一個確切的 Git 命令——克隆 Gitosis 的控制倉庫：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
# 在自己的電腦上&lt;br /&gt;
$ git clone git@gitserver:gitosis-admin.git&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
得到一個名為 gitosis-admin 的目錄，主要由兩部分組成：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
$ cd gitosis-admin&lt;br /&gt;
$ find .&lt;br /&gt;
./gitosis.conf&lt;br /&gt;
./keydir&lt;br /&gt;
./keydir/scott.pub&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
gitosis.conf 檔是用來設置用戶、倉庫和許可權的控制檔。keydir 目錄則是保存所有具有存取權限用戶公開金鑰的地方——每人一個。你 keydir 中的檔案名（前例中的 scott.pub）應該有所不同—— Gitosis 從使用 gitosis-init 腳本導入的公開金鑰尾部的描述中獲取該名。&lt;br /&gt;
&lt;br /&gt;
看一下 gitosis.conf 的內容，它應該只包含與剛剛克隆的 gitosis-admin 相關的資訊：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
$ cat gitosis.conf &lt;br /&gt;
[gitosis]&lt;br /&gt;
&lt;br /&gt;
[group gitosis-admin]&lt;br /&gt;
writable = gitosis-admin&lt;br /&gt;
members = scott&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
它顯示使用者 scott ——初始化 Gitosis 公開金鑰的擁有者——是唯一能訪問 gitosis-admin 專案的人。&lt;br /&gt;
&lt;br /&gt;
現在我們添加一個新的專案。我們將添加一個名為 mobile 的新節段(section)，在這裡羅列手機開發團隊的開發者以及他們需要存取權限的專案。由於 ‘scott’ 是系統中的唯一使用者，我們把它加成唯一的用戶，從創建一個叫做 iphone_project 的新專案開始：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
[group mobile]&lt;br /&gt;
writable = iphone_project&lt;br /&gt;
members = scott&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
一旦修改了 gitosis-admin 專案的內容，只有提交並推送至伺服器才能使之生效：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
$ git commit -am 'add iphone_project and mobile group'&lt;br /&gt;
[master]: created 8962da8: &amp;quot;changed name&amp;quot;&lt;br /&gt;
 1 files changed, 4 insertions(+), 0 deletions(-)&lt;br /&gt;
$ git push&lt;br /&gt;
Counting objects: 5, done.&lt;br /&gt;
Compressing objects: 100% (2/2), done.&lt;br /&gt;
Writing objects: 100% (3/3), 272 bytes, done.&lt;br /&gt;
Total 3 (delta 1), reused 0 (delta 0)&lt;br /&gt;
To git@gitserver:/opt/git/gitosis-admin.git&lt;br /&gt;
   fb27aec..8962da8  master -&amp;gt; master&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
第一次向新專案 iphone_project 的推送需要在本地的版本中把伺服器添加為一個 remote 然後推送。從此手動為新專案在伺服器上創建純倉庫的麻煩就是歷史了—— Gitosis 會在第一次遇到推送的時候自動創建它們：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
$ git remote add origin git@gitserver:iphone_project.git&lt;br /&gt;
$ git push origin master&lt;br /&gt;
Initialized empty Git repository in /opt/git/iphone_project.git/&lt;br /&gt;
Counting objects: 3, done.&lt;br /&gt;
Writing objects: 100% (3/3), 230 bytes, done.&lt;br /&gt;
Total 3 (delta 0), reused 0 (delta 0)&lt;br /&gt;
To git@gitserver:iphone_project.git&lt;br /&gt;
 * [new branch]      master -&amp;gt; master&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
注意到路徑被忽略了（加上它反而沒用），只有一個冒號加項目的名字—— Gitosis 會為你找到專案的位置。&lt;br /&gt;
&lt;br /&gt;
要和朋友們共同在一個專案上共同工作，就得重新添加他們的公開金鑰。不過這次不用在伺服器上一個一個手動添加到 ~/.ssh/authorized_keys 檔末端，而是在 keydir 目錄為每一個公開金鑰添加一個檔。文件的命名將決定在 gitosis.conf 檔中用戶的稱呼。現在我們為 John，Josie 和 Jessica 添加公開金鑰：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
$ cp /tmp/id_rsa.john.pub keydir/john.pub&lt;br /&gt;
$ cp /tmp/id_rsa.josie.pub keydir/josie.pub&lt;br /&gt;
$ cp /tmp/id_rsa.jessica.pub keydir/jessica.pub&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
然後把他們都加進 ‘mobile’ 團隊，讓他們對 iphone_project 具有讀寫許可權：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
[group mobile]&lt;br /&gt;
writable = iphone_project&lt;br /&gt;
members = scott john josie jessica&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
如果你提交並推送這個修改，四個用戶將同時具有該項目的讀寫許可權。&lt;br /&gt;
&lt;br /&gt;
Gitosis 也具有簡單的存取控制功能。如果想讓 John 只有讀許可權，可以這樣做：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
[group mobile]&lt;br /&gt;
writable = iphone_project&lt;br /&gt;
members = scott josie jessica&lt;br /&gt;
&lt;br /&gt;
[group mobile_ro]&lt;br /&gt;
readonly = iphone_project&lt;br /&gt;
members = john&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
現在 John 可以克隆和獲取更新，但 Gitosis 不會允許他向專案推送任何內容。這樣的群組你想要建立多少個就可以建立多少個，每一個群組包含不同的用戶和專案。甚至可以指定某個群組為成員(使用 @ 當做 prefix),，來自動繼承它所有的成員。&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
[group mobile_committers]&lt;br /&gt;
members = scott josie jessica&lt;br /&gt;
&lt;br /&gt;
[group mobile]&lt;br /&gt;
writable  = iphone_project&lt;br /&gt;
members   = @mobile_committers&lt;br /&gt;
&lt;br /&gt;
[group mobile_2]&lt;br /&gt;
writable  = another_iphone_project&lt;br /&gt;
members   = @mobile_committers john&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
如果出現了什麼問題，把 loglevel=DEBUG 加入到 [gitosis] 部分或許有幫助（譯注：把日誌設置到調試級別，記錄更詳細的資訊）。如果你一不小心搞錯了配置，失去了推送許可權，可以手動修改伺服器上的 /home/git/.gitosis 檔—— Gitosis 從該檔讀取資訊。一次推送會把 gitosis.conf 保存在伺服器上。如果你手動編輯該檔，它將維持原樣，直到你下次成功向 gitosis-admin 推送資料。&lt;/div&gt;</summary>
		<author><name>imported&gt;Ray</name></author>
	</entry>
</feed>