Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
著業務的發展,系統會越來越龐大,原本簡單穩定的功能,可能在不斷迭代后復雜度上升,潛在的風險也隨之暴露,導致最終服務不穩定,造成業務價值的損失。而為了減少這種情況,其中一種比較好的方式就是提高代碼質量,比如通過代碼審查,從而降低錯誤風險,但是,代碼審查難度大,代碼缺陷、漏洞不易發現,且審查工作隨著代碼量增加而增加,審查效率低。
工欲善其事,必先利其器,因此,這篇文章給大家介紹幾種檢查代碼質量的利器,Alibaba Java Coding Guidelines、CheckStyle、PMD、FindBugs、SonarLint,讓你在關注代碼質量的同時,減少 code review 的工作量,提高 code review 的效率,并通過代碼質量分析去反向提升我們的代碼編寫能力
Alibaba Java Coding Guidelines 專注于Java代碼規范,目的是讓開發者更加方便、快速規范代碼格式。該插件在掃描代碼后,將不符合規約的代碼按 Blocker、Critical、Major 三個等級顯示出來,并且大部分可以自動修復,它還基于 Inspection 機制提供了實時檢測功能,編寫代碼的同時也能快速發現問題所在。
阿里巴巴規約掃描包括:
File > Settings > Plugins > Marketplace 搜索 “Alibaba Java Coding Guidelines”,按照提示進行安裝,然后重啟即可。
3.1、運行方式:
(1)可以Tools > 阿里編碼規約 > 編碼規約掃描
(2)在編輯界面或者項目區域點擊右鍵,在右鍵菜單中選擇“編碼規約掃描”即可:
3.2、菜單功能:
3.3、運行結果:
掃描完成后顯示結果如下,我們可以看到掃描結果主要分為 Blocker(阻擋者)、Critical(嚴重問題)、Major(主要的)三個大類,它們表示的是問題的嚴重程度,嚴重程度由高到低為:Blocker > Critical > Major,至于每一類中都會包含什么樣的問題,圖中的內容已經說明了一切。
選中其中的一個問題項目,會出現如下內容(如果當前鼠標點擊的是最終項,右邊區域顯示的是其它的內容,后面會再講到):
(1)指定區域搜索同一類問題:
當點擊③處的按鈕時,會彈出如下按鈕:
這里選擇掃描區域,來掃描鼠標選中的同類問題。如果按照默認選擇,那么運行后的結果就如下圖所示:
這里我們可以看到,顯示了整個Project中的所有該類的問題。
(2)預覽具體的不規范代碼:
如果點擊的是最終的問題點或者問題所在的類文件,那顯示的就是如下界面,預覽該處不規范的代碼。
3.4、工具欄功能介紹:
CheckStyle 側重檢查編碼格式和代碼風格規范,如命名規范、Javadoc注釋規范、空格規范、size度量(如過長的方法)、重復代碼、多余Imports等,從而有效約束開發人員更好地遵循代碼編寫規范。Checkstyle主要是文法層面的代碼編寫規范的分析,對bug幾乎沒什么發現能力。
Checkstyle插件中默認內置有2個執行代碼檢查的配置文件(Sun Checks 和 Sun Checks),但是這兩個文件檢查的非常詳細嚴格,即使優秀的開源項目也會檢查出來有非常多的錯誤告信息,所以需要導入我們自定義的配置文件。
通過 File > Settings > Plugins > Marketplace 搜索 “CheckStyle”,按照提示進行安裝,然后重啟即可。
可以看到基本都是一些縮進啥的編碼規范,可以不用太關注
PMD側重面向安全編碼規則,且具備一定的數據流分析和路徑分析能力,能力比CheckStyle稍微強點,并且 PMD 支持自定義規則,PMD可以直接使用的規則包括以下內容:
通過 File > Settings > Plugins > Marketplace 搜索 “PMDPlugin”,按照提示進行安裝,然后重啟即可
3.1、運行方式:
(1)從Tools菜單中啟動:
通過 Tools > Run PMD 可以看到如下的界面,如果通過該方式啟動,掃描的范圍就是整個項目中的文件了。
(2)從右鍵菜單中啟動:
在文件或者編輯器中點擊右鍵,也可以看到“Run PMD”選項,如果通過該方式啟動, 檢測范圍取決于鼠標或光標當前所選中的區域。
3.2、運行結果:
運行后會出現如上所示的面板,左邊工具欄,鼠標停留在上面會提示其功能;右邊顯示了檢測結果,當點擊具體某一問題項時,會跳轉到對應的源碼中。
3.3、配置檢測規則:
通過 File > Settings > Other Settings > PMD 可以打開檢測規則的設置界面:
在 “RuleSets(規則設置)” 界面可以管理自定義的檢測規則。因為在實際工作中,可能需要根據實際情況自定義檢測規則,就可以通過這里導入,如果要使用它,需要在啟動PMD進行檢測時選擇該自定義規則。
點擊“Options”選項卡,在其中可以配置一些檢測規則選項:
其中重點需要留意的是“Skip TestSource”這一項,因為在項目中有不少Android Studio自動生成的測試代碼,如下所示,選擇上述選項后可以將其過濾掉。
FindBugs 側重于發現代碼中存在的bug,如運行時錯誤檢測(空指針檢查、未合理關閉資源、字符串相同判斷錯(==,而不是equals)等),它可以簡單高效全面地幫助我們發現程序代碼中存在的bug以及潛在隱患,針對各種問題,它提供了簡單的修改意見供我們參考
通過 File > Settings > Plugins > Marketplace 搜索 “FindBugs”,按照提示進行安裝,然后重啟即可
FindBugs 可以分析單個文件、包下面的所有文件、整個module下的文件、整個project下的文件,右鍵想要分析的文件名/包名/module名/project
分析完之后就會出現結果面板
點擊對應的item在右邊會定位到具體的代碼,這是根據提示進行處理修改就行
4.1、Bad practice 代碼壞習慣:
4.2、Dodgy code 糟糕的代碼:
4.3、Internationalization 代碼國際化相關:
4.4、Performance 代碼性能相關:
4.5、Experimental:
4.6、Malicious code vulnerability 惡意破壞代碼相關:
4.7、Multithreaded correctness 多線程代碼正確性相關:
4.8、Correctness 代碼正確性相關:
sonar 比 Findbugs 高了一個層級,它不僅關注常規靜態BUG,還關注到了如代碼質量、包與包、類與類之間的依賴情況,代碼耦合情況,類、方法、文件的復雜度,代碼中是否包含大量復制粘貼的代碼,關注的是項目代碼整體的健康情況。sonar 有兩種使用方式:插件和客戶端,sonar 的插件名稱為 sonarLint。
通過 File > Settings > Plugins > Marketplace 搜索 “SonarLint”,按照提示進行安裝,然后重啟即可
右鍵項目或者文件進行如上圖所示操作,執行之后可以看到如下信息,如果代碼中有不合理的地方會在report中顯示,同時點擊錯誤的地方在右邊會給出建議的修改供參考。
4.1、配置 Sonar 服務器:
sonarLint 插件的使用場景是自用自審,但 sonar 也提供了平臺版本,使用場景則是他審,sonar 平臺的搭建就不在這篇文章介紹了,感興趣的讀者可以自己上網查看,我們這里主要介紹如何在 sonarLint 插件中配置關聯 sonar 平臺服務器的工程,進行本地檢查:
點擊新增按鈕,輸入Configuration Name,配置sonarlint 服務器的地址,然后下拉框選擇 Login/Password,輸入 sonarlint服務器的賬號密碼
4.2、具體 Sonar工程配置:
配置完服務器之后,需要針對具體工程進行配置,點擊 connection下拉框,選擇上面配置好的服務器連接,然后點擊 Search in list,找到對應的工程:
4.3、使用 SonarLint 檢查:
配置完上面兩步之后,接下來就可以選擇要進行檢查的類或者目錄進行 sonarlint 檢查了(跟第3點的使用方式一致),同時,在 commit 代碼的時候,勾選 “Perform Sonarlint analysis”,會針對你要提交的代碼進行sonarlint檢查
onarSource目前提供三類產品,分別是SonarLint、SonarQube以及SonarCloud。三類產品雖然應用場景不同,但都給開發人員提供了靜態代碼分析(SAST)的能力,也就是在不運行程序的情況下通過一系列程序分析技術持續對代碼進行理解與檢測,發現代碼中存在的漏洞。
SonarSource的愿景是希望從根本上改變組織交付軟件的方式,幫助研發人員交付清潔代碼,即安全、健壯且可以發展的代碼。
"代碼重構/改善代碼質量"這件事情比作投資:“我們擁有的這種方法的美妙之處在于它不再花費;對于相同的投資,你有很好的代碼,以后你會有更大的投資回報,所以一開始的‘正確’就尤為重要,這是使軟件成為資產而非負債所需的唯一步驟
在整個的開發鏈條中還有其他工具也可以檢測軟件中存在的漏洞,比如IAST,DAST,FUZZ。這些動態測試工具受限于檢測漏洞的原理,往往需要較高的使用條件,比如需要準備軟件的運行環境、需要在測試過程中與軟件進行交互來觸發軟件的功能、需要準備大量的測試用例。
而基于不同理念所產生的靜態分析工具則沒有此類限制,只需要接觸源代碼即可完成分析。這樣的天然優勢給予了靜態代碼分析類工具更廣闊的市場空間,使得靜態代碼分析類工具更有可能成為走向研發者市場,成為一類具備普適性的研發效能工具。SonarSource的成功路徑也從側面證明了這一點。然而當我們把目光聚焦在國內市場,并沒有發現類似SonarSource的企業。在中國,靜態分析類工具仍然處在一個突破使用場景和市場空間的過程中,究其原因,我們認為以下三個方面的問題可能能夠做一些說明:
目前國內市場上常見的靜態代碼分析工具具備較高的使用門檻。從開始接觸到成功落地往往需要較多的適配與培訓工作,需要企業投入較多的時間與人力成本。在研發工具接受程度與使用習慣還未養成的中國市場,這些先決條件往往成為勸退企業的第一道門檻,導致了很多有相關需求的中小型企業望而卻步。
從用途來說,靜態代碼分析工具屬于軟件研發體系的支撐性工具,其使用場景往往會隨著軟件研發體系的變化而變化。
目前國內市場主流的靜態代碼分析工具仍然停留在傳統的客戶端軟件時代,用戶通過上傳代碼進行集中式的分析與結果展示。當用戶需要在現代化的研發體系(如模塊化DevOps敏捷流水線)中去使用相關能力時,這種傳統的軟件形態往往會帶來較多的麻煩,導致落地成本的提升和自動化程度的降低。
目前國外走在前沿的分析類工具,如SonarQube、 Snyk和Coverity均采用了解耦式的模塊化設計,方便用戶進行流水線集成和自動化調度。
隨著軟件產業的飛速發展,過去二十年間用戶對于靜態代碼分析類工具的需求也在不斷提升。從最早期進行代碼風格的管理,到嵌入式時代對于代碼質量的合規要求,到今天對于安全漏洞的治理。軟件的復雜程度日益提升,靜態代碼分析工具試圖解決的問題也越發復雜。現有的工具在面對復雜的軟件安全漏洞時,分析精度直線下降,誤報率往往超過50%。過高的誤報率帶來的是使用成本的大幅提升,同時也造就了靜態代碼分析類工具落地成本高,使用復雜的刻板印象。能否解決好復雜代碼場景的分析精度問題,是決定SAST類工具接受程度的核心難題。
SonarSource提供的一整套解決方案會在開發過程的整個生命周期,以及每個階段執行檢查。整套解決方案的核心理念是“Clean as You Code”。在開發者完成一部分新的代碼之后,可以將代碼推給掃描工具,并對這一部分的代碼的品質進行分析和評價,以保證開發者的代碼一直保持滿足標準的狀態。這個標準的狀態通過“Quality Gate”來嚴格把守,它是發布前的最后一道檢查,只有滿足所有的要求才能發布到生產環境中,比如代碼覆蓋率,可靠性評級等等。開發人員可以設置自己的標準,也可以使用SonarSource提供的默認標準“SonarWay”。
SonarLint是一個IDE擴展,可幫助開發人員在編寫代碼時檢測和修復質量問題。就像Grammarly拼寫檢查器一樣,SonarLint會實時提供反饋,以便在提交代碼之前修復它們。此外,SonarLint會提供詳細的規則描述和最佳實踐來展示代碼問題的原因與解決方案,開發人員可以在編碼的同時學習提高自己的技能。
公司主打的SAST產品。產品是分離式的架構,一側為SonarQube平臺,可以在web端查看掃描結果;另一側是SonarScanner,這是公司十多年來構建的代碼分析引擎,內含5000多條規則積累。此外SonarQube 并不是簡單地將各種質量檢測工具的結果直接展現給客戶,而是通過不同的算法來對這些結果進行再加工,最終以量化的方式來衡量代碼質量,并進行管理。
公司推出的SaaS云服務,針對開源項目進行分析檢測。基本功能和普通的SonarQube差不多,但提供更多的SaaS級別的服務。
上述三種產品本質上共同解決了三類代碼問題,分別是代碼可靠性,代碼安全性以及技術負債(代碼可維護性)。
分析引擎可以針對代碼中的Bug以及開發路徑存在的問題進行檢測。Bug通常是指一種編碼錯誤,可能會導致程序運行時出現錯誤或意外。
SonarQube可以展示代碼中的安全熱點(Security Hotspots),也就是一些敏感代碼,但它們不會影響整體應用程序安全性,也不需要研發人員立刻進行修復。但是事后審查的判斷是有必要的,因為研發人員可能也會發現這些“敏感地帶”會存在風險。除了安全熱點以外,分析引擎還可以針對安全漏洞(Vulnerabilities)進行檢測,安全漏洞是需要立即修復的,它們會嚴重影響應用程序安全性。這樣的分類方式進一步降低了誤報率,對研發人員更加友好。
分析引擎主要檢測的安全漏洞分為兩類。第一種是安全注入問題,第二種是安全配置問題。
分析引擎可以檢測代碼異味,也就是代碼可維護性的問題。通常它們使代碼混亂且難以維護,換而言之,維護人員不知道如何修復這段代碼,最壞的情況是原來的問題還沒有修復,就引入新的問題。代碼異味包括“七宗罪”,分別是不遵循代碼標準,潛在缺陷,糟糕的復雜度分布,重復,注釋不足或過多,缺乏單元測試,糟糕的設計。
這七點也是檢測技術負債的標準(技術負債是指修復代碼異味所花費的精力)。
對于修復技術負債的問題,SonarSource也有著自己獨到的解決方案。通常來說,主動對整個代碼庫的修復是費時費力的,也可能會產生功能回歸風險。然而程序員總是會在老代碼的基礎上進行新的修改。所以SonarSource的產品只對于新的代碼或者是在老代碼上做過修改的代碼進行掃描分析,也就是在不引入新的問題的同時逐漸對代碼庫進行修復,逐漸改進軟件的質量。實際上就算沒有主動去修復老的代碼,通過SonarSource的解決方案,也會被逐漸地被動修復。據估計,第一年后整體代碼的大約20%的問題將會被修復,兩年后大約35%的代碼問題會被修復,5年后大約50%的代碼問題會被修復。
三款產品中SonarLint和SonarCloud是開源免費的。除了SonarCloud定制的私人服務需要付費之外,公司主要的收入來源來自SonarQube,一共有四個版本,分別是社區版,研發者版,企業版和數據中心版。除了版本之間功能的不同之外,SonarQube的收費模式是根據可分析的最大代碼行數每年收license費用。
社區版是完全免費的,它實際上覆蓋了SonarQube絕大部分功能,包括支持大多數語言,對代碼質量和簡單安全問題檢測的能力,超過50種的插件等等。但問題是社區版不支持一個項目多分支的形式,這會導致一次掃描產生多個項目結果,增加管理的難度。
研發者版本起價是150美金一年,可使用的最大代碼限制行數是10萬行,已經可以滿足一般研發人員日常的檢測需求。此外,增加了C/C++語言的覆蓋,增加了分支分析的能力,增強了安全分析的能力,尤其是針對注入這個問題可以做到深度精確分析。
企業版起價2萬美金一年,可使用的最大代碼限制行數是100萬行。除了支持全部的27種語言之外,還提供了可以配置的SAST引擎功能,提供OWASP/SANS安全報告的能力。還賦能企業產出組合管理的能力。
數據中心版本起價10萬美金一年,可使用的最大代碼限制行數是200萬行。這個版本對高可用性和橫向擴展性有更好的支持。
此外,三個收費版本的產品價格均會隨著最大代碼限制行數的增加而提高。
2006年,Freddy Mallet意識到代碼質量管理至關重要。代碼的缺陷最終會反映到軟件交付的質量上,導致各種各樣的威脅與損失,比如數據泄露,隱私威脅,財產損失,甚至是對人物理上帶來的傷害。Freddy Mallet認為市場上需要一種提供自動化代碼審查的產品。Freddy Mallet與好友Simon Brandhof通過集成Java的最佳開源工具在2007年開始了對Sonar平臺的開發。Olivier Gaudin隨后加入團隊,SonarSource于2008年成立。
2010年,SonarSource實現了公司的第一個里程碑——Sonar平臺被社區和企業接受,每月下載量超過2K次。各種插件的集成讓Sonar備受好評。公司隨后加大研發力度,在2013年正式推出SonarQube。
2016年,SonarSource從Insight Venture Partners籌集了4500萬美元投資,以進一步加速增長。Richard Wells,MD和Insight Partners副總裁Matt Gatto加入公司董事會。此時的SonarQube已經完成了多次迭代,支持了大量的語言和規則,代碼質量分析的能力已經逐漸體現出優勢。
2018年,第一個SaaS平臺SonarCloud基于市場需求和用戶需求推出。在此之前的兩年中,SonarSource也納入了一些與代碼安全性相關的檢測能力,但是一直沒有辦法做到高精度的分析。
直到2020年,SonarSource收購RIPS。RIPS Technologies首席執行官兼聯合創始人Johannes Dahse博士加入SonarSource擔任研發主管。RIPS Technologies是一家致力于創新安全測試技術的公司,以從頭構建了其一流的 PHP 代碼分析引擎而聞名。它的團隊在構建高效的代碼分析解決方案方面有著悠久的歷史,他們的引擎甚至可以檢測復雜和深層嵌套的漏洞。這次收購讓SonarSource語言覆蓋的廣度和RIPS檢測的深度相結合,最終實現了多種語言上對安全漏洞的精準分析檢測。這也標志著SonarSource正式走入了安全性SAST的領域。
2022年,Sonar從新的和現有的投資者那里籌集了4.12億美元,估值為47億美元。該公司將利用這筆投資來擴大銷售團隊,以實現10億美元的收入。
聯合創始人兼CEO Olivier Gaudin來自瑞士日內瓦,于1998年畢業于法國國立應用科學學院(INSA)的應用數學工程專業。因為通過軟件更容易去計算和模擬數學理論的最后結果,所以Olivier選擇了偏計算機的方向,主攻Java語言。曾經在IT行業,金融行業,建筑行業工作過。
在一次代碼審查任務中,Olivier發現自己很難讀懂自己下屬寫的代碼,開始在自己的團隊內部開始設置一些基本的編寫規范。同時,Freddy和Simon也被同樣的問題困擾,他們正在試圖尋找一種自動化的工具來解決這個問題,但是并沒有找到。Freddy和Simon當時已經在IT咨詢公司Hortis共事了幾年,分別擔任CTO和高級Java研發員。Freddy有著二十多年軟件相關工作經驗,包括軟件研發,軟件基礎架構設計,軟件咨詢。Simon也有著十幾年的開發經驗,兩人率先開始研發Sonar平臺。
后來,Olivier遇到了Freddy和Simon,被二人的想法吸引并于2007年加入了他們團隊。有一次,他詢問了Freddy和Simon對“干凈的代碼”的理解,發現三個人產生了分歧。這更加堅定了他們做出一套被行業認可的代碼規范的想法,三人便于2008年創立SonarSource。
Andrea來自于瑞士日內瓦,于2003年畢業于歐洲工商管理學院的金融專業。曾在摩根大通擔任首席技術官和技術負責人 25 年。工作的同時又在2018年攻讀完成了美國斯坦福大學的創新科技項目。Andrea于2021年加入SonarSource,他的加入可以幫助SonarSource建立應對強勁增長所需的基礎設施。
Gordon來自美國馬塞諸塞州,于2000年畢業于本特利大學的金融MBA項目。他曾在軟件安全公司 Carbon Black擔任財務副總裁兼首席財務官,該公司于2019年被VMWare收購。他也曾擔任過領先的應用程序安全初創公司Onapsis的首席財務官,于2021年加入SonarSource。Gordon在這一領域有著十多年的經驗,有著非常廣的人脈與資源。
Gupta于2022年加入SonarSource,之前曾擔任Redis的首席營銷官,最近擔任Oracle的Java和GraalVM全球營銷副總裁,在他任職期間領導了這兩家公司實現了多倍增長。他的經驗將有助于SonarSource實現10億美元的收入目標。
Olivier曾在一次采訪中表示,“我們希望更多研發人員使用我們的產品,要知道全球有大約7000多萬的研發人員。這是我們在此之前從沒有遇到過的挑戰,我認為我們的產品已經準備好了,剩下的工作就是安全意識上的教育和啟發”。
實際上,SonarSource從很早的時候就開始嘗試進行安全意識教育的工作。比如每年12月,會在Twitter上發布24個面向研發人員的安全問題解謎挑戰,并為成功解謎者提供獎勵。這些安全問題都是SonarSource團隊在本年中花費大量時間研究和理解現實世界中的漏洞。公司正在嘗試通過各種形式增加與用戶之間的互動來傳遞安全意識。
SonarSource希望在未來可以提高分析引擎的掃描的速度以及對代碼安全問題深度分析的能力。SonarSource會繼續為開發人員增加價值,優化SonarLint的能力,讓研發人員在IDE側有更好的無摩擦開發體驗。
直接在.gitlab-ci.yml文件中填入如下內容,觸發掃描,即可在漏洞報告中查看結果。
variables:
sonar_host_url: http://1.13.160.207:9000
sonar_login: 333f3410ce3e575d559329e8f3d0a5d4ec8a499d
sonarqube:
artifacts:
reports:
sast:
- gl-sast-report.json
script:
- "/scan.sh"
image:
name: satomic/sonarscanner:v6
以下倉庫參考:
參考dvwa倉庫中的配置方法。
在project級別中,settings - CI/CD - Variables中添加如下2個變量指向SonarQube服務。
在待掃描倉庫中增加.gitlab-ci.yml配置文件,如下,不建議直接把敏感信息如快速入門那樣配置在ci文件中。
sonarqube:
artifacts:
reports:
sast:
- gl-sast-report.json
script:
- "/scan.sh"
image:
name: satomic/sonarscanner:v6
然后進行掃描即可得到掃描結果。
報告總覽
特定issue展現image
文件定位image
根據文章How to get the sonar-report.json file created with sonarqube?、How to get sonar-report.json file to display sonar issues at gerrit level itself中所言,從7.7版本開始,不支持在scanner端導出json格式的報告,因此部署支持的舊版本中的最后一個版本,即7.6版。
參考Docker 安裝SonarQube 步驟以及遇到的坑進行部署,
創建工作目錄
mkdir -p /home/sonar/postgres/postgresql
mkdir -p /home/sonar/postgres/data
創建網絡
docker network create sonarqube-network
部署pg
docker run --name postgres -d -p 5432:5432 --network sonarqube-network \
-v /home/sonar/postgres/postgresql:/var/lib/postgresql \
-v /home/sonar/postgres/data:/var/lib/postgresql/data \
-v /etc/localtime:/etc/localtime:ro \
-e POSTGRES_USER=sonar \
-e POSTGRES_PASSWORD=sonar \
-e POSTGRES_DB=sonar \
-e TZ=Asia/Shanghai \
--restart always \
--privileged=true \
--network-alias postgres \
postgres
創建工作目錄
mkdir -p /data/sonarqube_dir
修改系統參數
echo "vm.max_map_count=262144" > /etc/sysctl.conf
sysctl -p
運行測試容器
docker run -d --name sonartest sonarqube:7.6-community
拷貝必須文件到本地,并修改權限為777
docker cp sonartest:/opt/sonarqube/conf /data/sonarqube_dir
docker cp sonartest:/opt/sonarqube/data /data/sonarqube_dir
docker cp sonartest:/opt/sonarqube/logs /data/sonarqube_dir
docker cp sonartest:/opt/sonarqube/extensions /data/sonarqube_dir
chmod -R 777 /data/sonarqube_dir/
刪除容器
docker stop sonartest
docker rm sonartest
啟動SonarQube,其中SONARQUBE_JDBC_URL的IP地址需要修改為實際PgSql數據庫的IP
docker run -itd --name sonar -p 9000:9000 \
-e ALLOW_EMPTY_PASSWORD=yes \
-e SONARQUBE_DATABASE_USER=sonar \
-e SONARQUBE_DATABASE_NAME=sonar \
-e SONARQUBE_DATABASE_PASSWORD=sonar \
-e SONARQUBE_JDBC_URL="jdbc:postgresql://192.168.1.4:5432/sonar" \
--privileged=true \
--network sonarqube-network \
--restart always \
-v /data/sonarqube_dir/logs:/opt/sonarqube/logs \
-v /data/sonarqube_dir/conf:/opt/sonarqube/conf \
-v /data/sonarqube_dir/data:/opt/sonarqube/data \
-v /data/sonarqube_dir/extensions:/opt/sonarqube/extensions\
sonarqube:7.6-community
登錄SonarQube UI地址( http://IP:9000 ),默認用戶名密碼為admin/admin,在My Account - Security中生成Token。
參考SonarScanner下載最新版的掃描器。
解壓后,進入bin目錄,執行如下命令即可完成掃描,掃描完成后可以去SonarQube中查看掃描結果。
./sonar-scanner \
-Dsonar.host.url=http://1.13.160.207:9000 \
-Dsonar.login=333f3410ce3e575d559329e8f3d0a5d4ec8a499d \
-Dsonar.projectKey=my:test \
-Dsonar.sources=/path_to_codes
如果想要在本地生成json格式報告,則增加如下參數
-Dsonar.report.export.path=report.json \
-Dsonar.analysis.mode=preview
基于以上內容,關鍵是把掃描結果轉化為極狐GitLab旗艦版所識別的json格式。
SonarQube掃描結果issue樣本
{
"key": "AX-Gc4tIjhpt-OIbVVk0",
"component": "my:fuck:fuck/dvwa/includes/DBMS/MySQL.php",
"line": 70,
"startLine": 70,
"endLine": 70,
"message": "Extract this nested ternary operation into an independent statement.",
"severity": "MAJOR",
"rule": "php:S3358",
"status": "OPEN",
"isNew": False,
"creationDate": "2022-03-14T11:22:52+0800"
}
極狐GitLab報告展現issue樣本
{
"category": "test",
"message": "這個問題不怎么嚴重",
"cve": "python-webhook/MicroService/Service.py:960662f9bd521d32692b07bd8d5b10538924c23c37cec891847f40e436c5c2f:B104",
"severity": "Medium",
"confidence": "Medium",
"scanner": {
"id": "test",
"name": "test"
},
"location": {
"file": "python-webhook/MicroService/Service.py",
"start_line": 26,
"end_line": 28
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B104",
"value": "B104",
"url": "https://bandit.readthedocs.io/en/latest/plugins/b104_hardcoded_bind_all_interfaces.htl"
}
]
}
轉碼程序采用python,編寫converter.py文件,內容如下:
# coding=utf-8
# Copyright 2022 Xuefeng Yin, All Rights Reserved
from datetime import datetime
import json
import hashlib
f = open(".scannerwork/report.json", "r")
report = json.loads(f.read())
issues = report.get("issues")
# {u'INFO': 50, u'BLOCKER': 3, u'MAJOR': 5724, u'CRITICAL': 1089, u'MINOR': 1103}
severitys_mapper = {
"INFO": "info",
"BLOCKER":"Unknown",
"MAJOR":"High",
"CRITICAL":"Critical",
"MINOR":"Low",
}
# = issue.get("")
def conv(issue):
component = issue.get("component")
startLine = issue.get("startLine")
endLine = issue.get("endLine")
message = issue.get("message")
severity = issue.get("severity")
rule = issue.get("rule")
# "": ,
ret = {
"category": "sast",
"message": message,
"cve": "",
"severity": severitys_mapper.get(severity, "Unknown"),
"confidence": severitys_mapper.get(severity, "Unknown"),
"scanner": {
"id": "sonarqube",
"name": "sonarqube"
},
"location": {
"file": component.split(":")[-1],
"start_line": startLine,
"end_line": endLine
},
"identifiers": [
{
"type": rule,
"name": rule,
"value": rule,
"url": ""
}
]
}
id = hashlib.sha256(json.dumps(ret, sort_keys=True)).hexdigest()
ret["id"] = id
return ret
dateTimeObj = datetime.now()
timeStr = dateTimeObj.strftime("%Y-%m-%dT%H:%M:%S")
gl_sast_report = {
"version": "3.0.0",
"vulnerabilities": [],
"remediations": [],
"scan": {
"scanner": {
"id": "sonarqube",
"name": "SonarQube",
"url": "https://docs.sonarqube.org/",
"vendor": {
"name": "GitLab"
},
"version": "1.7.0"
},
"type": "sast",
"start_time": timeStr,
"end_time": timeStr,
"status": "success"
}
}
for i, issue in enumerate(issues[:]):
#print("Issue No. %s ---------------------" % i)
#print("SonarQube: %s" % issue)
issue_gitlab = conv(issue)
#print("GitLab: %s" % issue_gitlab)
gl_sast_report["vulnerabilities"].append(issue_gitlab)
gl_sast_report_file = open("gl-sast-report.json", "w")
gl_sast_report_file.write(json.dumps(gl_sast_report, indent=4, sort_keys=True))
gl_sast_report_file.close()
基于環境變量進行掃描
pwd
/sonar-scanner-4.7.0.2747-linux/bin/sonar-scanner -Dsonar.host.url=$sonar_host_url -Dsonar.login=$sonar_login -Dsonar.projectKey=my:test -Dsonar.sources=. -Dsonar.report.export.path=report.json -Dsonar.analysis.mode=preview
ls -l
ls -l .scannerwork
python /sonar-scanner-4.7.0.2747-linux/bin/converter.py
ls -l gl-sast-report.json
from ubuntu:18.04
run apt update -y
run apt install python -y
add sonar-scanner-4.7.0.2747-linux.tar .
workdir ./sonar-scanner-4.7.0.2747-linux/bin
add converter.py .
add scan.sh /
制作好的鏡像已經推送到DockerHub中,采用前文使用方法中所說的內容即可實現掃描。
docker build -t satomic/sonarscanner:v6 .
docker push satomic/sonarscanner:v6
到SonarQube的容器內部
docker exec -it sonar bash
在插件路徑中下載findbugs的jar包
cd /opt/sonarqube/extensions/plugins
wget https://github.com/spotbugs/sonarfindbugs/releases/download/3.10.0/sonar-findbugs-plugin-3.10.0.jar
然后重啟sonar即可
docker restart sonar
然后到sonar的UI上檢查是否安裝成功,出現如下畫面即表示可以。
在sonar UI上進行如下配置,這樣Java的默認規則就是Findbugs了
因為掃描Java項目需要代碼經過編譯,所以需要對掃描器配置maven掃描能力。理論上,通過在Dockerfile中添加安裝maven包即可,但是失敗,因此直接在前述步驟構建出的鏡像中操作完后commit出鏡像。操作步驟如下:
安裝軟件包列表
apt install openjdk-11-jdk-headless -y
apt install maven -y
apt install git
apt install wget
apt install unzip
apt install zip
apt install vim
apt install tree
commit命令
docker commit 100fd2c54f0a satomic/sonarscanner:v7-mvn
此時,考慮到參數暴露的問題,僅僅把如下4個參數內置到掃描器內部,因此修改scan.sh文件如下
pwd
/sonar-scanner-4.7.0.2747-linux/bin/sonar-scanner -X -Dsonar.host.url=$sonar_host_url -Dsonar.login=$sonar_login -Dsonar.report.export.path=report.json -Dsonar.analysis.mode=preview
ls -l
ls -l .scannerwork
python /sonar-scanner-4.7.0.2747-linux/bin/converter.py
ls -l gl-sast-report.json
再更新如上的scan.sh文件,所以Dockerfile更新為
from satomic/sonarscanner:v7-mvn
add scan.sh /
構建出最新鏡像
docker build -t satomic/sonarscanner:v9-mvn .
docker push satomic/sonarscanner:v9-mvn
為了支持Findbug的觸發,需要使用如下配置
# 正常情況下應該配置在settings設置的環境變量中,而不是如此明文暴露
variables:
sonar_host_url: http://1.13.160.207:9000
sonar_login: 333f3410ce3e575d559329e8f3d0a5d4ec8a499d
sonarqube:
artifacts:
reports:
sast:
- gl-sast-report.json
script:
# 通過在此動態生成 sonar-project.properties 配置,而無需侵入源碼倉庫
# 同同時可以提高自由度
- echo -e "sonar.projectKey=JavaProj\nsonar.projectName=JavaProj\nsonar.projectVersion=1.0\nsonar.sourceEncoding=UTF-8\nsonar.language=java\nsonar.sources=.\nsonar.java.binaries=./target/classes\nsonar.language=java\nsonar.ce.javaOpts=-Xmx2560m -Xms853m -XX:+HeapDumpOnOutOfMemoryError" > sonar-project.properties
# 檢查生成的配置是否正常
- cat sonar-project.properties
# 創建構建物目錄
- mkdir -p target/classes
# 此命令是否執行成功依賴mvn配置的合理性,需要實際倉庫的研發介入,配合配置的可用性,默認可訪問官方mvn庫的外網環境問題不大,內網則不太可能編譯成功
- mvn compile
# 查看編譯產物
- tree target/classes
# 執行sonar掃描
- /scan.sh
# 查看報告生成大小
- ls -l .scannerwork/report.json
image:
name: satomic/sonarscanner:v9-mvn
參考
文章轉自:《》https://note.youdao.com/ynoteshare/index.html?id=05b5ba9c1c49628901ebd1eadece97cd&type=note&_time=1703486325797
*請認真填寫需求信息,我們會在24小時內與您取得聯系。