iT邦幫忙

2026 iThome 鐵人賽

DAY 9
1
Security

槍林彈雨下的資安防守:從品質觀念切入,帶開發者從零動手作資安 30 天系列 第 9

【Day 09】【動手做】零成本建置資安檢測站:使用 Docker 5 分鐘架設 SonarQube

  • 分享至 

  • xImage
  •  

💡 今日學習目標:學會使用 Docker 容器化技術,在 5 分鐘內架設完成專屬的 SonarQube 免費社群版資安檢測站,並準備好一份明天要拿來開刀的專案。


📌 前言:升級你的防禦戰場!

昨天我們學會在單機 IDE 中使用 SonarQube for IDE 進行即時防護。但當專案變大、或是需要對整個程式庫做完整分析時,我們需要一個中央儀表板(Dashboard),來追蹤整體專案的安全趨勢與健康度。

今天,我們就要用 Docker,花不到 5 分鐘,在你的本機建置好一台 SonarQube Community Build(就是 Day 07 提過的、原本叫 Community Edition 的免費版)。


🛠️ Step-by-Step:使用 Docker 架設 SonarQube

前置需求準備

  • DockerDocker Desktop 已安裝且正在執行。
  • 記憶體至少留 2 GB 給它。SonarQube 內含一套 Elasticsearch,記憶體不足會直接啟動失敗。
  • 如果你是 Linux 原生 Docker,先檢查兩個核心參數。SonarQube 內含的 Elasticsearch 會在啟動時檢查它們,不夠就直接罷工:
sysctl vm.max_map_count fs.file-max

官方要求是 vm.max_map_count ≧ 524288fs.file-max ≧ 131072

🔑 請注意那個「≧」:這是下限,不是設定值。

很多教學(包括這篇的初版)會叫你直接執行 sudo sysctl -w fs.file-max=131072。但筆者在 Ubuntu 24.04 上實際量到的值是 9,223,372,036,854,775,807,照抄那行指令等於把它調降了。

vm.max_map_count 也有變化:Fedora、Arch、Ubuntu 在 2024 年前後把預設值從 65530 一口氣提高到 1048576(起因其實是 Wine/Proton 跑現代遊戲會撞到上限)。所以在新版發行版上,這兩項你很可能什麼都不用做

真的不夠再改。而且別用 sysctl -w,那是暫時的,重開機就沒了。直接寫成永久設定:

sudo tee /etc/sysctl.d/99-sonarqube.conf <<'EOF'
vm.max_map_count=524288
EOF

sudo sysctl --system

(只有在剛剛檢查發現 fs.file-max 真的小於 131072 時,才在上面多加一行 fs.file-max=131072。)

這是新手卡關率最高的一關。如果你的容器啟動後幾秒就自己停掉,docker logs sonarqube 裡看到 max virtual memory areas vm.max_map_count [65530] is too low,就是這個原因;那個 65530 代表你的系統還是舊的預設值。
(Windows / macOS 的 Docker Desktop 已經預設處理好,可以跳過。)


步驟 1:執行 Docker 啟動指令

開啟你的 Terminal(終端機)或 PowerShell,輸入以下指令:

docker run -d --name sonarqube \
  --restart unless-stopped \
  -p 9000:9000 \
  -v sonarqube_data:/opt/sonarqube/data \
  -v sonarqube_logs:/opt/sonarqube/logs \
  -v sonarqube_extensions:/opt/sonarqube/extensions \
  sonarqube:community

📌 參數分解說明:

  • -d:在背景持續執行(Background Mode)。
  • --name sonarqube:將此容器命名為 sonarqube,之後好操作。
  • --restart unless-stopped開機時自動啟動,除非你自己手動停掉它
  • -p 9000:9000:把本機的 9000 埠映射到容器內的 9000 埠。
  • -v sonarqube_*:...掛載三個資料卷。少了這三行,只要容器被刪掉,你的專案、設定與 Token 就全部消失。這是很多教學會漏掉、但你一定會後悔的一步。
  • sonarqube:community:免費社群版的映像檔。

🔑 --restart unless-stopped 這一行,是筆者自己踩過兩次才補上的。

Day 09 到 Day 11 是一個橫跨三天的練習,中間你一定會關機至少一次。而容器預設不會跟著開機一起起來:隔天你打開 localhost:9000,只會看到「無法連線」。

那個畫面不會告訴你原因,你會開始懷疑是不是昨天哪個步驟做錯了,然後把整篇重做一次。加上這一行就不會發生。

如果你已經照舊指令建好容器了,不用重建,直接對現有的容器改就生效:

docker update --restart unless-stopped sonarqube

⚠️ 不要用網路上常見的 sonarqube:lts-community。那個標籤停留在舊的 LTS 線上,已經將近一年沒有更新了;現在免費版的正確標籤就是 community

(如果你偏好長期支援版本,現在有 2026-lta-community 這個標籤可用;但本系列用 community 就好,它拿到的是最新的 Community Build。)


步驟 2:登入 SonarQube Web 管理介面

  1. 開啟瀏覽器,前往:http://localhost:9000
  2. 第一次啟動時,SonarQube 會進行資料庫初始化(約需等待 1 ~ 2 分鐘)。
  3. 看到登入畫面後,輸入預設的管理者帳號密碼:
    • 帳號 (Username)admin
    • 密碼 (Password)admin

https://ithelp.ithome.com.tw/upload/images/20260828/20007542YWJ9qfRkPi.png

🧐 畫面上寫的是「SonarQube Server」,跟我們說的「Community Build」是同一個東西嗎? 是的。

SonarQube Server 指的是「自架版」這整條產品線,Community Build 則是它底下那個免費的版本。就像「汽車」跟「某個車款」的關係,不是兩個不同的東西。你架起來的這台,正式的說法是「SonarQube Server 的 Community Build」。

🔎 如果瀏覽器連不上,先用 docker logs -f sonarqube 看啟動進度。看到 SonarQube is operational 才算真的起來了;在那之前連線會被拒絕,不是你設定錯了。


步驟 3:變更預設密碼與建立專案權限

登入成功後,系統會自動要求你變更 admin 的預設密碼,而且不改就進不去。

https://ithelp.ithome.com.tw/upload/images/20260828/20007542EQIlia6col.png

🛡️ 資安實踐 alert:將系統預設密碼改為強密碼,本身就是安全組態防範(Security Misconfiguration)的核心原則之一!

🧐 順便看一下畫面上那串密碼規則,它剛好是個很好的教材。

SonarQube 要求「至少 12 個字元、含大寫、小寫、數字、特殊符號」。這是非常典型的密碼政策,你在無數系統上都看過。

NIST 在 2025 年 7 月定稿的 SP 800-63B-4 裡,用 SHALL NOT 明文禁止了「強制字元組合規則」。理由是這種規則會逼使用者採用可預測的替換方式(a@o0),製造出「看起來很複雜、實際上很好猜」的密碼。

這不是說 SonarQube 做錯了。標準更新到工具跟上,中間有很長的時間差,而且改動預設政策會影響所有既有使用者。但它剛好示範了一件事:你在真實系統上看到的做法,不一定就是現在最新的建議。 Day 20 我們會完整處理這個題目。


步驟 4:產生分析 Token (Security Token)

為了讓後續的掃描工具能把結果上傳到這個 SonarQube 伺服器,我們需要發行一組認證 Token:

  1. 點擊右上角個人頭像 ➔ 選擇 My Account ➔ 選擇 Security 頁籤。
  2. Generate Token 區塊中:
    • 輸入 Token 名稱(例如:my-local-scanner)。
    • 類型選擇:Global Analysis Token
  3. 點擊 Generate,並複製產生出來的一長串亂碼 Token。

https://ithelp.ithome.com.tw/upload/images/20260828/200075425T54HCCrRL.png

這個畫面上有三個容易被滑過去、但值得停一下的細節:

  • 「Expires in」預設是 30 days。 這個欄位很容易忽略,但一個月後你的掃描會突然開始失敗,而錯誤訊息不會直接告訴你是 Token 過期。練習環境可以選長一點;正式環境則相反,短效期才安全
  • 「Make sure you copy it now, you won't be able to see it again!」 這句話是真的。關掉頁面之後這串 Token 就再也顯示不出來,只能撤銷重產。
  • 最上面那條黃色警告「Embedded database should be used for evaluation purposes only」,正是等一下「這台伺服器適合用到什麼程度」要講的事。SonarQube 自己就在提醒你,內建的 H2 資料庫只適合練習。

🛡️ 這裡就是一個現成的實戰練習:這串 Token 等同於存取這台伺服器的鑰匙。它不該被貼進 Slack、不該進版本庫、更不該出現在你的鐵人賽截圖裡。
明天我們會把它放進環境變數來使用,這正是 Day 08 那條「硬編碼機密」規則想教你的事。

🔑 而且塗黑只是防守,不是根除。 上面那張圖裡的 Token 雖然已經塗掉,但筆者的實際做法是:截完圖就直接按下那顆 Revoke 讓它作廢,再產一組新的給明天用。

塗黑防的是「有人看到」,撤銷防的是「就算被看到也沒用」。只要成本允許,永遠選後者。


步驟 5:準備一份「明天要被掃描」的專案

檢測站架好了,但它現在是空的。明天要掃什麼? 我們先把待宰的羔羊準備好。

建立一個專案資料夾:

mkdir -p ~/my-first-security-project
cd ~/my-first-security-project

📌 Windows 使用者請自己找一個好記的位置,例如 D:\sonar-lab\my-first-security-project等一下要記住這個絕對路徑,明天掛載目錄時會用到。

在裡面放一支 checksum.js。這段程式碼在計算檔案的完整性校驗碼,是真實專案裡到處都有的東西:

cat > checksum.js <<'EOF'
const crypto = require("node:crypto");

// 計算檔案的完整性校驗碼(checksum)
function generateChecksum(fileBuffer) {
    // ⚠️ MD5 已被證實可以人為製造碰撞
    return crypto.createHash("md5").update(fileBuffer).digest("hex");
}

module.exports = { generateChecksum };
EOF

如果你昨天選的是 Python 路線,就改放 checksum.py

cat > checksum.py <<'EOF'
import hashlib


def generate_checksum(file_bytes: bytes) -> str:
    # ⚠️ MD5 已被證實可以人為製造碰撞
    return hashlib.md5(file_bytes).hexdigest()
EOF

💻 Windows / PowerShell 使用者請注意:上面那幾行是 Linux 與 macOS 的寫法,mkdir -pcat > 檔名 <<'EOF'(here-document)在 PowerShell 都不能用。

最省事的做法是:直接用你 Day 08 裝好外掛的那個編輯器新增檔案、把程式碼貼進去、存檔就好。 反正等一下也要用編輯器來改它。重點只有兩個:資料夾位置你要記得,以及副檔名必須正確

順手把昨天 Day 08 那支 test.js(或 test.py)也複製進這個資料夾,用你修好之後的乾淨版本。這樣明天的掃描結果會很好讀:乾淨的那支一筆問題都沒有,只有 checksum.js 會亮起來,對照非常清楚。

🧨 這一次,請不要修它。

昨天在 IDE 裡,你一看到底線就順手把問題修掉了,那是對的習慣。但今天這支 checksum.js 要故意留著

  • 明天(Day 10),我們要看它在伺服器的儀表板上被算成幾分、歸在哪一類。
  • 後天(Day 11),我們要走完一次完整的審查流程,再親手把它修掉。

換句話說,這是刻意種下的一個問題,用來讓你看清楚整條「掃描 ➔ 判讀 ➔ 修復」的流水線。真實專案裡,這種程式碼是不小心寫下的;在這裡,它是教材。


📋 補充:這台伺服器適合用到什麼程度?

用上面這個指令跑起來的 SonarQube,內建的是一套 H2 嵌入式資料庫。它的定位很明確:

  • 本機學習、個人專案、評估試用:完全夠用,這也是我們接下來三天要做的事。
  • 團隊長期共用的正式環境:官方明確要求改接外部資料庫(PostgreSQL),H2 不保證資料安全與升級相容性。

換句話說,今天架的這台是你的練習場。等哪天要把它變成團隊真正依賴的服務,再花時間接上 PostgreSQL 就好,指令一樣是一段 docker compose


🎯 今日重點小結與防守心法

  • 🔹 心法 1:Docker 讓資安工具零門檻。不用手動裝 Java、不用配資料庫,一段指令就有一台資安檢測伺服器。
  • 🔹 心法 2:務必更改預設憑證admin/admin 是攻擊者掃到管理介面後的第一發子彈,而你剛剛親手把它換掉了,這就是最小成本的資安實踐。
  • 🔹 心法 3:資料卷不能省。少掛那三個 volume,容器一刪你就得從頭再來一次。工具要能長久用,資料就得活在容器之外。

💬 明日預告:【Day 10】【動手做】把程式碼丟進去掃描!解讀 SonarQube 的資安評分與漏洞報告
伺服器架好了!明天我們將親自執行第一次掃描,並教你看懂 A~E 級資安報告!


上一篇
【Day 08】【動手做】在 IDE 裝上第一道防護網:SonarQube for IDE 安裝與即時掃描示範
下一篇
【Day 10】【動手做】把程式碼丟進去掃描!解讀 SonarQube 的資安評分與漏洞報告
系列文
槍林彈雨下的資安防守:從品質觀念切入,帶開發者從零動手作資安 30 天10
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
AndyAWD
iT邦新手 1 級 ‧ 2026-08-28 23:31:28

原來 ≧ 是下限,學到了

我要留言

立即登入留言