1 序言
本次文(wén)章系列将會(huì)逐步分享作(zuò)者親身經曆以及解決思路,讓大(dà)家一起身臨其境,作(zuò)爲開(kāi)篇,會(huì)先和(hé)大(dà)家聊點有趣的,做這(zhè)件事(shì)的動機,對(duì)我的職業道(dào)路有什(shén)麽影響等,大(dà)家可以仁者見仁智者見智。
其實對(duì)我們正常程序員的工(gōng)作(zuò)流程來(lái)說,網絡這(zhè)塊對(duì)我們來(lái)說基本不會(huì)涉及,因爲公司的職責分配,大(dà)家都會(huì)隻負責自(zì)己的部分,例如ui隻負責ui,測試隻負責功能(néng)測試性能(néng)測試,軟件開(kāi)發隻負責軟件開(kāi)發,運維隻負責服務器資源調配整合管理(lǐ),網絡管理(lǐ)等等,但(dàn)是其實對(duì)于大(dà)多數程序員來(lái)說,公司的規模不大(dà)的情況下(xià),一般都會(huì)身兼數職,又是軟件開(kāi)發,又是測試,還需要去部署項目。那麽既然大(dà)家都有機會(huì)橫向拓展自(zì)身的技能(néng),其實真的可以利用(yòng)好(hǎo)機會(huì)去學習,去實踐,看(kàn)的再多,了(le)解的再多不如實際去試試。
又到(dào)了(le)我最喜歡的講故事(shì)環節啦~ 曾經我也(yě)是一名普通的Java程序開(kāi)發,每天寫寫bug,調試一下(xià)代碼,和(hé)産品鬥鬥嘴,日子一天天這(zhè)樣愉快(kuài)的過去。
突然一天,接到(dào)公司電話(huà):"大(dà)事(shì)不好(hǎo)了(le),所有用(yòng)戶都無法正常使用(yòng)應用(yòng)啦,用(yòng)戶投訴已經快(kuài)把公司電話(huà)打爆了(le)。你(nǐ)趕快(kuài)解決!" 當時(shí)還在休周末假期的我,一下(xià)就從(cóng)床上(shàng)挺直了(le)身闆,心想:不會(huì)吧,代碼應該沒問題啊,我不可能(néng)錯的啊(ps:程序員的蜜汁自(zì)信) 緊接着馬上(shàng)打開(kāi)筆(bǐ)記本電腦(nǎo),開(kāi)始排查問題,首先從(cóng)用(yòng)戶反饋的截圖來(lái)看(kàn),應用(yòng)其實連接超時(shí),沒有任何響應。那此時(shí)可以排除掉app應用(yòng)本身的問題,然後立馬使用(yòng)接口測試工(gōng)具postman測試一個線上(shàng)的接口,發現(xiàn)确實無任何響應了(le),糟糕,難道(dào)我的Java服務挂了(le)?然後懷着忐忑的心情登錄遠程服務器,發現(xiàn)服務器居然也(yě)無法登錄了(le),這(zhè)是什(shén)麽情況?
由于我使用(yòng)的是阿裏雲的雲産品,所以立馬登錄阿裏雲賬号,發起一個工(gōng)單咨詢阿裏雲的技術支持,在明(míng)确告知(zhī)了(le)雲服務器實例id以及無法訪問的異常情況後,等待對(duì)方的反饋。在這(zhè)裏給阿裏雲技術支持點個贊,技術反饋很(hěn)快(kuài),并且态度十分友好(hǎo)。最後阿裏雲技術支持反饋工(gōng)單說我們的服務器請(qǐng)求流量異常,進入他(tā)們的黑洞機制了(le)。wtf?說的白(bái)話(huà)一點就是有人在對(duì)我們服務器進行ddos攻擊,我們服務器的資源被耗盡并且觸發了(le)阿裏雲的黑洞機制,我們服務器被丢進"小(xiǎo)黑屋"了(le),什(shén)麽都做不了(le),第一次進入黑洞就是兩個小(xiǎo)時(shí),後面在進入黑洞就會(huì)逐漸時(shí)長增加。
這(zhè)可不得了(le),首先在聯系客戶,安撫客戶的同時(shí),也(yě)馬上(shàng)開(kāi)始針對(duì)這(zhè)次攻擊做出反應。期間黑客甚至還匿名聯系過我們,态度十分嚣張,說什(shén)麽不給"保護費"就會(huì)一直對(duì)我們服務器進行攻擊,不讓我們正常營業,還趾高(gāo)氣昂的說什(shén)麽今天不交5k的保護費,明(míng)天再交那就是一個達不溜,這(zhè)話(huà)聽着怎麽這(zhè)麽耳熟呢(ne)?今日割五城(chéng),明(míng)日割十城(chéng),然後得一夕安寝。取自(zì)<<六國論>>中的經典短句,今日你(nǐ)割讓5個城(chéng)池,明(míng)天再讓你(nǐ)割讓10個城(chéng)池,以此換來(lái)睡一個安穩的覺,然而第二天一看(kàn),秦國的軍隊又來(lái)了(le)。
壞人的欲望是無法滿足的。于是我緊急查找做網絡防火牆的解決方案提供商,阿裏雲的高(gāo)防,一年40多萬的費用(yòng),讓我們望而卻步,畢竟公司的業務暫時(shí)沒有這(zhè)麽大(dà)的量級,這(zhè)個方案屬于不适合當前的,最後接入了(le)一家小(xiǎo)衆公司的網絡防火牆方案,最後以一個月599的價格購買了(le)一個标準套餐的防火牆,測試通過後就将流量全部轉移到(dào)他(tā)們的防火牆進行流量清洗和(hé)監控,最後回源到(dào)我們服務中,而攻擊我們的黑客最後也(yě)是費勁心思的攻擊幾次後,眼看(kàn)攻擊無果,最後灰溜溜的消失在了(le)我們視(shì)線中。
在經曆了(le)服務不可用(yòng)之後再恢複正常使用(yòng)的這(zhè)段黑暗時(shí)刻後,其實心裏還是很(hěn)緊張的,首先就是自(zì)身處于舒适圈,沒有保持一個良好(hǎo)的學習熱忱,導緻技術棧相對(duì)狹隘,認爲一個軟件應用(yòng)從(cóng)開(kāi)發好(hǎo)後,把服務部署到(dào)服務器上(shàng),解析一個域名綁定服務器ip,然後讓app調用(yòng)這(zhè)個域名跟服務接口就完成了(le)任務,認爲自(zì)己這(zhè)樣做開(kāi)發效率還很(hěn)快(kuài),沾沾自(zì)喜,其實正是落入自(zì)己給自(zì)己設下(xià)的糖衣陷阱,限制了(le)自(zì)己的思想,阻礙了(le)自(zì)己思考的能(néng)力,于是我利用(yòng)接入了(le)第三方的防火牆這(zhè)段時(shí)間,自(zì)己也(yě)在惡補網絡相關的知(zhī)識,彌補自(zì)己對(duì)互聯網中的知(zhī)識匮乏。
首先這(zhè)次攻擊,再通過第三方防火牆的管理(lǐ)後台中,我們可以清楚的看(kàn)到(dào)所有的請(qǐng)求ip以及各個ip的請(qǐng)求次數,可以看(kàn)到(dào)正常ip的請(qǐng)求頻率在一分鐘(zhōng)以内一般也(yě)就幾十個連接請(qǐng)求,但(dàn)是有一批ip的請(qǐng)求都是幾萬次,明(míng)顯不正常,通過百度搜索這(zhè)些(xiē)ip,無一例外(wài)都是海外(wài)的ip,也(yě)就是什(shén)麽馬來(lái)西亞啊,柬埔寨啊等等是非之地的ip,這(zhè)一看(kàn)就是被控制了(le)肉雞對(duì)我們同時(shí)進行的ddos攻擊,導緻我們服務的癱瘓。
引用(yòng)百度百科中,DDOS一般指分布式拒絕服務攻擊,分布式拒絕服務攻擊(英文(wén)意思是Distributed Denial of Service,簡稱DDoS)是指處于不同位置的多個攻擊者同時(shí)向一個或數個目标發動攻擊,或者一個攻擊者控制了(le)位于不同位置的多台機器并利用(yòng)這(zhè)些(xiē)機器對(duì)受害者同時(shí)實施攻擊。由于攻擊的發出點是分布在不同地方的,這(zhè)類攻擊稱爲分布式拒絕服務攻擊,其中的攻擊者可以有多個。也(yě)就是上(shàng)面我們所遇到(dào)的對(duì)方使用(yòng)非法技術手段控制多台計(jì)算(suàn)機,同時(shí)對(duì)我們的這(zhè)台服務進行攻擊。而單一的DoS攻擊一般是采用(yòng)一對(duì)一方式的,它利用(yòng)網絡協議(yì)和(hé)操作(zuò)系統的一些(xiē)缺陷,采用(yòng)欺騙和(hé)僞裝的策略來(lái)進行網絡攻擊,使網站(zhàn)服務器充斥大(dà)量要求回複的信息,消耗網絡帶寬或系統資源,導緻網絡或系統不勝負荷以至于癱瘓而停止提供正常的網絡服務。也(yě)就是dos就是1v1單挑,拼的是誰的主機資源性能(néng)更好(hǎo),而ddos就是不講武德,多人運動,以多欺少。
既然知(zhī)道(dào)了(le)攻擊手段,那如何防範呢(ne)?那就要說說防火牆的分類了(le),一般防火牆是有物理(lǐ)硬件防火牆和(hé)軟件防火牆兩種,硬件防火牆代表有著名的F5,Symantec等,這(zhè)類軟硬一體防火牆,國内也(yě)有很(hěn)多做硬件防火牆的廠(chǎng)家,例如天融信,啓明(míng)星辰,聯想網禦,華爲,深信服等等。軟件防火牆有firewall,iptables等等
其中軟件防火牆也(yě)稱爲個人防火牆,它是最常用(yòng)的防火牆,通常作(zuò)爲計(jì)算(suàn)機系統上(shàng)的程序運行,它是可定制的,允許用(yòng)戶控制其功能(néng)。軟件防火牆單獨使用(yòng)軟件系統來(lái)完成防火牆功能(néng),将軟件部署在系統主機上(shàng),其安全性較硬件防火牆差,同時(shí)占用(yòng)系統資源,在一定程度上(shàng)影響系統性能(néng)。硬件防火牆是指把防火牆程序做到(dào)芯片裏面,由硬件執行這(zhè)些(xiē)功能(néng),能(néng)減少CPU的負擔,使路由更穩定。一般的軟件安全廠(chǎng)商所提供的硬件防火牆便是在硬件服務器廠(chǎng)商定制硬件,然後再把linux系統與自(zì)己的軟件系統嵌入。(Symantec的SGS便是DELL+Symantec的軟件防火牆)這(zhè)樣做的好(hǎo)處是linux相對(duì)Windows的server相對(duì)安全。
至于價格高(gāo),原因在于,軟件防火牆隻有包過濾的功能(néng),硬件防火牆中可能(néng)還有除軟件防火牆以外(wài)的其他(tā)功能(néng),例如CF(内容過濾)IDS(入侵偵測)IPS(入侵防護)以及VPN等等的功能(néng)。軟件防火牆一般可以是包過濾機制。包過濾過濾規則簡單,隻能(néng)檢查到(dào)第三層網絡層,隻對(duì)源或目的IP做檢查,防火牆的能(néng)力遠不及狀态檢測防火牆,連最基本的黑客攻擊手法IP僞裝都無法解決,并且要對(duì)所經過的所有數據包做檢查,所以速度比較慢。硬件防火牆主要采用(yòng)第四代狀态檢測機制。狀态檢測是在通信發起連接時(shí)就檢查規則是否允許建立連接,然後在緩存的狀态檢測表中添加一條記錄,以後就不必去檢查規則了(le)隻要查看(kàn)狀态監測表就OK了(le),速度上(shàng)有了(le)很(hěn)大(dà)的提升。
軟件防火牆隻能(néng)保護安裝它的系統。硬件防火牆保障整個内部網絡安全。它的安全和(hé)穩定,直接關系到(dào)整個内部網絡的安全。如果所在的網絡環境中,攻擊頻度不是很(hěn)高(gāo),用(yòng)軟件防火牆就能(néng)滿足要求了(le)。軟件防火牆的優點是定制靈活,升級快(kuài)捷。倘若攻擊頻度很(hěn)高(gāo),建議(yì)用(yòng)硬件來(lái)實現(xiàn)。
硬件防火牆的抗攻擊能(néng)力比軟件防火牆的高(gāo)很(hěn)多,通過硬件實現(xiàn)的功能(néng),效率高(gāo),專門(mén)爲了(le)防火牆這(zhè)一個任務設計(jì)的,内核針對(duì)性很(hěn)強。軟件防火牆在遇到(dào)密集的DDOS攻擊的時(shí)候,它所能(néng)承受的攻擊強度遠遠低(dī)于硬件防火牆。因爲硬件防火牆将防火牆功能(néng)集成到(dào)芯片中,有硬件執行,對(duì)于計(jì)算(suàn)機的cpu使用(yòng)可以算(suàn)是0占用(yòng),穩定性要高(gāo)得多,而軟件防火牆是安裝和(hé)運行在計(jì)算(suàn)機中,在運行時(shí)是會(huì)占用(yòng)當前計(jì)算(suàn)機的cpu以及内存,所以相對(duì)硬件要差一些(xiē)。
不用(yòng)說,那肯定是硬件防火牆的成本是最高(gāo)的,畢竟設備廠(chǎng)商是靠買這(zhè)些(xiē)硬件掙錢(qián)的,一般的硬件防火牆在1到(dào)幾萬不等,好(hǎo)點的都是十萬開(kāi)外(wài)了(le),而軟件防火牆相對(duì)就要友好(hǎo)的多了(le),隻需要能(néng)安裝軟件防火牆能(néng)力的主機即可,成本直線下(xià)降。對(duì)于小(xiǎo)型企業或者個人用(yòng)戶來(lái)說,使用(yòng)軟件防火牆是最适合的。
那麽此次的防火牆集群搭建的第一小(xiǎo)步,就是先在單機上(shàng)部署好(hǎo)一個軟件防火牆并且設定規則。我先是在阿裏雲上(shàng)購買了(le)一台1核1g的雲服務器,系統鏡像選擇centos 7.5 64位的。磁盤由于可能(néng)隻需要存一點點日志,對(duì)于磁盤要求不大(dà),所以選擇40G的一個磁盤挂載,網絡帶寬我們選擇按量付費,最高(gāo)帶寬值拉滿100M,這(zhè)樣的配置,一台服務器的費用(yòng)僅僅需要53塊一個月!流量費用(yòng)在超過每月贈送的固定值後按照每GB8毛錢(qián)來(lái)結算(suàn)。
centos7.5版本以後系統内核編譯的防火牆默認是firewall,而本次我們使用(yòng)的是iptables,所以我們需要先關閉原本的firewall,然後下(xià)載安裝iptables,再使用(yòng)iptables命令來(lái)進行添加規則,最後安裝一個nginx做前置網關,負載均衡到(dào)自(zì)己軟件服務主機上(shàng),以此來(lái)完成軟件防火牆的閉環搭建。
systemctl stop firewalld
systemctl mask firewalld
yum install -y iptables
yum update iptables
yum install iptables-services
iptables -P INPUT ACCEPT
iptables -F
iptables -X
iptables -Z
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
service iptables save
systemctl enable iptables.service
systemctl start iptables.service
yum install -y nginx
systemctl start nginx.service
systemctl enable nginx.service
客戶端的請(qǐng)求直接通過域名解析訪問到(dào)實際業務主機上(shàng),形同裸體,不設防備,所有請(qǐng)求直接打在業務服務器上(shàng),在沒有架設後置網關的情況,沒有負載均衡能(néng)力,服務容易被攻擊,不安全。并且服務器的真實ip暴露,容易被不法分子進行ssh爆破攻擊,對(duì)服務器運行帶來(lái)許多不穩定因素。
客戶端的請(qǐng)求通過域名解析來(lái)到(dào)了(le)防火牆所在的主機上(shàng),在驗證了(le)請(qǐng)求ip是否符合規範等情況後,由nginx轉發請(qǐng)求到(dào)業務服務器上(shàng),返回地址也(yě)使用(yòng)防火牆的ip地址信息,從(cóng)而隐藏了(le)真實的服務ip,避免暴露。本篇文(wén)章作(zuò)爲第一章節,隻介紹單機版本的搭建,以及實現(xiàn)邏輯,下(xià)一章節便給大(dà)家帶來(lái)集群如何實現(xiàn),以及爲什(shén)麽要用(yòng)集群的防火牆,單機的爲什(shén)麽不行。
既然我們已經搭建好(hǎo)并且啓動了(le)上(shàng)述iptables,我們知(zhī)道(dào)iptables也(yě)能(néng)拒絕連接,甚至可以拒接指定ip的連接,那我們隻需要寫一個腳本,每次啓動都檢測一下(xià)當前的ip連接數,對(duì)于單個ip連接數異常高(gāo)的進行一個封禁,那這(zhè)個ip所有的請(qǐng)求在達到(dào)防火牆這(zhè)一層就會(huì)被自(zì)動丢棄,不占用(yòng)系統的資源了(le),也(yě)不影響正常的用(yòng)戶ip的請(qǐng)求。
#iptables 禁用(yòng)單個ip連接
iptables -I INPUT -s 1.2.3.4 -j DROP
#或
iptables -A INPUT -s 1.2.3.4 -j DROP
-A 指定規則應該添加到(dào)的 chain 的名稱。例如,使用(yòng) INPUT 将會(huì)把規則添加到(dào)默認的 INPUT(入站(zhàn))鏈的末尾,而使用(yòng) OUTPUT 則會(huì)将規則添加到(dào)出站(zhàn)鏈的末尾。
-I 将規則添加爲 chain 中的第 rulenum 條規則,原先的第 rulenum 條及以後各條的需要順次 +1。如上(shàng)面一樣,1 表示該 chain 中第一條。默認爲 1,即,如果沒有指定 rulenum 則将該 chain 中第一條規則替換掉。
wget 'http://blog.houlangmark.com/ddos.sh' -O /etc/ddos/ddos.sh
vim 這(zhè)個ddos腳本,主要的命令爲下(xià)面這(zhè)行
cd /etc/ddos
vim ddos.sh
netstat -an |grep ^tcp.*:80|egrep -v 'LISTEN|127.0.0.1'|awk -F"[ ]+|[:]" '{print $6}'|sort|uniq -c|sort -rn
此時(shí)便可以通過定時(shí)啓動腳本一直檢測網絡連接的ip,找到(dào)非法的ip進行操作(zuò)。
由于文(wén)章的篇幅有限,這(zhè)個防火牆系列的第一篇文(wén)章便隻先介紹如何單機搭建好(hǎo)一個防火牆的簡單軟件,我這(zhè)邊給大(dà)家提供我自(zì)己編寫的一個初始化腳本,大(dà)家可以在一台新的服務器上(shàng)自(zì)己試試效果,腳本中每個步驟都有注釋,大(dà)家可以先自(zì)行理(lǐ)解一下(xià)。
wget http://blog.houlangmark.com/install.sh
下(xià)載後的初始化腳本,隻需要執行 sh install.sh即可完成所有步驟,無需你(nǐ)操心。大(dà)家可以先看(kàn)看(kàn)裏面的步驟,這(zhè)裏粘一個部分截圖。
給大(dà)家在這(zhè)裏梳理(lǐ)總結一下(xià),我的實現(xiàn)過程,在一台新的主機上(shàng)下(xià)載初始化腳本,執行腳本會(huì)把nginx下(xià)載下(xià)來(lái),并把一個模闆nginx.conf下(xià)載下(xià)來(lái)放(fàng)置nginx的目錄下(xià),啓動好(hǎo)nginx後會(huì)安裝iptables,安裝好(hǎo)後會(huì)先把所有規則先清理(lǐ)掉,然後開(kāi)放(fàng)基本的一些(xiē)端口服務,然後關閉當前主機原本默認的firewall,啓動iptables,接下(xià)來(lái)會(huì)安裝ipset拓展組件,用(yòng)于記錄ip黑名單和(hé)白(bái)名單,然後通過iptables命令将ipset的集合綁定起來(lái),保存并重啓iptables,最後下(xià)載我這(zhè)邊寫的ddos防禦腳本,并且啓動這(zhè)個腳本一直監聽網絡請(qǐng)求ip,将異常請(qǐng)求ip記錄到(dào)黑名單中,實現(xiàn)自(zì)動拉黑ip,阻止請(qǐng)求。最後就是利用(yòng)nginx将正常Ip的請(qǐng)求轉發到(dào)業務服務器上(shàng)去,到(dào)此第一部分,思路與大(dà)概實現(xiàn)就給大(dà)家分享完畢了(le)。
最後在這(zhè)裏給大(dà)家說一下(xià),由于第一次分享這(zhè)類自(zì)己一個人摸索實現(xiàn)的功能(néng),語言整理(lǐ)這(zhè)塊還有很(hěn)大(dà)的進步空(kōng)間,我也(yě)希望通過更多的分享來(lái)鍛煉自(zì)己的語言組織能(néng)力,給大(dà)家帶來(lái)更好(hǎo)的觀感體驗,能(néng)很(hěn)直觀并且不枯燥的看(kàn)完,更想能(néng)讓讀者自(zì)己動手時(shí)可以利用(yòng)我提供的部分下(xià)載實例能(néng)直接運行測試,後面我會(huì)越來(lái)越努力學習給大(dà)家分享的,歡迎大(dà)家給作(zuò)者一些(xiē)建議(yì),我會(huì)虛心接受。敬請(qǐng)期待下(xià)一期《iptables,ipset詳解》