可重復(fù)構(gòu)建( Reproducible Builds)是證明軟件供應(yīng)鏈安全的必要手段,2022已被納入SupplyChainSecurityCon的topics以及微軟的S2C2F(Secure Supply Chain Consumption Framework)當(dāng)中,并受到了Google開源安全團(tuán)隊(duì)的支持贊助。OpenSSF/SLSA在軟件供應(yīng)鏈完整性與包管理最佳實(shí)踐中也對(duì)可重復(fù)構(gòu)建有所要求。
2022年openEuler已初步建設(shè)可重復(fù)構(gòu)建能力。
什么是可重復(fù)構(gòu)建
對(duì)于可重復(fù)的構(gòu)建,給定相同的源代碼、構(gòu)建環(huán)境和構(gòu)建指令,任何人均可重建出Bit to Bit完全相同的指定制品。
可重復(fù)構(gòu)建的目的與意義
可重復(fù)構(gòu)建可以驗(yàn)證二進(jìn)制是否被植入后門,避免潛在安全風(fēng)險(xiǎn),從而保障二進(jìn)制的質(zhì)量。構(gòu)建環(huán)境和構(gòu)建工程能夠被還原,使依賴變化范圍最小化、測(cè)試最小化,方便問題定位、提高開發(fā)效率。
通過(guò)可重復(fù)構(gòu)建可以創(chuàng)建從代碼到制品的可獨(dú)立驗(yàn)證路徑,結(jié)合已有的代碼發(fā)布簽名、軟件倉(cāng)庫(kù)簽名、安全啟動(dòng)等技術(shù),使開源代碼從生產(chǎn)到使用的全過(guò)程可追溯成為可能。
構(gòu)建差異產(chǎn)生的原因
在代碼構(gòu)建期間,從源代碼到產(chǎn)品發(fā)布的二進(jìn)制包,中間每一個(gè)步驟、每一個(gè)構(gòu)建工具都有可能引入二進(jìn)制差異,而這些差異經(jīng)過(guò)逐步放大,導(dǎo)致最終發(fā)布的二進(jìn)制包每次編譯都不相同,而且差異非常巨大。
二進(jìn)制差異案例(差異放大)
導(dǎo)致構(gòu)建差異的因素有很多,包含環(huán)境、時(shí)間戳、隨機(jī)數(shù)、文件亂序等等,這些差異都是在構(gòu)建過(guò)程中生成的。數(shù)字簽名可以證明源碼和二進(jìn)制的唯一性,但是無(wú)法證明源碼與二進(jìn)制之間對(duì)應(yīng)關(guān)系的一致性。證明源碼與二進(jìn)制一致性的工作量非常大、技術(shù)難度高。例如下圖在各編譯過(guò)程中可能會(huì)產(chǎn)生差異的因素:
openEuler可重復(fù)構(gòu)建方案
openEuler當(dāng)前的可重復(fù)構(gòu)建是將rpm包構(gòu)建兩次,再進(jìn)行對(duì)比。在構(gòu)建過(guò)程中利用開源工具libfaketime進(jìn)行差異消除,構(gòu)建結(jié)束后將兩次構(gòu)建出的rpm包進(jìn)行對(duì)比,若rpm不一致,則進(jìn)行解壓繼續(xù)對(duì)比,將差異粒度精確到文件,并輸出差異報(bào)告。
為了達(dá)到構(gòu)建可重復(fù)的目的,通常要滿足兩個(gè)條件:
1、構(gòu)建系統(tǒng)的完全確定性,保證兩次構(gòu)建的日期、時(shí)間完全相同(或者去除掉時(shí)間信息),文件順序一致;
2、是用的構(gòu)建工具集及構(gòu)建工具需要一致或被記錄。
主要措施有以下三步:
1、 openEuler的可重復(fù)構(gòu)建使用了libfaketime工具消除差異。此工具主要是利用LD_PRELOAD環(huán)境變量進(jìn)行差異消除。LD_PRELOAD 是 Linux 系統(tǒng)的一個(gè)環(huán)境變量,它可以影響程序的運(yùn)行時(shí)的鏈接(Runtime linker),通過(guò)此變量將 Linux 系統(tǒng)自帶的動(dòng)態(tài)庫(kù).so 替換我們自己動(dòng)態(tài)庫(kù)中自定義的函數(shù),例如:time()、gethostname()、random()、rand()等函數(shù),確保編譯過(guò)程中獲取的時(shí)間、主機(jī)名、隨機(jī)數(shù)能夠保持一致。
差異消除工具原理
通過(guò)使用此工具,產(chǎn)品源代碼不需要修改,從而減少了產(chǎn)品在代碼糾正方面的投資,商業(yè)和開放源代碼工具所產(chǎn)生的差異也將得到消除,也無(wú)需進(jìn)行任何代碼修改,而且時(shí)間戳的語(yǔ)義被最大程度地保存。并且可以通過(guò)“ unset LD_PRELOAD”格式的命令禁用該工具。
除了libfaketime原有的功能以外,我們?cè)诖嘶A(chǔ)上進(jìn)行擴(kuò)展,增加了精準(zhǔn)黑白名單的機(jī)制可以有效解決因使用libfaketime而導(dǎo)致的構(gòu)建失敗問題;并完善了消除隨機(jī)數(shù)差異功能,增加了對(duì)random()、rand()、/dev/random、/dev/urandom獲取隨機(jī)數(shù)方法的替換。
2、 openEuler的可重復(fù)構(gòu)建還用到了unpacker自動(dòng)化解包對(duì)比工具,可以精準(zhǔn)分析文件級(jí)差異,輸出可視化差異報(bào)告。對(duì)比兩次構(gòu)建出rpm的校驗(yàn)值,若校驗(yàn)值一致則認(rèn)為構(gòu)建可重復(fù);若校驗(yàn)值不一致,則進(jìn)行解包對(duì)比,若兩個(gè)rpm包解壓后所有文件的校驗(yàn)值均一致,同樣認(rèn)為構(gòu)建可重復(fù),若出現(xiàn)不一致文件則使用diffoscope進(jìn)行對(duì)比并輸出差異報(bào)告。此外,工具會(huì)將RSA、PGP簽名文件從rpm包中拆分出來(lái),不會(huì)將簽名文件差異當(dāng)作是rpm差異。
解包對(duì)比工具原理
差異報(bào)告樣例
3、將rpm包對(duì)比結(jié)束后,我們會(huì)將對(duì)比結(jié)果以及差異報(bào)告歸檔,并在openEuler的可重復(fù)構(gòu)建網(wǎng)站展示并進(jìn)行治理。
2022年我們已經(jīng)對(duì)openEuler核心1800+個(gè)代碼倉(cāng)分別在arm及x86環(huán)境下進(jìn)行了可重復(fù)構(gòu)建的比對(duì),涉及軟件包6000+,可重復(fù)率達(dá)到了98%。今年我們把可重復(fù)構(gòu)建范圍擴(kuò)大到了openEuler 22.09的Everything版本,構(gòu)建成功了4130個(gè)代碼倉(cāng),涉及軟件包14000+,可重復(fù)率達(dá)到94%左右。經(jīng)過(guò)初步的分析,當(dāng)前大部分不可重復(fù)代碼倉(cāng)是因?yàn)闃?gòu)建出的rpm包存在html文件差異。
openEuler可重復(fù)構(gòu)建規(guī)劃
1、 針對(duì)不可重復(fù)代碼倉(cāng)分析原因、提出解決建議,并回合到上游社區(qū)。
2、 使用EulerMaker替換OBS進(jìn)行構(gòu)建,解決由于libfaketime導(dǎo)致的構(gòu)建失敗問題,并實(shí)現(xiàn)通過(guò)“元數(shù)據(jù)”隨時(shí)復(fù)現(xiàn)構(gòu)建過(guò)程的能力。
3、 逐步提高openEuler代碼倉(cāng)可重復(fù)率,達(dá)成Everything版本代碼倉(cāng)可重復(fù)率98%以上,領(lǐng)先業(yè)界水平。
4、 復(fù)制可重復(fù)構(gòu)建能力,幫助合作伙伴達(dá)成可重復(fù)構(gòu)建目標(biāo)。
審核編輯:劉清
-
freebsd
+關(guān)注
關(guān)注
0文章
37瀏覽量
10741 -
GNU
+關(guān)注
關(guān)注
0文章
142瀏覽量
17404 -
openEuler
+關(guān)注
關(guān)注
2文章
299瀏覽量
5783 -
Debian
+關(guān)注
關(guān)注
0文章
74瀏覽量
1094
原文標(biāo)題:可重復(fù)構(gòu)建為軟件供應(yīng)鏈安全保駕護(hù)航
文章出處:【微信號(hào):openEulercommunity,微信公眾號(hào):openEuler】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論