在本系列的第一篇文章中,我們介紹了我們客服系統(tǒng)遇到DDoS攻擊的情況,以及我們?yōu)槭裁礇Q定采用自建CDN的方式來解決這個問題的原因。
下面,我們將介紹自建CDN的具體建設(shè)規(guī)劃,主要從以下幾個方面進行考量:硬件成本、帶寬成本、架構(gòu)設(shè)計、實際部署。
硬件成本
在硬件上,我們選型的需求是在1U的基礎(chǔ)上具有強勁的性能,同時性價比要高。
我們選擇了(強氧)雙子星服務(wù)器,其硬件規(guī)格為:1U機身+支持雙路至強CPU+最大支持48G內(nèi)存+雙千兆網(wǎng)口x2+H3C S1208八口千兆,提供三年質(zhì)保服務(wù),總價約1.5萬。
帶寬成本
單線機房的機房和帶寬資源,由于不需要經(jīng)過第三方拉線撮合,直接從運營代理商購買,因此選擇余地大,性價比高。以租用電信、聯(lián)通單線資源為例,每條線獨享100M帶寬,提供8個IP,有些機房自帶硬防,能夠防御5G-10G流量。
平均費用,每個節(jié)點帶寬成本基本在1.6~2.5萬/年。
架構(gòu)設(shè)計
CDN架構(gòu)上要充分體現(xiàn)出抗攻擊能力和靈活應(yīng)變的原則。因此,我們將CDN節(jié)點分解成反向代理+緩存加速+攻擊防御這三個不同層次的功能結(jié)構(gòu)。
- 反向代理功能(作用:路由加速,隱藏主節(jié)點,負載均衡)
- 緩存加速功能(作用:靜態(tài)推送,節(jié)省后端主節(jié)點帶寬)
- 攻擊防御功能(作用:快速解析,匹配過濾惡意攻擊)
開源世界里能夠擔(dān)當(dāng)反向代理及緩存的軟件不少,而且各有優(yōu)劣。作為架構(gòu)師,要考慮如何選型,我們從性能、功能、配置上來進行比較篩選。
| 軟件名稱 | 性能 | 功能 | 過濾規(guī)則配置 |
|---|---|---|---|
| Squid | 不能多核是硬傷,磁盤緩存容量有優(yōu)勢,性能中等 | 多,支持ACL角色控制,也支持ICP緩存協(xié)議 | 支持外部規(guī)則文件讀取及熱加載,支持熱啟動 |
| Varnish | 多核支持,內(nèi)存緩存,性能強 | 夠用,不支持集群,支持后端存活檢查 | 不支持外部文件讀取,需要轉(zhuǎn)義,支持熱啟動 |
| Nginx | 多核支持,支持代理插件,性能較強 | 多,通過插件可以充當(dāng)多角色服務(wù)器 | 不支持外部文件讀取,需要轉(zhuǎn)義,支持熱啟動 |
| ATS | 多核支持,磁盤/內(nèi)存緩存,性能強 | 夠用,支持插件開發(fā),也支持ICP協(xié)議 | 支持外部規(guī)則文件讀取及熱加載,支持熱啟動,但缺乏文檔 |
| HAProxy | 多核支持,無緩存,HTTP頭支持語法操作,性能強 | 少,只專注HTTP頭部解析和轉(zhuǎn)發(fā)功能,支持ACL角色控制,支持后端存活檢查 | 支持外部規(guī)則文件讀取及熱加載,支持熱啟動,支持會話粘滯和長連接 |
我們對這三層功能結(jié)構(gòu)分別進行了測試調(diào)優(yōu)及生產(chǎn)線的實踐檢驗,從以下方面評估:
- HTTP防御性能:HAProxy在應(yīng)對大流量CC攻擊時,做正則匹配及頭部過濾時,CPU消耗只占10%~20%。其它軟件均狂占CPU資源約90%以上,容易成瓶頸導(dǎo)致整個系統(tǒng)無響應(yīng)。
- 反向代理性能:單純轉(zhuǎn)發(fā)效率以內(nèi)存緩存型的Varnish性能最強,ATS和Nginx次之,考慮大容量緩存因素,ATS也是個不錯的選擇,但文檔缺乏,需要持續(xù)關(guān)注。Nginx是專門針對C10K的產(chǎn)物,性能不錯,配合眾多插件,改造性很強。
- 過濾規(guī)則的可配置性:HAProxy,ATS,Squid均支持規(guī)則文件讀取、ACL定制和熱加載、熱啟動。Nginx則不支持外部文件正則匹配,略差一點,但可塑性強。
因此,綜合上述考慮,最終我們采用的架構(gòu)是HAProxy+Varnish/ATS/Nginx的組合,即防御型反向代理緩存方案,功能角色如下:
- 前面由HAProxy全力負責(zé)動靜資源分離,實現(xiàn)會話粘滯,節(jié)點負載均衡,故障轉(zhuǎn)移,遇到危急時承擔(dān)基于Http協(xié)議的CC類型攻擊防御。
- 后面為可插拔替換的反向代理緩存引擎:根據(jù)生產(chǎn)線上的實際應(yīng)用場景及緩存對象的容量來決定使用內(nèi)存型的varnish或者是磁盤型的ats,如果需要定制功能很強(防盜鏈)的反向代理如Nginx+plugins。
這個組合最大的特點是:
- 支持外部過濾規(guī)則的讀取,尤其是關(guān)鍵字符串無需轉(zhuǎn)義,可直接追加到文件中。
- 支持配置文件熱加載生效,都支持reload,服務(wù)平滑生效。
- 可插拔式的緩存組件靈活應(yīng)對各種業(yè)務(wù)需求。
- 部署簡單,節(jié)點失效/生效切換方便。
LVS缺席:為什么這里沒有提及LVS,因為LVS是個重量級、高效穩(wěn)定的四層轉(zhuǎn)發(fā),不能作七層HTTP協(xié)議的識別,但完全可以架設(shè)在七層之前。所以,LVS的使用并不會影響網(wǎng)絡(luò)結(jié)構(gòu),后續(xù)仍然可以想上就上,只是前提要兼顧到LVS的單點故障。
實際部署
最終我們在主節(jié)點周圍一共部署了8個CDN節(jié)點(節(jié)點數(shù)量根據(jù)自身公司實力及實際生產(chǎn)環(huán)境要求而靈活調(diào)整,此數(shù)字僅作參考),這些節(jié)點又按照地域劃分成了四個大區(qū):北方(以山東,河北為主)、西南(以四川為主)、華東(以寧波,嘉興為主) 華南(以福建,湖南為主 )兼顧全國各個省份。
總體成本情況
8個單線加速節(jié)點,每個節(jié)點100Mx8,8臺雙子星服務(wù)器,總共投資約30W(后續(xù)費用只考慮帶寬支出,約15W/年),我們應(yīng)急撥款為10W,每個月CDN預(yù)算為2W。
項目進度安排:
1~4個月抓進度:特點是快速部點。這里有個訣竅,前期可以先跟IDC按月或者季度簽約,然后通過監(jiān)控看連續(xù)的節(jié)點質(zhì)量,如果節(jié)點質(zhì)量不佳,更換提供商,這樣損失不會太大,如果節(jié)點質(zhì)量好,就半年付或者年付,這樣就可以保證質(zhì)量和性價比最高;
5~8個月為完善期:根據(jù)預(yù)算,有節(jié)奏的加點,加帶寬,保證帶寬的冗余度;
8個月以后為穩(wěn)定期:根據(jù)實際情況保證節(jié)點的最大可用性,同時也提升了整體防御能力。
如何做防護策略
開啟HAProxy的httplog功能,記錄日志。
HAProxy的配置策略:
global
nbproc 24
pidfile /var/run/haproxy.pid
daemon
quiet
user nobody
group nobody
chroot /opt/haproxy
spread-checks 2
defaults
log 127.0.0.1 local5
mode http
option forwardfor
option httplog
option dontlognull
option nolinger # reduce FIN_WAIT1
option redispatch
retries 3
option http-pretend-keepalive
option http-server-close
option accept-invalid-http-request
timeout client 15s
timeout connect 15s
timeout server 15s
timeout http-keep-alive 15s
timeout http-request 15s
stats enable
stats uri /stats
stats realm 53KF\ Proxy\ Status
stats refresh 60s
stats auth admin:adminxxx
listen Web_FB 0.0.0.0:80
option httpchk GET /alive.php HTTP/1.0
acl invalid_referer hdr_sub(referer) -i -f /opt/haproxy/etc/bad_ref.conf
acl invalid_url url_sub -i -f /opt/haproxy/etc/bad_url.conf
acl invalid_methods method -i -f /opt/haproxy/etc/bad_method.conf
block if invalid_referer || invalid_url || invalid_methods
acl dyn_host hdr(host) -i -f /opt/haproxy/etc/notcache_host.conf
acl static_req path_end -i -f /opt/haproxy/etc/allow_cache_file.conf
use_backend img_srv if static_req !dyn_host
# acl shaohy
acl geek hdr_dom(host) -i 17geek.com
use_backend geek if geek
# backend shaohy
backend geek
mode http
balance source
cookie SESSION_COOKIE insert indirect nocache
option tcpka
server geek_1 127.0.0.1:81 cookie geek_1 maxconn 10000 weight 8
backend img_srv
mode http
option tcpka
server img_srv 127.0.0.1:88 maxconn 30000 weight 8Varnish的配置策略:
backend h_17geek_com_1 {
.host="127.0.0.1";
.port="81";
.connect_timeout=300s;
.first_byte_timeout=300s;
.between_bytes_timeout=300s;
}
director geek srv {
{ .backend=h_17geek_com_1; .weight=3;}
}
sub vcl_recv {
if (req.http.host~"^(www).?17geek.com$"){
set req.backend=geek_srv;
if (req.request != "GET" && req.request != "HEAD") {
return (pipe);
}
if(req.url ~ "\.(php|jsp)($|\?)") {
return (pass);
}
else {
return (lookup);
}
}
}對于CC類型的DDoS攻擊,通過第一篇當(dāng)中介紹的監(jiān)控異常流量的方法依然適用,而且優(yōu)勢更明顯,因為:
- 節(jié)點各自承擔(dān)相應(yīng)的日志記錄,分析日志的系統(tǒng)開銷,發(fā)現(xiàn)異常請求后直接在haproxy前端做ACL規(guī)則 過濾,因此,攻擊壓力不會傳遞給后端服務(wù)器,保證后端安全。
- 節(jié)點受到的攻擊流量過大,機房可以拉黑IP或者引流,后端智能DNS會自動把這個節(jié)點剔除,后續(xù)請求不要通過此節(jié)點。
在本系列的下一篇文章中,我們會介紹這個CDN架構(gòu)的一些后續(xù)改進工作,包括智能DNS、大規(guī)模日志分析、利用OpenCDN改善后臺管理等。
作者簡介
邵海楊(個人頁面),來自杭州Linux用戶組。網(wǎng)名“海洋之心”,系統(tǒng)架構(gòu)師,業(yè)余撰稿人,致力于開源軟件及前沿科技的研究和探索。
張磊(微博,博客),來自杭州谷歌開發(fā)者社區(qū)。專注于信息安全技術(shù)領(lǐng)域,曾主導(dǎo)多項銀行/證券行業(yè)網(wǎng)站安全測試和入侵取證分析項目,為四大銀行提供安全防護技術(shù)支持。目前創(chuàng)業(yè)做互聯(lián)網(wǎng)安全防護。 ?




