資安 mod_maxminddb Apache GeoLite 存取控制

部署mod_maxminddb存取控制 GeoLite資料庫整合Apache

地理位置納入流量防護 實作連線來源國別管制

2026-07-29
開源碼社群中的地理位置管控模組mod_maxminddb,讓使用者除了利用傳統的IP管控機制外,還可導入以地理位置為基礎的存取控制。本文將以Apache網站伺服器為例,動手實作為其加上以地理位置來限定連線的功能。

隨著網站服務日益普及,其所面臨的資安威脅也愈加嚴峻。在現今網際網路環境中,網站時時都會面臨來自世界各地的惡意攻擊行為,例如自動化弱點掃描、針對帳號密碼的暴力攻擊等等。

一般而言,當網站管理者偵測到此類異常活動時,通常會透過防火牆或其他資安設備,針對可疑來源IP進行封鎖,以降低潛在風險。然而,在現今的網路環境中,僅單純依靠以IP為基礎的防護策略,往往難以全面應對日益複雜的攻擊手法,例如攻擊者可利用代理伺服器或使用VPN等方式來隨機變換IP。若單純僅依靠以來源IP封鎖的方式,將無法真正有效地封鎖來源IP。

本文將介紹一套開源碼社群中有名的地理位置管控模組mod_maxminddb,其官方網址是「https://github.com/maxmind/mod_maxminddb?tab=readme-ov-file」,讓使用者除了利用傳統的IP管控機制外,還導入了以地理位置(如僅允許某個特定國家或地區的連線)為基礎的存取控制(Geo-based Access Control),並以著名的Apache網站伺服器為例,為其加上以地理位置來限定連線的功能。而本次所使用的作業系統為CentOS Stream 9。

什麼是mod_maxminddb

mod_maxminddb是一個Apache的模組程式,主要功能是將IP位址(通常是網站的連線來源IP位址)轉換為地理位置,例如將168.95.1.1轉換成國別代碼如TW。而後再藉由網站的存取控制機制,針對轉換後的地理位置資訊進行相關規則管控,例如設定僅允許來自台灣的來源能進行連線。其運作流程,簡單說明如下:

1. 使用者瀏覽網站。

2. Apache網站伺服器接收到使用者的要求(Request)後,其mod_maxminddb模組會取得使用者的來源IP,並藉由查詢地理資料庫(本文使用GeoLite的地理資料庫)來取得該來源IP所對應的地理位置,然後將該資料儲存於變數中。

3. Apache網站伺服器可針對該變數設定相關管控規則,以決定該連線是否可存取。

安裝mod_maxminddb模組

在了解相關運作後,接著就來安裝mod_maxminddb模組。在安裝之前,必須先安裝地理資料庫。首先執行以下的指令,安裝用來讀取地理資料庫格式(格式為mndb)的相關程式庫:

dnf install libmaxminddb dnf install libmaxminddb-devel

接著,下載相關的地理資料庫。相關資料庫目前是由maxmind公司(https://www.maxmind.com/)所維護,提供付費的完整版本或免費的精簡(GeoLite)版本,在本文中使用的版本為精簡版。不管是完整或精簡版本,均須先註冊為該公司的會員,才可以下載地理資料庫,因此先連線至網址「https://www.maxmind.com/en/create-account」進行註冊。

註冊完成後,即可先行登入後取得Account ID(帳號ID)及License Key(使用金鑰)等資訊,以供後續設定使用,如圖1所示。

圖1  登入後取得帳號ID和使用金鑰。

緊接著執行如下的指令,安裝更新地理資料庫的管理程式,名稱為「geoipupdate」:

dnf install geoipupdate

安裝完成後,即可使用geoipupdate程式來取得並更新最新版本的地理資料庫。在使用geoipupdate之前,先設定組態檔(/etc/GeoIP.conf),主要設定下列組態值即可(其中#為註解說明):

AccountID  [帳號ID]     #在登入maxmind後取得 LicenseKey  [使用金鑰]   #在登入maxmind後取得

接著,設定所要下載的地理資料庫名稱,在此僅下載精簡版本的國家(GeoLite2-Country)和城市(GeoLite2-City)的地理資料庫:

#設定下載精簡版本的地理資料庫 EditionIDs  GeoLite2-Country GeoLite2-City   #設定地理資料庫置放的目錄位置 DatabaseDirectory /usr/local/ share/GeoIP

完成設定後,使用以下的指令來執行更新,-f:為指定組態檔的位置:

geoipupdate -f /etc/GeoIP.conf

更新完成後,在「/usr/local/share/GeoIP」目錄下應該就會有GeoLite2-City.mmdb和GeoLite2-Country.mmdb地理資料庫檔案。

接著,可利用mmdblookup來測試地理資料庫是否正常(將IP轉換成地理區域資訊),執行如下指令,其中--file指定地理資料庫檔案的位置,而--ip為測試的IP:

mmdblookup --file /usr/local/share/GeoIP/ GeoLite2-City.mmdb --ip 168.95.1.1

在正常的情況下,將會回覆一個JSON格式的回覆資訊(內容包含此IP所屬的城市和國別等資訊)。在安裝好地理資料庫與管理程式後,接著就能安裝mod_maxminddb(在此版本為1.3.0)。本文假設已安裝Apache伺服器並安裝於「/usr/local/apache2/」目錄,所以執行如下的安裝指令:

#取得mod_maxminddb的原始碼 wget https://github.com/maxmind/mod_ maxminddb/archive/refs/tags/1.3.0.tar.gz

在解壓縮後,至其原始碼的目錄並執行下列指令:

bootstrap  #重新建立編譯環境設定

由於要編譯成Apache網站伺服器所使用的模組,因此必須使用--with-apxs來指定apxs程式的位置,指令內容如下:

configure --with-apxs=/usr/local/ apache2/bin/apxs

然後,以make指令進行編譯(Compiler)。編譯成功後,即可利用「make install」來安裝相關模組。如果一切正常,完成安裝後,在「/usr/local/apache2/modules/」目錄下將會產生名稱為「mod_maxminddb.so」的模組程式。

mod_maxminddb.so常用組態

以下說明mod_maxminddb.so常用組態:

MaxMindDBEnable [On|Off]

設定是否啟用IP對應地理位置的查詢。

MaxMindDBFile [變數名稱] [地理位置資料庫位置]

設定以變數名稱來儲存地理位置資料庫的位置。例如「MaxMindDBFile COUNTRY_DB /usr/share/GeoIP/GeoLite2-Country.mmdb」,是以變數名稱為COUNTRY_DB來表示GeoLite2-Country.mmdb。

MaxMindDBEnv [變數名稱] [地理資料庫名稱/資料路徑

設定以變數來儲存以IP(網站的來源連線IP)查詢到的地理區域資訊,也就是將查詢地理資料庫的結果儲存至變數中,而後續網站伺服器(Apache)可針對此變數進行相關的存取控制。例如「MaxMindDBEnv MM_COUNTRY_CODE COUNTRY_DB/country/iso_code」,其中COUNTRY_DB為地理資料庫名稱,country/iso_code為資料路徑,表示取得地理資料庫(GeoLite2-Country.mmdb)內的國家代碼(iso_code)資訊,並將此資訊儲存在名稱為MM_COUNTRY_CODE的變數中,後續即可針對MM_COUNTRY_CODE設定相關規則進行連線的管控。

由於地理資料庫的儲存方式採用json的階層格式,因此county/iso_code表示取得國家代碼的資訊,如圖2所示,在本例中,國家代碼為TW,以此類推,如果想取得國家的英文名稱,可使用country/names/en來取得(本例為Taiwan)。

圖2  地理資料庫的儲存方式採用json的階層格式。

說明過相關組態的用法後,最後使用mod_maxminddb模組實作一個利用地理區域來管控來源IP的機制。為了測試方便,這裡以封鎖來自台灣的連線IP為例。

相關Apache組態說明

由於是利用Apache的管控機制進行來源連線的控管,因此在設定之前,先簡單說明相關的Apache組態:

SetEnvIf [來源欄位] [規則] [變數]

此組態是針對來源欄位,建立比對的規則(可使用正規表示法),如果規則成立,便會建立一個變數,後續即可利用此變數,制定相關管控連線規則。例如「SetEnvIf MM_COUNTRY_CODE  ^(TW)$  BlockCountry」,表示當MM_COUNTRY_CODE變數內容為TW時,便符合所設定的規則,此時會建立一個名稱為BlockCountry的變數。

〈RequireAll〉…〈/RequireAll〉

此組態可設定是否允許來源IP的連線,必須在此區段中所有設定的規則均符合,才會允許連線,其設定語法為:

Require  [條件式]

其常見的規則設定,如下所示:

Require all granted:表示允許所有來源的連線,一般而言,通常會先預設此規則,後續再設定欲管控的限制規則。 Require all denied:表示拒絶所有來源的連線。 Require [設定IP]:表示僅允許來源為[設定IP]的連線。 Require env [變數名稱]:表示如果所設定的變數存在,才可允許連線。 Require not env [變數]:表示如果所設定的變數不存在,才可允許連線。在本文中,便是利用此規則來完成管控措施。

動手實作測試

了解會使用到的相關組態用法後,接著以限制來自「台灣」的連線為例,完成地理位置管控的功能。可在Apache的組態設定檔「httpd.conf」內加入下列的設定(其中#為註解說明):

#設定載入mod_maxminddb模組 LoadModule maxminddb_module modules/mod_maxminddb.so 〈IfModule mod_maxminddb.c〉    MaxMindDBEnable On  #啟用IP轉地        理區域資訊的功能    #設定以COUNTRY_DB變數來表示地理         資料庫的位置   MaxMindDBFile COUNTRY_DB /usr/    local/share/GeoIP/GeoLite2-Country.mmdb    #以MM_COUNTRY_CODE變數來儲存來         源IP轉換過後的國別代碼    MaxMindDBEnv MM_COUNTRY_CODE    COUNTRY_DB/country/iso_code    〈Directory /usr/local/apache2/htdocs〉    #針對網站根目錄(Documentroot)進行設定   #如果MM_COUNTRY_CODE變數內容為TW        即建立名稱為BlockCountry的變數 SetEnvIf MM_COUNTRY_CODE ^(TW)$  BlockCountry     〈RequireAll〉#需符合下列所有規 則,方可進行連線                 #預設所有來源均可連線         Require all granted         #設定當BlockCountry變數存 在即拒絶連線      #由於來源IP轉換過後的國碼為TW 時就會產生BlockCountry變數,因此 此規則是設定拒絶來自台灣的連線       Require not env BlockCountry      〈/RequireAll〉     〈/Directory〉 〈/IfModule〉      

設定完成後,重新啟動Apache網站伺服器,此時即可拒絶所有來自台灣的連線。

<本文作者:吳惠麟,多年資安經驗,喜好利用開源碼建構相關解決方案,著有「資訊安全原理與實驗」等書。>


追蹤我們Featrue us

本站使用cookie及相關技術分析來改善使用者體驗。瞭解更多

我知道了!