備注:本筆記所描述的問題的前提是機器上已安裝成功git且通過配置ca證書支持以https方式獲取遠程倉庫,如果使用git時碰到這篇文章描述的問題,那么按那篇文章給出的辦法解決即可。
最近從github clone repo時,git clone命令報錯如下(以vim代碼補全插件youcompleteme為例):
[plain]view plaincopy
$?git?clone?https://github.com/Valloric/YouCompleteMe.git
Cloning?into?'YouCompleteMe'...
fatal:?unable?to?access?'https://github.com/Valloric/YouCompleteMe.git/':?error:0D0890A1:asn1?encoding?routines:ASN1_verify:unknown?message?digest?algorithm
由于git底層是用本機安裝的curl去fetch遠程repo的,所以我們可以打開curl調試選項查看具體的錯誤:
[plain]view plaincopy
$?export?GIT_CURL_VERBOSE=1
$?git?clone?https://github.com/Valloric/YouCompleteMe.git
Cloning?into?'YouCompleteMe'...
*?Couldn't?find?host?github.com?in?the?.netrc?file,?using?defaults
*?About?to?connect()?to?github.com?port?443
*???Trying?192.30.252.129...?*?connected
*?Connected?to?github.com?(192.30.252.129)?port?443
*?successfully?set?certificate?verify?locations:
*???CAfile:?/home/slvher/tools/https-ca/github-ca/ca-bundle.crt
CApath:?none
*?error:0D0890A1:asn1?encoding?routines:ASN1_verify:unknown?message?digest?algorithm
*?Closing?connection?#0
fatal:?unable?to?access?'https://github.com/Valloric/YouCompleteMe.git/':?error:0D0890A1:asn1?encoding?routines:ASN1_verify:unknown?message?digest?algorithm
從verbose輸出可知,git已經借助curl成功連接上github.com,但以https方式clone remote repo時,由于本地配置的CAfile無法識別github提供的ssl認證算法,所以本次session失敗退出。
從stackoverflow的這個帖子(Can not use “git pull” beacause of some error)得知,github在https的ssl認證中,采用的是sha256算法,而這個sha256算法是openssl從version 0.9.8o才引入的。
用下面的命令驗證我機器(公司統一的開發環境)上openssl的版本,發現居然是0.9.7a,這個版本不支持github采用的sha256算法,真心蛋疼。。。
[python]view plaincopy
$?python?-c'import?ssl;?print?ssl.OPENSSL_VERSION'
OpenSSL0.9.7aFeb192003
既然git clone報錯的原因已清楚,解決思路就明確了,可以執行下面的步驟進行修復。
1. 更新機器上的openssl庫至v0.9.8o或更高版本
a. 從openssl官網下載合適的版本,例如我下載的是openssl-1.0.1j.tar.gz
b. 解壓上步下載的壓縮包,cd至解壓目錄
c. 在當前shell終端執行以下命令
[plain]view plaincopy
$?export?CFLAGS="-fPIC"
$?./config?shared?--openssldir=/home/slvher/tools/openssl-1.0.1j/??##?無root權限,故由openssldir指定自定義安裝路徑
$?make?depend
$?make?all
$?make?install
openssl源碼編譯/安裝成功后,可在openssldir指定的目錄下看到下面的目錄結構
[plain]view plaincopy
$?ls
bin??certs??include??lib??man??misc??openssl.cnf??private
我們需要的共享庫libssl.so文件在lib目錄下。
備注1:更新版本時需注意曾在2014年4月爆發的針對openssl version 1.0.1的heartbleed漏洞,所以需要下載openssl ver 1.0.1g或更高版本。
備注2:這步安裝openssl至非系統默認目錄是由于我沒有root權限,不能覆蓋系統默認的openssl版本,而且冒然升級也可能影響到機器上其他用戶。這也直接導致本文的解決方法還需要完成下面3個步驟。
2. 重新編譯curl或替換curl依賴的openssl共享庫
顯然,相比于重新源碼編譯curl,直接替換curl依賴的libssl.so更方便,借助LD_PRELOAD即可實現目的:
[plain]view plaincopy
$?export?LD_PRELOAD=/home/slvher/tools/openssl-1.0.1j/lib/libssl.so:/home/slvher/tools/openssl-1.0.1j/lib/libcrypto.so
$?python?-c?'import?ssl;?print?ssl.OPENSSL_VERSION'?##?驗證是否替換成功,我機器的輸出為OpenSSL?1.0.1j?15?Oct?2014,可見成功替換
3. 驗證git clone是否能成功執行
[plain]view plaincopy
$?git?clone?https://github.com/Valloric/YouCompleteMe.git
Cloning?into?'YouCompleteMe'...
remote:?Counting?objects:?29685,?done.
remote:?Compressing?objects:?100%?(3/3),?done.
remote:?Total?29685?(delta?0),?reused?0?(delta?0)
Receiving?objects:?100%?(29685/29685),?28.81?MiB?|?5.77?MiB/s,?done.
Resolving?deltas:?100%?(9501/9501),?done.
Checking?connectivity...?done.
至此,目的達成。世界真美妙 ^_^
4. 將替換openssl庫的過程自動化
第2步通過設置環境變量LD_PRELOAD實現了更新curl依賴的libssl.so共享庫版本的目的。但這個替換動作只對當前終端的session有效,當該session窗口關閉或切換到其它窗口時,執行git clone還是會出錯。
將這種替換操作自動化的一個方法是在~/.bash_profile中將LD_PRELOAD設置為新版libssl.so的路徑并export該變量。但這種方式可能會影響當前用戶下的所有模塊。
這里我借助bash的alias命令對git clone的動作做改寫:
1) 打開~/.bashrc文件
2) 給git命令設置alias
[plain]view plaincopy
alias?git='export?LD_PRELOAD=/home/slvher/tools/openssl-1.0.1j/lib/libssl.so:/home/slvher/tools/openssl-1.0.1j/lib/libcrypto.so;?git'
3) 保存退出
4) 在其他終端窗口執行source ~/.bashrc
5) 在該窗口驗證git clone是否正常,可以驗證,alias設置是成功的
至此,終于大功告成。
【參考資料】
1. stackoverflow:Can not use “git pull” beacause of some error
2. OpenSSL Doc:Compilation and Installation
3. wikipedia:Heartbleed
========================= EOF =========================備注:本筆記所描述的問題的前提是機器上已安裝成功git且通過配置ca證書支持以https方式獲取遠程倉庫,如果使用git時碰到這篇文章描述的問題,那么按那篇文章給出的辦法解決即可。
最近從github clone repo時,git clone命令報錯如下(以vim代碼補全插件youcompleteme為例):
[plain]view plaincopy
$?git?clone?https://github.com/Valloric/YouCompleteMe.git
Cloning?into?'YouCompleteMe'...
fatal:?unable?to?access?'https://github.com/Valloric/YouCompleteMe.git/':?error:0D0890A1:asn1?encoding?routines:ASN1_verify:unknown?message?digest?algorithm
由于git底層是用本機安裝的curl去fetch遠程repo的,所以我們可以打開curl調試選項查看具體的錯誤:
[plain]view plaincopy
$?export?GIT_CURL_VERBOSE=1
$?git?clone?https://github.com/Valloric/YouCompleteMe.git
Cloning?into?'YouCompleteMe'...
*?Couldn't?find?host?github.com?in?the?.netrc?file,?using?defaults
*?About?to?connect()?to?github.com?port?443
*???Trying?192.30.252.129...?*?connected
*?Connected?to?github.com?(192.30.252.129)?port?443
*?successfully?set?certificate?verify?locations:
*???CAfile:?/home/slvher/tools/https-ca/github-ca/ca-bundle.crt
CApath:?none
*?error:0D0890A1:asn1?encoding?routines:ASN1_verify:unknown?message?digest?algorithm
*?Closing?connection?#0
fatal:?unable?to?access?'https://github.com/Valloric/YouCompleteMe.git/':?error:0D0890A1:asn1?encoding?routines:ASN1_verify:unknown?message?digest?algorithm
從verbose輸出可知,git已經借助curl成功連接上github.com,但以https方式clone remote repo時,由于本地配置的CAfile無法識別github提供的ssl認證算法,所以本次session失敗退出。
從stackoverflow的這個帖子(Can not use “git pull” beacause of some error)得知,github在https的ssl認證中,采用的是sha256算法,而這個sha256算法是openssl從version 0.9.8o才引入的。
用下面的命令驗證我機器(公司統一的開發環境)上openssl的版本,發現居然是0.9.7a,這個版本不支持github采用的sha256算法,真心蛋疼。。。
[python]view plaincopy
$?python?-c'import?ssl;?print?ssl.OPENSSL_VERSION'
OpenSSL0.9.7aFeb192003
既然git clone報錯的原因已清楚,解決思路就明確了,可以執行下面的步驟進行修復。
1. 更新機器上的openssl庫至v0.9.8o或更高版本
a. 從openssl官網下載合適的版本,例如我下載的是openssl-1.0.1j.tar.gz
b. 解壓上步下載的壓縮包,cd至解壓目錄
c. 在當前shell終端執行以下命令
[plain]view plaincopy
$?export?CFLAGS="-fPIC"
$?./config?shared?--openssldir=/home/slvher/tools/openssl-1.0.1j/??##?無root權限,故由openssldir指定自定義安裝路徑
$?make?depend
$?make?all
$?make?install
openssl源碼編譯/安裝成功后,可在openssldir指定的目錄下看到下面的目錄結構
[plain]view plaincopy
$?ls
bin??certs??include??lib??man??misc??openssl.cnf??private
我們需要的共享庫libssl.so文件在lib目錄下。
備注1:更新版本時需注意曾在2014年4月爆發的針對openssl version 1.0.1的heartbleed漏洞,所以需要下載openssl ver 1.0.1g或更高版本。
備注2:這步安裝openssl至非系統默認目錄是由于我沒有root權限,不能覆蓋系統默認的openssl版本,而且冒然升級也可能影響到機器上其他用戶。這也直接導致本文的解決方法還需要完成下面3個步驟。
2. 重新編譯curl或替換curl依賴的openssl共享庫
顯然,相比于重新源碼編譯curl,直接替換curl依賴的libssl.so更方便,借助LD_PRELOAD即可實現目的:
[plain]view plaincopy
$?export?LD_PRELOAD=/home/slvher/tools/openssl-1.0.1j/lib/libssl.so:/home/slvher/tools/openssl-1.0.1j/lib/libcrypto.so
$?python?-c?'import?ssl;?print?ssl.OPENSSL_VERSION'?##?驗證是否替換成功,我機器的輸出為OpenSSL?1.0.1j?15?Oct?2014,可見成功替換
3. 驗證git clone是否能成功執行
[plain]view plaincopy
$?git?clone?https://github.com/Valloric/YouCompleteMe.git
Cloning?into?'YouCompleteMe'...
remote:?Counting?objects:?29685,?done.
remote:?Compressing?objects:?100%?(3/3),?done.
remote:?Total?29685?(delta?0),?reused?0?(delta?0)
Receiving?objects:?100%?(29685/29685),?28.81?MiB?|?5.77?MiB/s,?done.
Resolving?deltas:?100%?(9501/9501),?done.
Checking?connectivity...?done.
至此,目的達成。世界真美妙 ^_^
4. 將替換openssl庫的過程自動化
第2步通過設置環境變量LD_PRELOAD實現了更新curl依賴的libssl.so共享庫版本的目的。但這個替換動作只對當前終端的session有效,當該session窗口關閉或切換到其它窗口時,執行git clone還是會出錯。
將這種替換操作自動化的一個方法是在~/.bash_profile中將LD_PRELOAD設置為新版libssl.so的路徑并export該變量。但這種方式可能會影響當前用戶下的所有模塊。
這里我借助bash的alias命令對git clone的動作做改寫:
1) 打開~/.bashrc文件
2) 給git命令設置alias
[plain]view plaincopy
alias?git='export?LD_PRELOAD=/home/slvher/tools/openssl-1.0.1j/lib/libssl.so:/home/slvher/tools/openssl-1.0.1j/lib/libcrypto.so;?git'
3) 保存退出
4) 在其他終端窗口執行source ~/.bashrc
5) 在該窗口驗證git clone是否正常,可以驗證,alias設置是成功的
至此,終于大功告成。
【參考資料】
1. stackoverflow:Can not use “git pull” beacause of some error
2. OpenSSL Doc:Compilation and Installation
3. wikipedia:Heartbleed
========================= EOF =========================