ModSecurity 作為網頁應用程式防火牆(WAF),在防禦 SQL 注入、跨站指令碼(XSS)等攻擊方面扮演著重要角色。本文將引導讀者瞭解如何在 NGINX 環境下安裝和組態 ModSecurity 3.0,並提供一個簡單的規則設定範例,演示如何阻止特定請求。ModSecurity 3.0 的新架構採用動態模組設計,提升了效能和靈活性。對於 NGINX Open Source 使用者,需要自行編譯 ModSecurity 模組,而 NGINX Plus 則提供預編譯模組,簡化了安裝流程。文章也提到了 ModSecurity 3.0 的一些限制,例如不支援檢查回應主體和 DDoS 緩解規則等,並提供了相應的解決方案或替代方案。

ModSecurity 3.0 與 NGINX:快速入門

第一章:簡介

“ModSecurity 不是一個高飛的、雲端啟用、機器學習的奇才。把它想成是一塊機械錶會更好。” - Dr. Christian Folini,OWASP Core Rule Set 專案共同長官者

ModSecurity 的簡史

ModSecurity 最初由 Ivan Ristić 建立,用於幫助保護他負責的幾個網頁應用程式。他設想建立一個軟體解決方案,位於這些應用程式的前端,分析流入和流出的資料。這樣的解決方案既可以提供可見性,又可以阻止潛在的攻擊。

Ristić 隨後開始將這個解決方案作為一個愛好者的側面專案,結果產生了一個 Apache HTTP Server 的外掛。到 2002 年 11 月,他發布了第一個開源版本,將他的作品命名為 ModSecurity。ModSecurity 很快獲得了流行,因為它作為保護網頁應用程式的工具提供了即刻的價值。

從那時起,事件接踵而至:

  • 2004 年:ModSecurity 商業化為 Thinking Stone;Ristić 辭去日常工作,全職專注於 ModSecurity
  • 2006 年:Thinking Stone 被 Breach Security 收購
  • 2006 年:發布 ModSecurity 2.0
  • 2009 年:Ristić 離開 Breach Security 和 ModSecurity 專案
  • 2010 年:Breach Security 被 Trustwave 收購;隨後發布了更多版本
  • 2017 年:發布支援 NGINX 和 NGINX Plus 的 ModSecurity 3.0

如今,Trustwave 繼續是 ModSecurity 的企業贊助商,為開源專案的發展提供資金,同時也提供商業規則集。

ModSecurity 的工作原理

作為一個 WAF,ModSecurity 專門用於關注 HTTP 流量。當發出 HTTP 請求時,ModSecurity 檢查請求的所有部分是否有任何惡意內容或異常。如果請求被認為是惡意的,則可以根據組態被阻止、記錄或兩者兼而有之。

ModSecurity 使用一個“規則”資料函式庫來定義惡意行為。ModSecurity 3.0 支援 OWASP ModSecurity Core Rule Set(CRS),這是 ModSecurity 最廣泛使用的開源規則集,以及 Trustwave 商業規則集(使用者需要付費)。OWASP CRS 由社群維護,透過廣泛的曝光調整,具有非常少的誤報。

ModSecurity 3.0 的新架構

ModSecurity 3.0 是 NGINX 和 NGINX Plus 的動態模組。與之前的版本相比,它具有多項改進,包括更好的效能、新的規則語言和改進的可擴充套件性。

重點解說:
  1. 動態模組:ModSecurity 3.0 被設計為 NGINX 和 NGINX Plus 的動態模組,這意味著它可以在不需要重新編譯 NGINX 的情況下被載入和解除安裝。
  2. 效能改進:新的架構帶來了效能上的改進,使其更適合在生產環境中使用。
  3. 新的規則語言:規則語言得到了改進,使其更具表現力和靈活性。
  4. 改進的可擴充套件性:新的架構允許更輕鬆地擴充套件和自定義 ModSecurity 的功能。

結語

本章介紹了 ModSecurity 的歷史、工作原理以及 ModSecurity 3.0 的新架構。下一章將介紹如何安裝 ModSecurity。

ModSecurity 3.0 與 NGINX:快速入門 - 簡介

SQL 注入(SQLi)是最常見的網路攻擊手段之一,根據 Akamai State of the Internet – Security 的報告,這類別攻擊佔已知網路應用程式攻擊的 51% 以上。這類別攻擊利用了使用者輸入欄位(如表單)未經適當驗證的漏洞。舉個簡單的例子,考慮一個攻擊者在登入表單中輸入以下內容(為清晰起見,密碼欄位未被遮蔽):

使用者名稱:someone_else
密碼:1' or '1'='1
登入

一個簡單的 SQL 注入攻擊範例

如果一個網路應用程式直接使用表單輸入的資訊來形成一個 SQL 查詢,以從資料函式庫中檢索使用者資訊,而未首先驗證密碼,則會生成如下的 SQL 陳述式:

SELECT * FROM Users WHERE Username='someone_else' AND Password='1' OR '1' = '1';

由於陳述式 '1' = '1' 永遠為真,這個查詢繞過了密碼檢查,允許攻擊者以 someone_else(或任何其他帳戶)登入。如果一個請求比對任何 SQL 注入規則,ModSecurity 可以根據組態丟棄該封包、記錄它,或兩者兼而有之。

在 CRS(Core Rule Set)中,有類別似的規則來檢測和阻止其他常見攻擊,如跨站指令碼(XSS)和本地檔案包含(LFI)。

ModSecurity 3.0 的新架構

之前的 ModSecurity 版本(直到 2.9 版)技術上可以與 NGINX 協同工作,但效能不佳。這是因為 ModSecurity 被包裹在完整的 Apache HTTP Server 中,提供了一個相容層。ModSecurity 與 Apache 緊密結合。

ModSecurity 3.0 則是對 ModSecurity 的完全重寫,可以原生地與 NGINX 協同工作,無需 Apache。

ModSecurity 3.0 架構與 NGINX 和 NGINX Plus

此新架構將核心功能移到一個名為 libmodsecurity 的獨立引擎中。libmodsecurity 元件透過一個名為 NGINX 聯結器的最佳化聯結器與 NGINX 介面。還有一個單獨的聯結器適用於 Apache。

NGINX 的 ModSecurity 動態模組將 libmodsecurity 和 NGINX 聯結器合併在一個套件中。NGINX Plus 發行版包含編譯好的動態模組。NGINX Open Source 使用者每次更改 NGINX 版本時都需要編譯 ModSecurity 原始碼。

新模組比舊版模組更快、更穩定,並且得到了 NGINX, Inc. 和 Trustwave 團隊的積極支援。

已知的限制

ModSecurity 3.0 尚未達到與先前版本 ModSecurity 2.9 的功能對等。請注意以下限制:

  • 不支援檢查回應主體的規則,如果包含在組態中則會被忽略。可以使用 NGINX 的 sub_filter 指令來檢查和重寫回應資料。在 OWASP Core Rule Set 中,這些是 95x 規則。
  • 不支援 OWASP Core Rule Set 中的 DDoS 緩解規則(REQUEST-912-DOS-PROTECTION.conf)。有關使用 NGINX 啟用 DDoS 緩解的替代方法,請參閱第 7 章第「使用 NGINX 進行 DDoS 緩解和速率限制」節。
  • 不支援在稽核日誌中包含請求和回應主體。
  • 部分指令未實作;如果嘗試使用,可能會出現錯誤。ModSecurity 參考手冊列出了 ModSecurity 中所有可用的指令,以及它們是否在 libModSecurity 中得到支援。

目前尚未確定 ModSecurity 3.0 何時能夠達到與 ModSecurity 2.9 的功能對等,但它正在積極開發中,每個新版本都在縮小差距。

安裝 ModSecurity

“網路應用程式——你的、我的、大家的——平均而言非常不安全。我們努力跟上安全問題,需要任何幫助來保護它們。”——Ivan Ristić,ModSecurity 建立者

本章涵蓋瞭如何為 NGINX Open Source 和 NGINX Plus 安裝 ModSecurity 3.0。NGINX Open Source 使用者需要從原始碼編譯 ModSecurity。NGINX Plus 使用者則使用由 NGINX, Inc. 提供的預編譯的 ModSecurity 3.0 動態模組。

使用 ModSecurity 3.0 與 NGINX Plus 的好處

ModSecurity 3.0 for NGINX Plus 被稱為 NGINX WAF。商業訂閱有多項好處:

  • 您無需自行編譯 ModSecurity 動態模組;NGINX, Inc. 為您提供預編譯的模組,節省時間和精力。
  • NGINX, Inc. 對動態模組進行了全面測試,因此您知道它適合生產環境使用。
  • NGINX, Inc. 不斷追蹤變更,並為每個重要變更和安全漏洞更新模組,因此您無需自行處理這些事務。
  • NGINX Plus 的每個新版本都包含新版本的動態模組,因此您可以在升級時無需重新編譯 ModSecurity。
  • 您將獲得全年無休的支援,包括 ModSecurity 和 OWASP Core Rule Set 的安裝,以及故障排除和除錯協助。

程式碼範例與解析

SELECT * FROM Users WHERE Username='someone_else' AND Password='1' OR '1' = '1';

內容解密:

  1. SELECT * FROM Users:這條 SQL 陳述式用於從 Users 表格中選取所有欄位。
  2. WHERE Username='someone_else':這部分條件篩選出使用者名稱為 someone_else 的記錄。
  3. AND Password='1':這裡檢查密碼是否為 1
  4. OR '1' = '1':由於 '1' = '1' 永遠為真,這使得整個條件永遠為真,從而繞過密碼檢查。
  5. 這種 SQL 注入攻擊利用了應用程式未正確驗證使用者輸入的漏洞,允許攻擊者以任意使用者身份登入。
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title NGINX ModSecurity 快速入門

package "安全架構" {
    package "網路安全" {
        component [防火牆] as firewall
        component [WAF] as waf
        component [DDoS 防護] as ddos
    }

    package "身份認證" {
        component [OAuth 2.0] as oauth
        component [JWT Token] as jwt
        component [MFA] as mfa
    }

    package "資料安全" {
        component [加密傳輸 TLS] as tls
        component [資料加密] as encrypt
        component [金鑰管理] as kms
    }

    package "監控審計" {
        component [日誌收集] as log
        component [威脅偵測] as threat
        component [合規審計] as audit
    }
}

firewall --> waf : 過濾流量
waf --> oauth : 驗證身份
oauth --> jwt : 簽發憑證
jwt --> tls : 加密傳輸
tls --> encrypt : 資料保護
log --> threat : 異常分析
threat --> audit : 報告生成

@enduml

此圖示展示了 ModSecurity 如何檢測和處理 SQL 注入攻擊。使用者輸入首先被傳遞給 SQL 查詢,如果查詢比對到已知的 SQL 注入規則,則會被丟棄或記錄,從而防止潛在的攻擊。

詳細解說:

  • 圖表展示了從使用者輸入到 SQL 查詢生成的流程,以及 ModSecurity 如何介入檢查潛在的 SQL 注入攻擊。
  • 如果 SQL 查詢比對到已知的攻擊規則,ModSecurity 可以根據組態丟棄該請求或進行記錄。
  • 這種機制有效地保護了網路應用程式免受 SQL 注入攻擊,提高了安全性。

ModSecurity 3.0 與 NGINX:快速入門 第二章 - 安裝 ModSecurity

NGINX 開源版本安裝

安裝概述

在 NGINX 1.11.5 及更高版本中,您可以編譯個別的動態模組而無需編譯完整的 NGINX 二進位檔案。在逐步介紹編譯過程後,我們將說明如何將 ModSecurity 動態模組載入 NGINX 並執行基本測試以確保其正常運作。

  1. 從官方倉函式庫安裝 NGINX 首先,如果尚未安裝 NGINX,請從我們的官方倉函式庫安裝 NGINX 的主線分支。有多種方式可以安裝 NGINX,就像大多數開源軟體一樣。我們通常建議從官方倉函式庫安裝 NGINX 的主線分支。安裝請參閱:nginx.org/en/linux_packages.html#mainline。 本章的假設您已經從官方倉函式庫安裝了 NGINX。它們可能也適用於從其他來源獲得的 NGINX,但尚未經過測試。 注意:需要 NGINX 1.11.5 或更高版本。

  2. 安裝先決套件 第一步是安裝完成本教程其餘步驟所需的套件。執行以下命令,這適用於新安裝的 Ubuntu/Debian 系統。對於 Red Hat Enterprise/CentOS/Oracle Linux,所需的套件可能會有所不同:

    $ apt-get install -y apt-utils autoconf automake build-essential git libcurl4-openssl-dev libgeoip-dev liblmdb-dev libpcre++-dev libtool libxml2-dev libyajl-dev pkgconf wget zlib1g-dev
    
  3. 下載並編譯 libmodsecurity 安裝所需的先決套件後,下一步是將 ModSecurity 編譯為 NGINX 動態模組。在 ModSecurity 3.0 的新模組化架構中,libmodsecurity 是核心元件,包含所有規則和功能。架構中的第二個主要元件是聯結器,它將 libmodsecurity 連線到正在執行的網頁伺服器。有為 NGINX 和 Apache HTTP Server 分別提供的聯結器。我們將在下一節中介紹 NGINX 聯結器。 要編譯 libmodsecurity:

    • 複製 GitHub 倉函式庫:
      $ git clone --depth 1 -b v3/master --single-branch https://github.com/SpiderLabs/ModSecurity
      
    • 切換到 ModSecurity 目錄並編譯原始碼:
      $ cd ModSecurity
      $ git submodule init
      $ git submodule update
      $ ./build.sh
      $ ./configure
      $ make
      $ make install
      

    編譯過程大約需要 15 分鐘,具體取決於系統的處理能力。 注意:在構建過程中忽略類別似以下的訊息是安全的。即使出現這些訊息,編譯也會完成並建立一個可用的物件:

    fatal: No names found, cannot describe anything.
    
  4. 下載 NGINX 聯結器並將其編譯為動態模組 將 ModSecurity 聯結器為 NGINX 編譯為動態模組:

    • 複製 GitHub 倉函式庫:
      $ git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git
      
    • 確定在哪個主機上載入 ModSecurity 模組的 NGINX 版本:
      $ nginx -v
      nginx version: nginx/1.13.7
      
    • 下載與已安裝的 NGINX 版本相對應的原始碼(即使只編譯動態模組,也需要完整的原始碼):
      $ wget http://nginx.org/download/nginx-1.13.7.tar.gz
      $ tar zxvf nginx-1.13.7.tar.gz
      
    • 編譯動態模組並將其複製到模組的標準目錄:
      $ cd nginx-1.13.7
      $ ./configure --with-compat --add-dynamic-module=../ModSecurity-nginx
      $ make modules
      $ cp objs/ngx_http_modsecurity_module.so /etc/nginx/modules
      
  5. 載入 NGINX ModSecurity 聯結器動態模組/etc/nginx/nginx.conf 的主要(頂層)上下文中新增以下 load_module 指令。它指示 NGINX 在處理設定時載入 ModSecurity 動態模組:

    load_module modules/ngx_http_modsecurity_module.so;
    

NGINX Plus 安裝

本文說明如何安裝 NGINX 網頁應用程式防火牆(WAF)。NGINX WAF 根據 ModSecurity 3.0 構建。 NGINX WAF 可供 NGINX Plus 客戶作為額外付費下載的動態模組。要購買或開始免費試用 NGINX WAF,或將 NGINX WAF 新增到現有的 NGINX Plus 訂閱中,請聯絡 NGINX 銷售團隊,郵件地址為 nginx-inquires@nginx.com

先決條件

安裝 NGINX Plus R12 或更高版本,請按照以下進行:nginx.com/resources/admin-guide/installing-nginx-plus/

安裝 NGINX WAF

要安裝 NGINX WAF 的動態模組,請執行以下步驟:

  1. 使用作業系統套件管理工具從 NGINX Plus 模組倉函式庫安裝動態模組。以下命令適用於 Debian 和 Ubuntu 系統。對於使用 RPM 套件的系統,請替換為 yum install 命令:
    $ sudo apt-get install nginx-plus-module-modsecurity
    
  2. /etc/nginx/nginx.conf 的頂層(“main”)上下文中新增以下行:
    load_module modules/ngx_http_modsecurity_module.so;
    
  3. 執行以下命令以驗證模組是否成功載入,確認輸出結果如下:
    $ sudo nginx -t
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful
    

驗證安裝

示例:使用簡單規則設定 ModSecurity 3.0

在本文中,我們設定一個簡單的 ModSecurity 規則,以阻止對演示應用程式的某些請求。NGINX 在示例中充當反向代理,但同樣的設定也適用於負載平衡。演示應用程式只是一個傳回狀態碼 200 和文字訊息的 NGINX 虛擬伺服器。 它在有關使用 ModSecurity 3.0 的規則集的章節中也作為演示應用程式。

建立演示網頁應用程式

透過在 NGINX 中設定虛擬伺服器來建立演示網頁應用程式:

  1. 建立檔案 /etc/nginx/conf.d/echo.conf,內容如下。它設定了一個在 localhost 的 8085 連線埠上監聽並傳回狀態碼 200 和包含請求 URI 的訊息的網頁伺服器:
    server {
        listen localhost:8085;
        location / {
            default_type text/plain;
            return 200 "Thank you for requesting ${request_uri}\n";
        }
    }
    

內容解密:

此組態建立了一個簡單的網頁伺服器,用於監聽本地主機的8085埠,並對任何請求傳回狀態碼200和一條包含請求URI的訊息。這對於測試ModSecurity規則非常有用,因為它提供了一個簡單、可預測的回應來評估規則的效果。

程式碼邏輯解析

上述組態和命令展示瞭如何在NGINX上安裝和設定ModSecurity。首先,我們需要確保NGINX已安裝並更新到合適的版本。然後,我們下載並編譯ModSecurity及其NGINX聯結器,將其作為動態模組載入到NGINX中。這使得NGINX能夠利用ModSecurity的功能來增強網頁應用程式的安全性。

最後,透過建立一個簡單的演示網頁應用程式,我們可以測試ModSecurity規則的效果,確保其按照預期工作。

程式碼重點解析:

  1. 安裝先決套件:列出並安裝編譯ModSecurity所需的套件。
  2. 編譯ModSecurity:下載ModSecurity原始碼並進行編譯。
  3. 編譯NGINX聯結器:下載NGINX聯結器的原始碼,將其編譯為動態模組,並將其載入到NGINX中。
  4. 設定ModSecurity規則:透過一個簡單的示例展示如何設定ModSecurity規則,以阻止特定的請求。