記一次LVS/Nginx環(huán)境下的訪問控制

在偶然中,我注意到 graphite 顯示的服務器網(wǎng)卡流量呈現(xiàn)出一種鋸齒狀的波動,這引起了我的警覺。通過檢查 nginx 日志,我發(fā)現(xiàn)了有人在周期性地抓取我們的接口數(shù)據(jù)。這種行為讓我無法容忍。

通過對訪問日志進行簡單的分析,我迅速鎖定了可疑的 IP 段,并嘗試使用 iptables 進行封禁:

shell> iptables -A INPUT -s x.y.z.0/24 -j DROP

我原本以為這樣就能解決問題,然而結(jié)果卻讓我大失所望——似乎這些措施完全無效。難道這些“小偷”已經(jīng)找到了繞過封鎖的方法?這不太可能!我的直覺告訴我,這可能與 lvs 有關(guān),但遺憾的是我對 LVS 的了解非常有限。我唯一知道的是項目使用的是 FULLNAT 模式,于是我決定從這個角度開始深入調(diào)查:

記一次LVS/Nginx環(huán)境下的訪問控制LVS FULLNAT

FULLNAT 模式的工作原理是,當用戶請求通過 LVS 轉(zhuǎn)發(fā)到 RS 服務器時,源 IP 會被替換為 LVS 的內(nèi)網(wǎng) IP,而目標 IP 則從 LVS 的 VIP 變成 RS 服務器的 IP;當 RS 服務器響應通過 LVS 發(fā)送回用戶時,源 IP 從 RS 服務器的 IP 變?yōu)?LVS 的 VIP,目標 IP 從 LVS 的內(nèi)網(wǎng) IP 變?yōu)橛脩舻?IP。

備注:如需了解更多關(guān)于 LVS 的詳細信息,請參考「從一個開發(fā)的角度看負載均衡和LVS」一文。

然而,矛盾的是,盡管 RS 服務器看到的是 LVS 的 IP,nginx 日志中卻記錄的是客戶端的 IP。這是為什么呢?原來 LVS 在 FULLNAT 模式下引入了 TOA 補丁機制,通過 TCP 三次握手階段的 options 傳遞用戶 IP 和端口信息,從而覆蓋 socket 的 IP 和端口數(shù)據(jù)。

換句話說,從 iptables 的角度看,RS 服務器上看到的都是 LVS 的 IP,而從 Nginx 的角度看,由于 TOA 的作用,記錄的是用戶的 IP。這可以通過 tcpdump 命令抓包來驗證:

記一次LVS/Nginx環(huán)境下的訪問控制tcpdump

備注:如圖所示,254 開頭的字符串中包含了用戶的 IP 和端口信息。

因此,可以得出結(jié)論:在 RS 服務器上使用 iptables 封禁用戶 IP 是無效的,因為我無法操作 LVS 服務器,只能在 RS 服務器上想辦法。由于 Nginx 能夠獲取到用戶的 IP,我們可以選擇在 Nginx 上解決這個問題。Nginx 提供了 Access、GEO 等多個模塊供選擇,這里我們選擇 GEO 模塊:

geo $bad {     default 0;     x.y.z.0/24 1; }  location / {     if ($bad) {         return 403;     } }

關(guān)于 GEO 模塊的使用,有許多優(yōu)秀的參考資料可供查閱,這里就不再贅述。

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點贊6 分享