SonarQube 是一套程式碼品質掃瞄工具,可以分析你的程式的寫法是否存在 Bug、漏洞或不好的寫法(Code Smell)

這篇簡單記錄我如何在 Linux 主機上安裝 SonarQube Docker,並用它在 Linux 掃瞄 .NET 專案。

安裝步驟我主要參考這篇:於 Ubuntu 透過 Docker 建置 SonarQube Community Edition by Archer,記錄重點如下:

  1. 調整 Linux 作業系統記憶體及檔案參數
    vm.max_map_count 要大於 524288、fs.file-max 大於 131072
  2. docker-compose.yml 如下:
    version: "3"
    
    services:
      sonarqube:
        image: sonarqube:community
        depends_on:
          - db
        environment:
          SONAR_JDBC_URL: jdbc:postgresql://db:5432/sonar
          SONAR_JDBC_USERNAME: sonar
          SONAR_JDBC_PASSWORD: sonar
        volumes:
          - sonarqube_data:/opt/sonarqube/data
          - sonarqube_extensions:/opt/sonarqube/extensions
          - sonarqube_logs:/opt/sonarqube/logs
        ports:
          - "9000:9000"
      db:
        image: postgres:12
        environment:
          POSTGRES_USER: sonar
          POSTGRES_PASSWORD: sonar
        volumes:
          - postgresql:/var/lib/postgresql
          - postgresql_data:/var/lib/postgresql/data
    
    volumes:
      sonarqube_data:
      sonarqube_extensions:
      sonarqube_logs:
      postgresql:
      postgresql_data:
    

之後開啟 http://localhost:9000 用 admin/admin 登入並修改密碼,即可開始使用 SonarQube。

SonarQube 的最佳用法是串接 Azure DevOps、Github... 等版控系統,每次 Commit 後進行掃瞄實現 CI/CD。新建專案介面會提示你設登入版控系統:

但我是掃瞄本地專案,故要下載安裝 SonarScanner CLI。Linux 下載路徑可由官方網站取得,使用 curl 或 wget 下載 ZIP 檔並解壓縮,將檔案移至 opt 目錄,在 .bashrc 設定 $PATH 方便從任意目錄執行:參考 SonarQube 程式碼品質分析工具使用教學 by 張志合

# 下載 zip
wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-5.0.1.3006-linux.zip
# 解壓縮
unzip sonar-scanner-cli-5.0.1.3006-linux.zip
# 將 SonarScanner 資料夾搬到 /opt/ 目錄
sudo mv sonar-scanner-5.0.1.3006-linux /opt/
# 將 SonarScanner 資料夾加入程式搜尋路徑
echo 'export PATH=$PATH:/opt/sonar-scanner-5.0.1.3006-linux/bin' >> ~/.bashrc
# 重載生效
source ~/.bashrc
# 檢查是否可執行 SonarScanner
sonar-scanner -h

執行 SonarScanner CLI 時需指定 SonarQuber 伺服器 URL 及 Access Token,若想簡化可修改 /opt/sonar-scanner-5.0.1.3006-linux/conf/sonar-scanner.properties 加入以下設定:

#----- Default SonarQube server
sonar.host.url=http://localhost:9000

Access Token 有三種,User Token (用於存取 WebAPI,多配合 IntelliJ、VS、VSCode、Eclipse 使用)、Project Analysis Token (範圍只限該專案,較安全) 以及 Global Analysis Token (可分析任何專案,適合批次或服務)。若不想每次掃瞄傳 Access Token 參數,可將其設成環境變數 export SONAR_TOKEN="sqa_85d63b6c71d9325e5bef822e8db32316948726a1"

使用 sonar-scanner 掃瞄 .NET 8 專案,故意用有問題的寫法卻掃不出來,健檢一切正常。摸索一陣子才發現我搞錯了,.NET 專案不能直接用 SonarScanner CLI 掃,需另外透過專用工具 - SonarScanner for .NET 間接呼叫。(線索在 sonar-scanner 輸出訊息,有條 INFO: Sensor C# [csharp] WARN: Your project contains C# files which cannot be analyzed with the scanner you are using. To analyze C# or VB.NET, you must use the SonarScanner for .NET 5.x or higher, see https://redirect.sonarsource.com/doc/install-configure-scanner-msbuild.html,從掃瞄結果完全看不出來,不過是我沒耐性把文件看過一遍,算我的責任失分)

SonarScanner for .NET 要分別安裝 .NET Core Global Tool 及 SonarScanner 程式。.NET Core Global Tool 使用 dotnet 指令安裝 dotnet tool install --global dotnet-sonarscanner --version 6.1.0,SonarScanner 程式則需由網站下載,

sudo unzip sonar-scanner-6.1.0.83647-net.zip -d /opt/sonar-scanner-6.1.0.83647-net
sudo chmod +x /opt/sonar-scanner-6.1.0.83647-net/sonar-scanner-5.0.1.3006/bin/*
echo 'export PATH=$PATH:/opt/sonar-scanner-6.1.0.83647-net' >> ~/.bashrc
source ~/.bashrc
# 需要 Java Runtime,default-jre 不行,要裝 55+ 版本
sudo apt install -y openjdk-18-jre-headless

.NET 版的 SonarQube 網址及 Access Token 設定位置在 /opt/sonar-scanner-6.1.0.83647-net/SonarQube.Analysis.xml,這樣可不用每次都帶 Access Token 參數。

<SonarQubeAnalysisProperties  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.sonarsource.com/msbuild/integration/2015/1">
  <Property Name="sonar.host.url">http://localhost:9000</Property>
  <Property Name="sonar.token">sqa_85...a1</Property>
</SonarQubeAnalysisProperties>

.NET 掃瞄程序較麻煩,要先 dotnet sonarscanner begin、dotnet build,再 dotnet sonarscanner end,官方範例如下:

dotnet sonarscanner begin /k:"project-key" /d:sonar.token="<token>"
dotnet build <path to project file or .sln file> --no-incremental
dotnet sonarscanner end /d:sonar.token="<token>"

我有在 SonarQube.Analysis.xml 設定 sonar.token,理論上會自動抓設定檔,但實測不 OK 得指定設定檔路徑 /s:<path-to-onarQube.Analysis.xml> 才會生效。 參考

我的解法是用 ln -s /opt/sonar-scanner-6.1.0.83647-net/SonarQube.Analysis.xml /home/jeffrey/sqconf.xml 將檔案連結到 ~/sqconf.xml,然後將以下指令存成 sca.sh:

#!/bin/bash
dotnet sonarscanner begin /k:my:vulerable-sample /s:"$HOME/sqconf.xml"
dotnet build --no-incremental
dotnet sonarscanner end

這樣就能成功掃瞄囉~

掃瞄結果有抓到 SQL Injection 問題點:

歷經波折,再學會一件新工具。

Tutorial of installing Sonar docker and using it to scan .NET 6+ projects.


Comments

# by 布丁布丁吃布丁

實用,下次我也來試試。

# by Plusone

順便補充一下,如果使用Mac Silicon系列晶片的工作機開發的人,記得Terminal中要先執行 arch -x86_64 zsh讓CLI工具跟notnet以x64模式執行,不然怎麼掃都會跟你說失敗... by 曾經浪費了半天的過來人...

Post a comment