Ubuntu14.04.5 TLS搭建Git伺服器筆記
1 傳輸協議說明
Git 可以使用四種主要的協議來傳輸資料:本地協議(Local),HTTP 協議,SSH(Secure Shell)協議及Git 協議。
我們這裡架設 Git 伺服器時使用 SSH 協議作為傳輸協議。 因為大多數環境下已經支援通過 SSH 訪問 —— 即時沒有也比較很容易架設。 SSH 協議也是一個驗證授權的網路協議;並且,因為其普遍性,架設和使用都很容易。且我們主要應用環境就是公司的內網中使用,所以選擇SSH傳輸協議來搭建。
通過 SSH 協議克隆版本庫,你可以指定一個 ssh:// 的 URL:
$ git clone ssh://[email protected]
或者使用一個簡短的 scp 式的寫法:
$ git clone [email protected]:project.git
你也可以不指定使用者,Git 會使用當前登入的使用者名稱。
SSH 協議優勢
用 SSH 協議的優勢有很多。 首先,SSH 架設相對簡單 —— SSH 守護程序很常見,多數管理員都有使用經驗,並且多數作業系統都包含了它及相關的管理工具。 其次,通過 SSH 訪問是安全的 —— 所有傳輸資料都要經過授權和加密。 最後,與 HTTP/S 協議、 Git 協議及本地協議一樣,SSH 協議很高效,在傳輸前也會盡量壓縮資料。
SSH 協議缺點
SSH 協議的缺點在於你不能通過他實現匿名訪問。 即便只要讀取資料,使用者也要有通過 SSH 訪問你的主機的許可權,這使得 SSH 協議不利於開源的專案。 如果你只在公司網路使用,SSH 協議可能是你唯一要用到的協議。 如果你要同時提供匿名只讀訪問和 SSH 協議,那麼你除了為自己推送架設 SSH 服務以外,還得架設一個可以讓其他人訪問的服務。
2 git伺服器軟體安裝與配置
操作平臺:Ubuntu伺服器
2.1安裝git和openssh
[email protected]:~$ sudo apt-get install git-core openssh-server openssh-client python-setuptools
說明:
git-core: git服務核心軟體;
openssh-server和openssh-client:git通過ssh協議在伺服器與客戶端之間進行資料傳輸;
python-setuptools:python的setup tool,因為gitosis的安裝用到這個工具
2.2 新加使用者git
該使用者將作為所有程式碼倉庫和使用者許可權的管理者
[email protected]:~$ sudo useradd -m git
[email protected]:~$ sudo passwd git
2.3準備安裝gitosis
安裝gitosis之前需要初始化伺服器的git使用者資訊,這個根據實際情況填寫即可。git希望所有的使用者都要對自己的行為負責,不喜歡潛伏者或者那些喜歡胡作非為的人,所以在任何一臺機器上第一次使用git時,都必須要初始化一下git。方法如下:
[email protected]:~$ git config –global user.name “myname”
[email protected]:~$ git config –global user.email “[email protected]“
安裝gitosis.gitosis主要是給使用者授權.通過以下命令獲取gitosis版本檔案獲得gitosis包:
[email protected]:~$ cd /tmp
[email protected]:/tmp$ git clone https://github.com/res0nat0r/gitosis.git
注意:中間有兩個是數字零
獲取gitosis檔案後,進入到檔案目錄下面
[email protected]:/tmp$ cd gitosis
接著使用python命令安裝目錄下的setup.py的python指令碼進行安裝
[email protected]:/tmp/gitosis$ sudo python setup.py install
到這裡,整個安裝步驟就完成了,下面就開始對git進行一些基本的配置。
2.4建立一個git倉庫的儲存點
建立一個git倉庫節點,並且讓除了git以外的使用者對此目錄無任何許可權
[email protected]:~$ sudo mkdir /home/gitrepository
[email protected]:~$ sudo chown git:git /home/gitrepository/
[email protected]:~$ sudo chmod 700 /home/gitrepository/
由於gitosis在預設狀態下會將倉庫放在user賬戶路徑的repositories目錄下,例如git使用者的倉庫地址預設在/home/git/repositories/目錄下,這裡我們需要建立一個連結對映。讓他指向我們前面建立的專門用於存放專案的倉庫目錄/home/gitrepository。
使用su命令切換使用者賬號,su命令(switch user)
[email protected]:~$ su git
[email protected]:~$ sudo ln -s /home/gitrepository /home/git/repositories
[email protected]:~$ exit
2.5 生成ssh公鑰
在伺服器端生成ssh公鑰,如果想在其他機器上管理也可以在其他機器上生成一個ssh的公鑰。
[email protected]:~$ ssh-keygen -t rsa
ssh-keygen會確認金鑰的儲存位置(預設是 .ssh/id_rsa ),也可以根據實際情況重新填寫路徑和命名。然後它會要求你輸入兩次金鑰口令。 如果你不想在使用金鑰時輸入口令,將其留空即可。
然後用剛生成公鑰id_rsa.pub來對gitosis進行初始化。
[email protected]:~$ gitosis-init < ~/.ssh/id_rsa.pub
gitosis主要是通過gitosis-admin.git倉庫來管理一些配置檔案的,如使用者許可權的管理。這裡我們需要對其中的一個post-update檔案新增可執行的許可權。
[email protected]:~$ sudo chmod 755 /home/gitrepository/gitosis-admin.git/hooks/post-update
操作平臺:git使用者pc機
如果你將作為git使用者,那麼在你的電腦上(另一臺pc)上按上述操作生成ssh公鑰,然後git使用者需要將各自的公鑰傳送給Git 伺服器管理員,或將公鑰拷貝到伺服器的/tmp下。
[email protected]:~$ mkdir .ssh
[email protected]:~$ ssh-keygen -t rsa
在得到ssh公鑰時,提示將生成的ssh要鑰存放點路徑時填寫.ssh,然後有提示輸入密碼,可以直接按照回車。然後注意看提示,提示你的ssh公鑰匙已經存放到你當前路徑下的.ssh資料夾中。
將公鑰拷貝到伺服器的/tmp下或者是其他的方式進行授權檔案配置方法,選擇一種即可:
cp /路徑/.ssh/id_rsa.pub [email protected]gitServerIP:/tmp
注意:要把這裡的路徑改為上句命令下,提示你公鑰匙存放的路徑。這裡把上句命令中的IP 改為你自己作為git伺服器的pc的IP地址,例如192.168.1.22(地址我隨便編的,請大家填寫自己的ipv4地址)
3 伺服器上建立專案倉庫
3.1 建立測試倉庫
操作平臺:git伺服器
使用git賬戶在伺服器上建立一個目錄(testproject)並初始化成git專案倉庫(testproject)。
[email protected]:~$ su git
[email protected]:~$ cd /home/gitrepository
[email protected]:/home/gitrepository$ mkdir testproject
[email protected]:/home/gitrepository$ cd testproject
[email protected]:/home/gitrepository/testproject$ git init --bare
[email protected]:/home/gitrepository/testproject$ exit
說明:這裡對創庫的初始化,是必須在該testproject檔案中進行
但是,到目前為止,這只是一個空倉庫,空倉庫是不能clone下來的。為了能做clone,我們必須先讓某個有許可權的人放一個初始化的版本到倉庫中。
所以,我們必須先修改一下gitosis-admin.
3.2使用gitosis管理使用者許可權
一點分析:對於git伺服器來說,整體有三個部分,一部分是你自己的檔案,另外一個是快取區,最後一個就是本地庫。當你修改了自己的檔案後,你會git add xx將修改儲存到快取區,然後再用commit推送修改到本地庫中。注意git push是將本地倉庫的修改推送到伺服器的倉庫中,git commit是將本地修改儲存到本地倉庫中。
Git伺服器推行原則:先從遠端倉庫clone資料本地倉庫,本地進行修改操作完成之後在推送回git遠端倉庫中,不推行隨意的往遠端倉庫中推送資料的行為。因此在伺服器上,為了修改git倉庫中的/home/gitrepository/gitosis-admin.git這個管理許可權的倉庫,也是要把該倉庫clone到本地的一個倉庫中的。然後像前面說的,在本地倉庫中修改檔案,之後將本地修改儲存到本地倉庫。最後再將本地倉庫修改推送至伺服器倉庫。這樣就完成了伺服器許可權的修改了,當然,前提是要具有管理員許可權。
剛剛提到,gitosis本身的配置也是通過git來實現的。在你自己的開發機裡,把gitosis-admin.git這個倉庫clone下來,就可以以管理員的身份修改配置了。
操作平臺:git使用者usr1的pc1機
[email protected]:~/work$ mkdir gitadmin
[email protected]:~/work$ cd gitadmin
[email protected]:~/work/gitadmin$ git clone [email protected]:/home/gitrepository/gitosis-admin.git
[email protected]:~/work/gitadmin$ cd gitosis-admin/
clone下來的gitosis-admin檔案中有一個gitosis.conf的配置檔案和一個keydir的目錄。gitosis.conf用於配置使用者的許可權資訊,keydir主要使用者存放ssh公鑰檔案(一般以“使用者名稱.pub”命名,gitosis.conf配置檔案中需使用相同使用者名稱),用於配置git使用者對git遠端倉庫的操作許可權。
現在讓需要授權的git使用者按照前面的方式各自在其自己的機器上生成相應的ssh公鑰檔案,管理員把他們分別按使用者名稱命名好,比如b.pub, lz.pub等,統統拷貝到keydir目錄下。該目錄下的keydir目錄是用來存放所有需要訪問git伺服器的使用者的ssh公鑰:
[email protected]:~/work/gitosis-admin$ cp ~/.ssh/joy.pub ./keydir
[email protected]:~/work/gitosis-admin$ exit
然後修改gitosis.conf檔案,我的配置大致如下:
[gitosis]
[group gitosis-admin]? #管理員組
members = [email protected] #管理員使用者名稱。需要在keydir目錄下找到相應的.pub檔案,多個 ? #可用空格隔開
writable = gitosis-admin? #可寫的專案倉庫名,多個可用空格隔開(下同)
[group testwrite] #可讀寫許可權組
members = hw?joy #組成員
writable = testproject #可讀寫的專案倉庫
[group testread] #只讀許可權組
members = wf #組成員
readonly = testproject #只讀專案倉庫名
注意:這裡相當於有三個倉庫,分別是gitosis-admin,testwrite,testread。
這個配置檔案表達瞭如下含義:gitosis-admin組成員有git,相當於這倆是git伺服器的管理員。該組對gitosis-admin倉庫有讀寫許可權;
testwrite組有hw joy兩個成員,該組對testwrite倉庫有讀寫許可權;
testread組有wf一個成員,對testread倉庫有隻讀許可權。
當然目前這些配置檔案的修改只是在你的本地,你必須推送到遠端的gitserver上才能真正生效。
加入新檔案、提交併push到git伺服器:
[email protected]:/home/usr/work/gitosis-admin$ git add .
[email protected]:/home/usr/work/gitosis-admin$ git commit -am "add testwrite project and users permission"
[email protected]:/home/usr/work/gitosis-admin$ git push origin master
注意:這裡" "裡面的內容是自己寫的備註之類的東西,可以和上面不同,但是一定要使用英文的雙引號
新增的使用者許可權不能立即生效,這時候需要git伺服器上需要重新啟動一下ssh的服務
操作平臺:git伺服器
[email protected]:~$ sudo /etc/init.d/ssh restart
現在,服務端的git就已經安裝和配置完成了,接下來就需要有許可權的組成員在各自的機器上clone伺服器上的相應
專案倉庫進行相應的工作了。
4初始化測試專案
現在伺服器就搭建完了,並且有一個空的專案teamwork在伺服器上。接下來呢?當然是測試一下,空倉庫是不能clone的,所以需要某一個有寫許可權的人初始化一個版本。在git客戶端usr1完成以下操作。
4.1 從本地倉庫推送到伺服器倉庫
操作平臺:git使用者usr1的pc1機
[email protected]:~/work$ mkdir testproject
[email protected]:~/work$ cd testproject
[email protected]:~/work/testproject$ git init
[email protected]:~/work/testproject$ echo "this is a test text file,will push to server" > hello.txt
[email protected]:~/work/testproject$ git add .
[email protected]:~/work/testproject$ git commit -am "init a base version,add a first file for push to server"
[email protected]:~/work/testproject$ git remote rm origin
[email protected]:~/work/testproject$ git remote add origin [email protected]:/home/gitrepository/testproject.git
[email protected]:~/work/testproject$ git push -u origin master
注意:上述的git remote add origin命令中,仍然是把上句中的ServerIP 改成是你自己作為git伺服器的IP地址
到此為止testproject.git的倉庫的基礎版本就建成了,其他的組成員只要先clone一下 testproject.git倉庫,就可以任意玩了。
4.2 從伺服器倉庫clone到本地倉庫
接下來在git客戶端usr2來測試,將遠端倉庫從git伺服器上clone下來。
操作平臺:git使用者usr2的pc2機
[email protected]:~$ mkdir work
[email protected]:~$ cd work
[email protected]:~/work$ git clone [email protected]:/home/git/repositories/testproject.git
注意:這裡仍然是把上句中的IP 改成是你自己作為git伺服器的IP地址,同時如果當前目錄下已經有testproject檔案的時,執行git clone命令時會報錯
fatal: destination path 'testproject' already exists and is not an empty directory.
只要將目錄中與遠端倉庫中的專案名相同的檔案刪除後在執行git clone命令即可。
[email protected]:~/work$ cd testproject
[email protected]:~/work/testproject$ echo "this is another text file created by other" >another.txt
[email protected]:~/work/testproject$ git add .
[email protected]:~/work/testproject$ git commit -am "add a another file by other"
[email protected]:~/work/testproject$ git push origin master
[email protected]:~/work/testproject$ exit
至此,git伺服器基本功能已經搭建並測試完成了。
5 命令使用說明
5.1 查詢本地倉庫當前的origin
git remote -v查詢當前的origin
當需要往遠端倉庫中推送資料時,可以先檢視確認遠端倉庫的目標路徑設定,確保沒有推送到錯誤的專案工程中
5.2 刪除掉原有的origin
git remote rm origin刪除掉原有的origin
當發現遠端倉庫的目標路徑設定跟實際目標路徑不一致時,我們需要先刪除掉origin之後,在使用新增origin命令。
例如:
git remote add origin [email protected]:/home/git/repositories/testproject.git
或者出現如下錯誤時
都可以先刪除本地倉庫原有設定的origin,在重新新增origin
5.3 從本地倉庫最新的修改推送遠端倉庫
git push -u origin master -f 從本地倉庫推送遠端倉庫
備註:origin:遠端倉庫名字;master:分支
注意:我們第一次push的時候,加上-u引數,Git就會把本地的master分支和遠端的master分支進行關聯起來,我們以後的push操作就不再需要加上-u引數了
如果出現類似下面內容:
Username for 'https://github.com': shiren1118
Password for 'https://[email protected]':
To https://github.com/shiren1118/iOS_code_agile.git
![rejected] master -> master(non-fast-forward)
error: failed to push some refs to'https://github.com/shiren1118/iOS_code_agile.git'
hint: Updates were rejected because the tip of yourcurrent branch is behind
hint: its remote counterpart. Merge the remote changes(e.g. 'git pull')
hint: before pushing again.
hint: See the 'Note about fast-forwards' in 'git push--help' for details.
則輸入命令:git push -u origin master –f即可搞定問題
此處的-f就是--force的縮寫,表示強制推送到遠端倉庫中,因為前面提到的Git伺服器推行原則:先從遠端倉庫clone資料本地倉庫,本地進行修改操作完成之後在推送回git遠端倉庫中,不推行隨意的往遠端倉庫中推送資料的行為。因為這一種不負責任的行為。所以當有些倉庫並非從遠端倉庫clone到的本地,也選擇往遠端倉庫中推送資料時,會報如上錯誤。此時可以使用 -f引數強行推送,同時也是比較危險的行為,應該慎重使用。
前人種樹,後人乘涼。感謝前人的貢獻能幫助到我們,也希望我能繼續幫助到後續來者。
參考連結: