說明
本文轉(zhuǎn)載:
原GitHub地址:https://github.com/xirong/my-git
====================
由于公司團隊使用 GitLab 來托管代碼,同時,個人在 Github 上還有一些代碼倉庫,可公司郵箱與個人郵箱是不同的,由此產(chǎn)生的 SSH key 也是不同的,這就造成了沖突 ,文章提供此類問題的解決方案:**如何在一臺機器上面同時使用 Github 與 Gitlab 的服務(wù)?**
# 問題產(chǎn)生場景
## 無密碼與遠程服務(wù)器交互的秘密 - SSH
如果采用`ssh 協(xié)議`或者`git 協(xié)議`通過終端命令對遠程倉庫進行`push`操作的時候,大概的過程如下:(前提在 Github 上已經(jīng)配置的本機的 SSH Public Key)
1. 客戶端發(fā)起一個 Public Key 的認證請求,并發(fā)送RSA Key的模數(shù)作為標識符。(關(guān)于 RSA Key 詳細 [維基百科](https://en.wikipedia.org/wiki/RSA_(algorithm)))
2. 服務(wù)端檢查是否存在請求帳號的公鑰(Linux中存儲在~/.ssh/authorized_keys文件中),以及其擁有的訪問權(quán)限。
3. 服務(wù)端使用對應(yīng)的公鑰對一個隨機的256位的字符串進行加密,并發(fā)送給客戶端。
4. 客戶端使用私鑰對字符串進行解密,并將其結(jié)合session id生成一個MD5值發(fā)送給服務(wù)端。 結(jié)合session id的目的是為了避免攻擊者采用重放攻擊(replay attack)。
5. 服務(wù)端采用同樣的方式生成MD5值與客戶端返回的MD5值進行比較,完成對客戶端的認證。
6. 將push的內(nèi)容進行加密與服務(wù)端傳輸數(shù)據(jù)。
關(guān)于 SSH,請查看 [SSH原理簡介](http://erik-2-blog.logdown.com/posts/74081-ssh-principle) ,更通俗易懂的文章請查看[阮一峰-SSH原理與運用(一):遠程登錄](http://www.ruanyifeng.com/blog/2011/12/ssh_remote_login.html) 。
## 具體場景
無論使用哪種代碼托管服務(wù)商,對于 Git 而言,`郵箱` 是識別用戶的唯一手段,所以對于不同的服務(wù)商,由于郵箱不同,那么通過郵件名創(chuàng)建的 SSH Key 自然是不同的,這時候在不同的服務(wù)商之間進行 `push` 命令的時候,Git 是不知道使用哪個 SSH Key ,自然導致 `push` 的失敗。場景如下:
1. 在公司團隊使用搭建的 Gitlab 服務(wù),提交郵箱`xirong.liu@corp.xx.com`, 個人 Github 服務(wù),提交郵箱 `ixirong.liu@gmail.com` (Bitbucket 同理)。
2. 有兩個Github賬戶,不同的賬戶提交不同的倉庫內(nèi)容。
# 解決方案
## 方案一:同一個郵箱
由于`郵箱`是識別的唯一手段,那么自然的,這兩者采用同一個郵箱,生成的 public key 也會是同一個,上傳到 Github 或者 Gitlab 上面,在 Git 的配置中 ,設(shè)置好 Global 的配置 :` git config --global user.name 'xirong.liu' && git config --global user.email 'xirong.liu@corp.xx.com'` 進行日常的開發(fā)是沒有問題的。
實際生活中采用同一個郵箱的可能性并不是太大,這就引出了方案二
方案二:基于config文件
所謂的方案二,原理上就是對 SSH 協(xié)議配置 config 文件,對不同的域名采用不同的認證密鑰。
git config 介紹
Git有一個工具被稱為git config,它允許你獲得和設(shè)置配置變量;這些變量可以控制Git的外觀和操作的各個方面。這些變量可以被存儲在三個不同的位置:
1. /etc/gitconfig 文件:包含了適用于系統(tǒng)所有用戶和所有庫的值。如果你傳遞參數(shù)選項’`--system`’ 給 git config,它將明確的讀和寫這個文件。
2. ~/.gitconfig 文件 :具體到你的用戶。你可以通過傳遞 ‘`--global`’ 選項使Git 讀或?qū)戇@個特定的文件。
3. 位于 Git 目錄的 config 文件 (也就是 .git/config) :無論你當前在用的庫是什么,特定指向該單一的庫。每個級別重寫前一個級別的值。因此,在 .git/config 中的值覆蓋了在/etc/gitconfig中的同一個值,可以通過傳遞‘`--local`’選項使Git 讀或?qū)戇@個特定的文件。
由于采用了不同的郵箱,對不同的服務(wù)商進行提交,所以此時我們經(jīng)常配置的 `git config --global` 就不能常用了,必須在每個倉庫的目錄下進行配置自己的用戶名、郵箱。(嫌麻煩?xirong 是這么解決的,由于個人的 Github 上有較多的倉庫,而自己團隊的代碼基本上都是穩(wěn)定的,有數(shù)的幾個,所以在 `git config --global user.email 'ixirong.liu@gmail.com'` 中全局配置的是個人郵箱,在團隊的項目中配置)
1.? 配置 Git 用戶名、郵箱
如剛才所說,xirong 的配置如下:
# 全局配置,Github倉庫中默認使用此配置
git config --global user.name 'xirong' && git config --global user.email 'ixirong.liu@gmail.com'
# 團隊項目配置,每次新創(chuàng)建一個項目,需要執(zhí)行下
git config --local user.name 'xirong.liu' && git config --local user.email 'xirong.liu@corp.xxx.com'
### 2. 生成 ssh key 上傳到 Github/Gitlab
ssh key 默認生成后保存在 `~/.ssh/`目錄下 ,默認為 `id_rsa 和 id_rsa.pub` 兩個文件,由于我們需要分開配置,所以這么做:
# 生成公鑰、密鑰的同時指定文件名,Gitlab使用
ssh-keygen -t rsa -f ~/.ssh/id_rsa.gitlab -C "xirong.liu@corp.xxx.com"
# 生成默認,Github使用
ssh-keygen -t rsa -C "ixirong.liu@gmail.com"
命令執(zhí)行完成后,這時`~/.ssh`目錄下會多出`id_rsa.gitlab`和`id_rsa.gitlab.pub`兩個文件,`id_rsa.gitlab.pub` 里保存的就是我們要使用的key,這個key就是用來上傳到 Gitlab上的。
### 3. 配置 config 文件
在 `~/.ssh`目錄下,如果不存在,則新建 `touch ~/.ssh/config`文件 ,文件內(nèi)容添加如下:
Host *.corp.xxx.com
IdentityFile ~/.ssh/id_rsa.gitlab
User xirong.liu
配置完成后,符合 `*.corp.xxx.com`后綴的 Git 倉庫,均采取` ~/.ssh/id_rsa.gitlab` 密鑰進行驗證,其它的采取默認的。
4. 上傳public key 到 Github/Gitlab
以Github為例,過程如下:
1. 登錄github
2. 點擊右上方的Accounting settings圖標
3. 選擇 SSH key
4. 點擊 Add SSH key
在出現(xiàn)的界面中填寫SSH key的名稱,填一個你自己喜歡的名稱即可,然后將上面拷貝的`~/.ssh/id_rsa.pub`文件內(nèi)容粘帖到`key`一欄,在點擊“`add key`”按鈕就可以了。
添加過程github會提示你輸入一次你的github密碼 ,確認后即添加完畢。 上傳Gitlab的過程一樣,請自己操作。
?5. 驗證是否OK
由于每個托管商的倉庫都有唯一的后綴,比如 Github的是 `git@github.com:*`,所以可以這樣測試:
?? ~? ssh -T git@github.com
Hi xirong! You've successfully authenticated, but GitHub does not provide shell access.
?? ~? ssh -T git@gitlab.dev
Welcome to GitLab, xirong.liu!
看到這些 `Welcome` 信息,說明就是 OK的了。
以后,如果還有任何的需求,都可以這么解決,看下 xirong 的幾個托管倉庫:
?? ~? ll ~/.ssh
total 40
-rw-r--r-- 1 xirong staff? 264 Jul 10 14:42 config
-rw------- 1 xirong staff 3243 Jul 10 14:09 id_rsa
-rw------- 1 xirong staff 1675 Jan 28 20:39 id_rsa.gitlab
-rw-r--r-- 1 xirong staff? 407 Jan 28 20:39 id_rsa.gitlab.pub
-rw-r--r-- 1 xirong staff? 747 Jul 10 14:09 id_rsa.pub
-rw------- 1 xirong staff 1679 Jun 22 11:42 id_rsa_gitcafe
-rw-r--r-- 1 xirong staff? 407 Jun 22 11:42 id_rsa_gitcafe.pub
-rw-r--r-- 1 xirong staff 9139 Jul 29 15:08 known_hosts