在軟體開發生命週期中,從程式碼撰寫到最終交付,佈署和測試環節至關重要。傳統的手動佈署流程繁瑣且容易出錯,測試也常因成本考量而延後,導致後期修復錯誤更加困難。自動化佈署和持續整合/持續交付(CI/CD)的出現,有效解決了這些問題。透過自動化流程,開發團隊能更頻繁地進行測試,及早發現錯誤並降低修復成本,同時也能更快速地將軟體交付給使用者。安全測試在現代軟體開發中也扮演著關鍵角色,從程式碼的靜態分析到動態測試,以及依賴函式庫的安全性掃描,都是確保軟體安全不可或缺的步驟。GitLab CI/CD 提供了一個整合的平台,將程式碼版本控制、自動化建置、測試和佈署流程串連起來,簡化了開發流程,並提升了軟體交付的效率和安全性。

傳統開發流程中的挑戰

在傳統開發流程中,程式碼驗證和測試是一個複雜且耗時的過程。即使完成了各種不同型別的測試,開發者還需要處理如何解釋和報告結果。如果幸運的話,測試工具可以生成標準格式的報告並整合到儀錶板中;但通常至少有一個工具需要手動解釋和整理。

測試結果處理

不同型別的測試需要反覆執行以捕捉迴歸錯誤或解決「閃爍」測試問題(即某些測試在特定條件下會成功或失敗)。因此,手動管理或觸發自動化測試成為一個巨大負擔。

具體挑戰

  1. 資源管理:確保適當的硬體和環境可供測試使用。
  2. 靈活調整:根據需求變化調整測試頻率。
  3. 報告整合:將多種測試工具的結果整合到統一報告中。

延遲測試帶來的問題

由於執行測試昂貴且困難,開發團隊通常傾向於盡量減少測試頻率。這種傾嚮往往導致測試被推遲到開發週期結束時才進行(如兩週衝刺結束或年終專案完成)。這種延遲測試會導致大批次程式碼交付給 QA 團隊進行驗證,從而增加了診斷和修復錯誤的難度。

具體影響

  1. 程式碼品質問題:大批次程式碼難以追蹤和除錯
  2. 時間延誤:開發週期延長
  3. 團隊協作困難:開發團隊與 QA 團隊之間缺乏緊密聯絡

理解開發營運整合(DevOps)前的軟體開發

在探討開發營運整合(DevOps)之前,我們需要深入瞭解軟體開發在這個時代之前的困境。這些困境包括測試的重要性、設定測試環境的耗時、手動執行無法自動化的使用者測試的麻煩、處理和報告測試結果的挑戰,以及在大量程式碼中找到和修復漏洞的困難。

功能測試與其挑戰

功能測試是確保軟體按預期工作的關鍵步驟。然而,在 DevOps 時代之前,這個過程非常繁瑣。開發者需要手動執行各種測試,並且經常面臨以下問題:

  • 測試環境設定:設定不同環境以進行測試是一項耗時且容易出錯的工作。
  • 手動執行測試:無法自動化的使用者測試需要手動執行,這不僅耗時且容易出現人為錯誤。
  • 處理和報告結果:處理和報告測試結果也是一項挑戰,特別是在大規模專案中。
  • 找到和修復漏洞:在大量程式碼中找到和修復漏洞是一項極其艱難的任務。

安全測試:保護軟體免受威脅

除了功能測試,安全測試也是軟體開發中的重要環節。由於其重要性和複雜性,安全測試通常由專門的團隊來執行。這些團隊會使用多種方法來進行安全測試,主要分為三大類別:

  1. 檢查原始碼:透過檢查原始碼來找出潛在的安全問題。
  2. 與執行中的程式互動:透過模擬使用者行為來找出可能的安全漏洞。
  3. 檢查第三方依賴:檢查專案所依賴的第三方函式庫是否存在已知漏洞。

靜態程式碼分析:找出潛在風險

靜態程式碼分析是一種透過檢查原始碼來找出潛在安全問題的方法。例如,如果程式碼接受使用者輸入並將其用於資料函式庫查詢,則可能會遭受 SQL 注入攻擊。以下是一個簡單的範例:

employee_name = get_user_input()
sql = "SELECT salary FROM employee_records WHERE employee_name = $employee_name"
call_database(sql)

內容解密:

這段程式碼接受使用者輸入並將其直接用於 SQL 查詢,沒有進行任何驗證。這樣做會導致 SQL 注入攻擊,攻擊者可以透過輸入惡意值來取得更多資訊。

def sum(i, j, k, l, m, n, o, p, q, r):
    return i + j

內容解密:

這個 Python 函式接受大量引數但只使用其中兩個,這種寫法不僅讓程式難以閱讀和維護,還可能導致未來出現安全問題。

機密檢測:保護敏感資料

機密檢測是靜態程式碼分析的一種特殊形式,專門用於檢查原始碼中是否存在應該被移除並儲存在更安全位置的機密資料。例如:

String bethSSN = "555-12-1212";
if (customerSSN.equals(bethSSN))) {
    System.out.println("Welcome, Beth!");
}

內容解密:

這段 Java 程式碼包含了一個社會安全號碼(SSN),任何擁有程式碼讀取許可權的人都可以看到它。這樣的機密資料應該被移除並儲存在更安全的位置。

動態分析:與執行中的程式互動

動態分析是透過與執行中的程式互動來找出潛在問題。例如,你可以模擬使用者行為來找出潛在的安全漏洞。以下是一個簡單的範例:

puts 'how many hats do you have?'
num_hats = gets.to_i
puts 'how many cats do you have?'
num_cats = gets.to_i
puts "you have #{num_hats / num_cats} hats per cat"

內容解密:

這段 Ruby 程式碼可能會導致除零錯誤(ZeroDivisionError),如果未處理好可能會導致程式當機。這樣的錯誤可能會被惡意攻擊者利用來實施攻擊。

依賴掃描:確保依賴函式庫的安全性

依賴掃描是比對專案所依賴的第三方函式庫與已知漏洞資料函式庫,以確保依賴函式庫是最新版本且沒有已知漏洞。幾乎每個非平凡的軟體都依賴於數十甚至數百個第三方函式庫。

此圖示展示了依賴掃描的基本流程:

  graph TD;
    A[依賴掃描] --> B[取得專案依賴];
    B --> C[比對已知漏洞];
    C --> D[更新或移除有漏洞依賴];
    D --> E[確保系統安全];

內容解密:

此圖示展示了依賴掃描的基本流程,從取得專案依賴到比對已知漏洞再到更新或移除有漏洞依賴,最終確保系統安全。

DevOps 的到來

瞭解了這些困境之後,我們可以更好地欣賞 GitLab CI/CD Pipeline 如何簡化測試流程並提高效率。早期和頻繁執行測試不僅能更快地發現問題,還能降低修復成本。總之,DevOps 的到來讓軟體開發變得更加高效和安全。

安全性測試的手動方法

在軟體開發過程中,安全性測試是不可或缺的一環。以下是一些常見的安全性測試方法及其重要性。

依賴掃描(Dependency Scanning)

依賴掃描是檢查你的專案是否使用了已知有漏洞的第三方或開源函式庫。例如,Log4j 是一個廣泛使用的 Java 日誌記錄函式庫,近期發現了一個嚴重的漏洞,允許駭客遠端執行命令或安裝惡意軟體。依賴掃描可以及時發現這類別問題,並建議升級到最新版本。

此圖示

  graph TD;
    A[專案] --> B[依賴掃描];
    B --> C[檢查已知漏洞];
    C --> D[更新到最新版本];
內容解密:

上述圖表展示了依賴掃描的基本流程。首先,專案中的依賴會進行掃描,接著檢查是否存在已知的漏洞,最後會建議升級到最新版本以消除潛在的安全風險。

條件掃描(Container Scanning)

很多軟體產品現在都是以 Docker 映像的形式交付。條件掃描會檢查 Docker 映像中的基礎 Linux 系統是否存在已知的安全漏洞。例如,CentOS 6 已經停止維護,其中包含的函式庫有許多嚴重的安全漏洞。條件掃描會建議你升級到 CentOS 7 或更高版本作為基礎映像。

此圖示

  graph TD;
    A[Docker 映像] --> B[條件掃描];
    B --> C[檢查基礎系統];
    C --> D[更新到最新版本];
內容解密:

上述圖表展示了條件掃描的基本流程。首先,Docker 映像中的基礎系統會進行掃描,接著檢查是否存在已知的安全漏洞,最後會建議升級到最新版本以提升安全性。

其他手動測試

除了依賴和條件掃描外,還有許多其他測試需要手動進行,例如程式碼審查、靜態分析和動態分析等。這些測試能夠檢測程式碼中可能存在的安全問題或不良編碼習慣。雖然這些步驟看似繁瑣,但在當今資訊安全威脅日益嚴重的環境下,這些測試是必不可少的。

GitLab 前的困境

在 GitLab 出現之前,開發團隊面臨許多困難。手動進行各種安全測試不僅耗時耗力,還需要安裝和組態多種工具,維護多個測試環境和報告系統。這些工作不僅增加了開發成本,還容易出現錯誤和疏忽。

手動封裝與佈署

在完成軟體構建和安全測試後,下一步是封裝和佈署。封裝過程取決於程式語言和構建管理工具。例如,使用 Maven 構建 Java 應用程式和使用 Gradle 構建 Java 應用程式需要不同的命令;而封裝 Ruby 程式碼成 Ruby gem 需要另一套完全不同的流程。

封裝過程通常涉及收集大量檔案、檢查檔案完整性、加入必要的檔案和可能進行數位簽名以證明來自可信來源。

授權合規性掃描(License Compliance Scanning)

在佈署之前,還需要進行授權合規性掃描。這包括檢查你所使用的所有開源函式庫和工具是否符合相關授權要求。這不僅是法律問題,還涉及公司聲譽和未來合作。

GitLab 的解決方案

GitLab 提供了一個全面的 CI/CD 預設管道(pipeline),能夠自動化大部分手動測試和佈署流程。這不僅提高了效率,還減少了人為錯誤。

未來趨勢

隨著技術不斷進步,未來可能會有更多自動化工具來簡化安全測試和佈署流程。例如,機器學習技術可以用來自動檢測程式碼中的潛在漏洞。然而,無論技術如何進步,專業開發者仍然需要深入瞭解這些流程並保持警覺。

參考資料
  1. Open Web Application Security Project (OWASP)
  2. GitLab Documentation on CI/CD Pipelines
  3. Docker Security Best Practices

軟體開發生命週期中的手動佈署與許可證掃描

許可證合規掃描

大多數開源和第三方函式庫都是在特定的軟體許可證下發行的。雖然有無數的許可證可以選擇,但絕大多數開源函式庫使用的僅是幾種主要的許可證,包括 MIT 許可證、GNU 通用公共許可證(GPL)和 Apache 許可證。瞭解這些依賴函式庫所使用的許可證至關重要,因為根據法律,您無法使用與專案整體許可證不相容的依賴函式庫。

那麼,哪些情況會導致兩個許可證不相容呢?一些許可證,如和平開源許可證(Peaceful Open Source License),明確禁止軍事使用該軟體。更常見的許可證衝突則發生在所謂的 Copyleft 許可證與專有許可證之間。例如,GPL 這類別 Copyleft 許可證規定,任何使用由 GPL 覆寫的函式庫的軟體必須自己也使用 GPL 許可證。這些 Copyleft 許可證有時被稱為病毒式許可證,因為它們將其許可限制傳播到任何使用受該型別許可證覆寫的依賴函式庫的軟體。

由於法律要求您確保主許可證與任何第三方函式庫的許可證相容,您需要在封裝和佈署工作流程中新增一個許可證掃描步驟。無論是手動進行還是使用自動化工具,您都必須識別並替換任何不允許使用的依賴函式庫。

軟體佈署

當軟體已經封裝完畢且您已經檢查過依賴函式庫的許可證後,下一步就是將程式碼佈署到正確的位置和時間。

大多數開發團隊會將程式碼佈署到多個環境中。雖然每個組織設定這些環境的方式不同,但典型(儘管最小化)的環境結構可能如下:

  • 一個或多個測試環境。
  • 一個預生產或模擬環境,該環境組態與生產環境盡可能相似,但通常規模較小。
  • 一個生產環境。

我們將在稍後詳細討論這些不同環境的使用情況,但現在您只需要瞭解每個環境如何作為基本佈署工作流程的一部分。當程式碼正在開發時,通常會佈署到測試環境中,以便 QA 隊伍或釋出工程師確保它能正常執行並且與現有程式碼整合而不引起任何問題。當新程式碼被宣佈準備好新增到生產程式碼函式庫時,它通常會佈署到模擬環境中,以便進行最後一輪測試,確保新程式碼與其最終執行的環境之間沒有不相容性。如果這些測試進展順利,程式碼最終會佈署到生產環境中,讓真實使用者能夠從新程式碼引入的功能、錯誤修復或其他改進中受益。

掌握 DevOps 前的人生

正如您所想像的那樣,確保將正確的程式碼佈署到正確的環境並在正確的時間是一項棘手但至關重要的工作。而佈署只是戰鬥的一半!另一半是確保各種環境都可用且健康。它們必須執行在正確型別和規模的硬體上,必須配備正確的使用者帳戶,必須正確組態網路和安全策略,並且必須安裝正確版本的作業系統、工具和其他基礎設施軟體。當然,還有一些維護任務、升級和其他系統重新組態工作需要計劃、執行以及修復失敗時。這些任務複雜而令人頭痛,因此大型組織通常有一整支釋出工程師團隊來確保一切順利進行並且在出現問題時迅速排查。

這樣我們就完成了對最常見 SDLC 工作流程的一瞥:

  1. 編譯程式碼。
  2. 使用各種測試驗證程式碼的功能、效能、資源使用等。
  3. 使用更多測試來確保程式碼沒有安全漏洞。
  4. 將程式碼封裝成可以佈署的格式。
  5. 查詢並修復任何與不相容許可證相關的問題。
  6. 將程式碼佈署到適當的環境。

現在您應該感受到一種主題:GitLab 出現之前的人生是複雜、錯誤百出且緩慢。這些形容詞肯定適用於軟體開發生命週期後期發生的一些封裝、掃描和釋出任務。但正如我們在後續章節中會詳細學習到的是,GitLab CI/CD Pipeline可以為您處理這些任務中的最繁重部分。透過讓Pipeline處理那些乏味且重複性高的工作,您可以專注於撰寫軟體中的更創意和滿足感強烈部分。

傳統手動軟體開發生命週期實踐中的問題

現在您對於從開發人員完成編寫軟體到使用者能夠接觸到它之間所發生的一系列事情有一個總體概念了,您就可以開始理解這個過程有多麼艱難了。在向使用者交付安全且正常執行的程式碼過程中需要完成很多工:

  • 編寫程式碼
  • 編輯檔案
  • 模組化設計
  • 測試功能
  • 測試效能
  • 測試資源使用
  • 測試安全漏洞
  • 把檔案封裝成適合傳遞給客戶端格式
  • 檢查相容性
  • 解決所有沒有相容性問題

以下是玄貓對於「手動封裝及佈署」內容之詳細補充與說明: