本篇文章更新時間:2022/11/23
如有資訊過時或語誤之處,歡迎使用 Contact 功能通知。
一介資男的 LINE 社群開站囉!歡迎入群聊聊~
如果本站內容對你有幫助,歡迎使用 BFX Pay 加密貨幣新台幣 贊助支持。


先前筆記的 [VPS] WordPress 網站主機群防護升級的作法[Nginx] 阻擋惡意請求來源(User-Agent)的方法[Fail2ban] 同步 Cloudflare WAF 防火牆封鎖 IP 清單的方法 這三篇,主要都是在實作第一版 PHP WAF 網站應用程式防火牆的筆記。

而自從挖到了 CIDRAM 這款開源工具後,寫了這篇 [WordPress] 開源且強大的防火牆外掛 – CIDRAM 筆記。隨後我就開始展開第二版的「即時防護」功能開發。

畢竟第一版還沒解決分析速度,只能從 Log 瀏覽請求日誌下手,這次有方向後就花了一個禮拜給他大改版!

由於整個專案裡包含了公司的機敏內容,所以不能開源,但日後整理出一些技術細節還會再發文筆記。以下就是過程中整理的資源筆記~

架構上主要思路是:「來自機房、非普通瀏覽者的請求都給予封鎖

所以整理好這些機房 IP 區段的黑、白名單就是首要任務!而正巧 CIDRAM 這專案已經準備好了,再來就是先前第一版的防火牆這半年來的封鎖「功績」紀錄。

CIDRAM 的黑名單紀錄:

$cidram_list = array(
    'ipv4.dat'       => 'https://raw.githubusercontent.com/CIDRAM/CIDRAM/v3/vault/signatures/ipv4.dat',
    'ipv4_isps.dat'  => 'https://raw.githubusercontent.com/CIDRAM/CIDRAM/v3/vault/signatures/ipv4_isps.dat',
    'ipv4_other.dat' => 'https://raw.githubusercontent.com/CIDRAM/CIDRAM/v3/vault/signatures/ipv4_other.dat',
    'ipv6.dat'       => 'https://raw.githubusercontent.com/CIDRAM/CIDRAM/v3/vault/signatures/ipv6.dat',
    'ipv6_isps.dat'  => 'https://raw.githubusercontent.com/CIDRAM/CIDRAM/v3/vault/signatures/ipv6_isps.dat',
    'ipv6_other.dat' => 'https://raw.githubusercontent.com/CIDRAM/CIDRAM/v3/vault/signatures/ipv6_other.dat',
);

有興趣了解名單內容的可以花點時間研究這個專案!

再來是「白名單」,來自 Google / Bing / Facebook 等搜尋引擎與社群媒體爬蟲網段:

$cloudflare_list = array(
    'cf_ips-v4' => 'https://www.cloudflare.com/ips-v4',
    'cf_ips-v6' => 'https://www.cloudflare.com/ips-v6',
);
$goodbot_list = array(
    'bingbot.json'   => 'https://www.bing.com/toolbox/bingbot.json',
    'goog.json'      => 'https://www.gstatic.com/ipranges/goog.json',
    'googlebot.json' => 'https://developers.google.com/static/search/apis/ipranges/googlebot.json',
);

看到這會想說,那 Facebook 呢? 就他最特別沒有一個公開的 IP 區段列表,只有公告這些 IP 地址時常變更,要最準的話只有從 ASN 編號去反查 AS32934 Facebook 註冊的網段。

Facebook

處理 ASN 自治系統編號的網段又是另一個門路:

ASN 編號去查使用的企業主名稱,最簡單是 whois AS編號 的指令方法,再來是網友開源的 Whois.phpphp-whois PHP 版本工具以及 whois-locaweb Ruby 版本工具,還有網友直接每日程式自動更新 IP 資訊的 repo IP to ASN list

如果想速查 ASN <-> 使用組織名稱 的關係,可以參考這份多來源整合版本的 repo AS numbers to organization names。其他資源就比較偏向「原始」一點,有些組織名稱還偏向代號,可讀性差一點,BGP 的網站查詢工具。(其他參考1, 其他參考2, 其他參考3

如果想查 IP <-> ASN 的關係,基礎一樣可以使用 Whois 指令,直接 whois 1.1.1.1 這樣,而開發上,最快是直接使用現成的 DB 資料庫來查 IP 資訊,多來源版本 IP to location database by ASN,NodeJS 版本的 iptoasn、Rust 版本的網站查詢工具 iptoasn-webservice、 Bash 版本的查詢工具 ASN。(其他參考1, 其他參考2

如果想查 ASN -> IP區段(prefixes) 的話,Whois 的 RADB 主機指令查詢 whois -h whois.radb.net -- '-i origin AS714' (從 RADB 撈全部 ASN 對應網段的 Shell Script 工具 asn-ip-prefix-full-list),或使用 BGP 提供的 API https://api.bgpview.io/asn/714/prefixes (上述兩個範例都是查詢 Apple AS714 的網段),Go 版本的查詢工具 SPKCYMRU 網站提供的多元工具組、Shell Script 的工具 nginx-acl,直接幫你輸出成 Nginx 可以讀取的黑白名單檔案。

到這邊就差不多資源可以處理 ASN <- 組織 -> IP 這樣的關係了,所以 Facebook 的爬蟲白名單要撈到也不是問題。

下面提供目前我列出來的黑白名單:

$asn_list = array(
    'deny'  => array(
        '9009'   => 'M247',
        '51167'  => 'Contabo',
        '141995' => 'Contabo Asia Private',
        '47154'  => 'HUSAM A. H. HIJAZI',
        '30447'  => 'Hostopia Inc. a Deluxe Company [USA]',
        '207651' => 'Hosting technology',
        '64286'  => 'LogicWeb Inc Hosting Services',
        '45544'  => 'SUPERDATA',
        '211632' => 'Internet Solutions & Innovations LTD',
    ),
    'allow' => array(
        '32934'  => 'FB BOT',
        '2635'   => 'Automattic',
        '3462'   => 'Data Communication Business Group',
        '9416'   => 'Hoshin Multimedia Center Inc.',
        '131596' => 'TBC',
        '4780'   => 'Digital United Inc.',
        '17809'  => 'VEE TIME CORP.',
        '17421'  => 'Mobile Business Group',
        '18049'  => 'Taiwan Infrastructure Network Technologie',
        '9924'   => 'Taiwan Fixed Network, Telco and Network Service Provider.',
        '38841'  => 'kbro CO. Ltd.',
        '24163'  => 'UNION BROADBAND NETWORK',
        '24164'  => 'UNION BROADBAND NETWORK',
        '18182'  => 'Sony Network Taiwan Limited',
        '7482'   => 'Asia Pacific On-line Service Inc.',
        '131627' => 'Peicity Digital Cable Television., LTD',
        '9919'   => 'New Century InfoComm Tech Co., Ltd.',
        '18419'  => 'DaDa Broadband LTD.',
    ),
);

可以看得出來白名單其實主要多是國內網路提供業者 ISP,而這些還不是全部,但因為 CIDRAM 這專案有把這裡面的業者網段給封鎖,所以特別挑出來處理白名單部分。

原本還要直接從 IP 分配端的最前線來開始處理爬蟲,但後來想想也沒必要,這些雲端機房的資訊還滿公開的,可以碰一個封鎖一個。

當時處理 IP 的一些筆記也放一下:


$registries = array();
//資料源頭,包含管理局、地區(ISO 3166 2-letter country code)、ASN編號、地區、IP區段 Ref: https://ftp.ripe.net/pub/stats/ripencc/RIR-Statistics-Exchange-Format.txt
// afrinic|ZA|asn|1228|1|19910301|allocated
// afrinic|ZA|ipv4|41.56.0.0|65536|20100125|allocated
// afrinic|ZA|ipv6|2001:43f8:1300::|48|20181116|assigned
$registries['afrinic'] = 'http://ftp.afrinic.net/pub/stats/afrinic/delegated-afrinic-latest'; //Africa
$registries['apnic'] = 'https://ftp.apnic.net/stats/apnic/delegated-apnic-latest'; //Asia & Pacific
$registries['arin']    = 'https://ftp.arin.net/pub/stats/arin/delegated-arin-extended-latest'; //North America
$registries['lacnic']  = 'http://ftp.lacnic.net/pub/stats/lacnic/delegated-lacnic-latest'; //South America
$registries['ripe']    = 'https://ftp.apnic.net/stats/ripe-ncc/delegated-ripencc-latest'; //Europe

對應不同區域查詢的 Whois 主機服務清單:List of Routing RegistriesIPv4 分配的狀態

然後因為爬 Whois 資料庫有些有每日的請求上限,如果需要套代理伺服器(Proxy)的話這個 Go 版本的工具 goforward 很方便處理!

到這邊也差不多告一個段落,取得黑、白名單後,就是建立資料庫,然後快速查詢請求的 IP 是否符合條件,要封鎖要放行,後面就容易多了!

我的網站伺服器環境主要是 Nginx,如果要列一份黑白名單的話,只要白名單在前,黑名單在後,就算後段黑名單有符合條件也還是會放行,就不會變成單一 IP 與 CIDR IP 區段的衝突,能夠達成「想封鎖 AWS 全網段,但又不要封鎖到我的 AWS 主機」,算是滿方便的設計。

後記

整個實作的過程中閱讀與尋找了很多資源。其實也發現有不少人跟我一樣的想法(至少從 CIDRAM 這專案開始)。

有人是直接套用 Cloudflare 的 WAF,列一份清單來處理 Hosting Companies ASN LIST,更也有人整理了一份雲端業者的清單來開源 bad-asn-list,看延伸要怎用都有自由,雖然名稱用了「bad」,但其實看說明也是能理解主要是用這些服務來亂的那些人。

我相信實作方式肯定會是因人因架構而異,像是我有些網站是在 Cloudflare CDN 背後且不同帳號管理,所以 WAF 防火牆也要去分主動被動模式,第一個請求雖然給予通過,但快速的將 IP 通報到 Cloudflare 的 WAF 就可以及時阻止第二個請求發生。

如此一來第一版本從 Log 去分析是否為攻擊請求,再搭配直接從可能的惡意名單(主機服務商)封鎖,攔截掉攻擊的可能性又更高了。


Share:

作者: Chun

資訊愛好人士。主張「人人都該為了偷懶而進步」。期許自己成為斜槓到變進度條 100% 的年輕人。[///////////____36%_________]

參與討論

1 則留言

  1. 自動引用通知: [WordPress] 搭配 Cloudflare WAF 規則減少網站被攻擊的幾個做法 – 一介資男

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *


文章
Filter
Apply Filters
Mastodon