在今天的內容開始之前,我先賣個關子,文章結尾,我會放一個超級彩蛋,所以,今天的內容你一定要看到最后哦!
上一節我們看到,做一個小區物業維護一個大家共享的環境,還是挺不容易的,如果都是自覺遵守規則的住戶那還好,如果遇上不自覺的住戶就會很麻煩,
就像公有云的環境,其實沒有你想的那么純凈,各懷鬼胎的黑客到處都是,掃描你的埠呀,探測一下你啟動的什么應用啊,看一看是否有各種漏洞啊,這就像小偷潛入小區后,這兒看看,那兒瞧瞧,窗戶有沒有關嚴了啊,窗簾有沒有拉上啊,主人睡了沒,是不是時機潛入室內啊,等等,
假如你創建了一臺虛擬機,里面明明跑了一個電商應用,這是你非常重要的一個應用,你會把它進行安全加固,這臺虛擬機的作業系統里,不小心安裝了另外一個后臺應用,監聽著一個埠,而你的警覺性沒有這么高,
虛擬機的這個埠是對著公網開放的,碰巧這個后臺應用本身是有漏洞的,黑客就可以掃描到這個埠,然后通過這個后臺應用的埠侵入你的機器,將你加固好的電商網站黑掉,這就像你買了一個五星級的防盜門,卡車都撞不開,但是廁所窗戶的門把手是壞的,小偷從廁所里面就進來了,
所以對于公有云上的虛擬機,我的建議是僅僅開放需要的埠,而將其他的埠一概關閉,這個時候,你只要通過安全措施守護好這個唯一的入口就可以了,采用的方式常常是用 ACL(Access Control List,訪問控制串列)來控制 IP 和埠,
設定好了這些規則,只有指定的 IP 段能夠訪問指定的開放介面,就算有個有漏洞的后臺行程在那里,也會被屏蔽,黑客進不來,在云平臺上,這些規則的集合常稱為安全組,那安全組怎么實作呢?
我們來復習一下,當一個網路包進入一臺機器的時候,都會做什么事情,
首先拿下 MAC 頭看看,是不是我的,如果是,則拿下 IP 頭來,得到目標 IP 之后呢,就開始進行路由判斷,在路由判斷之前,這個節點我們稱為 PREROUTING,如果發現 IP 是我的,包就應該是我的,就發給上面的傳輸層,這個節點叫作 INPUT,如果發現 IP 不是我的,就需要轉發出去,這個節點稱為 FORWARD,如果是我的,上層處理完畢后,一般會回傳一個處理結果,這個處理結果會發出去,這個節點稱為 OUTPUT,無論是 FORWARD 還是 OUTPUT,都是路由判斷之后發生的,最后一個節點是 POSTROUTING,
整個程序如圖所示,

整個包的處理程序還是原來的程序,只不過為什么要格外關注這五個節點呢?
是因為在 Linux 內核中,有一個框架叫 Netfilter,它可以在這些節點插入 hook 函式,這些函式可以截獲資料包,對資料包進行干預,例如做一定的修改,然后決策是否接著交給 TCP/IP 協議堆疊處理;或者可以交回給協議堆疊,那就是 ACCEPT;或者過濾掉,不再傳輸,就是 DROP;還有就是 QUEUE,發送給某個用戶態行程處理,
這個比較難理解,經常用在內部負載均衡,就是過來的資料一會兒傳給目標地址 1,一會兒傳給目標地址 2,而且目標地址的個數和權重都可能變,協議堆疊往往處理不了這么復雜的邏輯,需要寫一個函式接管這個資料,實作自己的邏輯,
有了這個 Netfilter 框架就太好了,你可以在 IP 轉發的程序中,隨時干預這個程序,只要你能實作這些 hook 函式,
一個著名的實作,就是內核模塊 ip_tables,它在這五個節點上埋下函式,從而可以根據規則進行包的處理,按功能可分為四大類:連接跟蹤(conntrack)、資料包的過濾(filter)、網路地址轉換(nat)和資料包的修改(mangle),其中連接跟蹤是基礎功能,被其他功能所依賴,其他三個可以實作包的過濾、修改和網路地址轉換,
在用戶態,還有一個你肯定知道的客戶端程式 iptables,用命令列來干預內核的規則,內核的功能對應 iptables 的命令列來講,就是表和鏈的概念,

iptables 的表分為四種:raw–>mangle–>nat–>filter,這四個優先級依次降低,raw 不常用,所以主要功能都在其他三種表里實作,每個表可以設定多個鏈,
filter 表處理過濾功能,主要包含三個鏈:
- INPUT 鏈:過濾所有目標地址是本機的資料包;
- FORWARD 鏈:過濾所有路過本機的資料包;
- OUTPUT 鏈:過濾所有由本機產生的資料包,
nat 表主要是處理網路地址轉換,可以進行 Snat(改變資料包的源地址)、Dnat(改變資料包的目標地址),包含三個鏈:
- PREROUTING 鏈:可以在資料包到達防火墻時改變目標地址;
- OUTPUT 鏈:可以改變本地產生的資料包的目標地址;
- POSTROUTING 鏈:在資料包離開防火墻時改變資料包的源地址,
mangle 表主要是修改資料包,包含:
- PREROUTING 鏈;
- INPUT 鏈;
- FORWARD 鏈;
- OUTPUT 鏈;
- POSTROUTING 鏈,
將 iptables 的表和鏈加入到上面的程序圖中,就形成了下面的圖和程序,

- 資料包進入的時候,先進 mangle 表的 PREROUTING 鏈,在這里可以根據需要,改變資料包頭內容之后,進入 nat 表的 PREROUTING 鏈,在這里可以根據需要做 Dnat,也就是目標地址轉換,
- 進入路由判斷,要判斷是進入本地的還是轉發的
- 如果是進入本地的,就進入 INPUT 鏈,之后按條件過濾限制進入,
- 之后進入本機,再進入 OUTPUT 鏈,按條件過濾限制出去,離開本地,
- 如果是轉發就進入 FORWARD 鏈,根據條件過濾限制轉發
- 之后進入 POSTROUTING 鏈,這里可以做 Snat,離開網路介面,
iptables -t filter -A INPUT -s 0.0.0.0/0.0.0.0 -d X.X.X.X -j DROP
-s 表示源 IP 地址段,-d 表示目標地址段,DROP 表示丟棄,也即無論從哪里來的,要想訪問我這臺機器,全部拒絕,誰也黑不進來,
但是你發現壞了,ssh 也進不來了,都不能遠程運維了,可以打開一下,
iptables -I INPUT -s 0.0.0.0/0.0.0.0 -d X.X.X.X -p tcp --dport 22 -j ACCEPT
如果這臺機器是提供的是 web 服務,80 埠也應該打開,當然一旦打開,這個 80 埠就需要很好的防護,但是從規則角度還是要打開,
iptables -A INPUT -s 0.0.0.0/0.0.0.0 -d X.X.X.X -p tcp --dport 80 -j ACCEPT
這樣就搞定了,其他的賬戶都封死,就一個防盜門可以進出,只要防盜門是五星級的,就比較安全了,
這些規則都可以在虛擬機里,自己安裝 iptables 自己配置,但是如果虛擬機數目非常多,都要配置,對于用戶來講就太麻煩了,能不能讓云平臺把這部分作業做掉呢?
當然可以了,在云平臺上,一般允許一個或者多個虛擬機屬于某個安全組,而屬于不同安全組的虛擬機之間的訪問以及外網訪問虛擬機,都需要通過安全組進行過濾,

例如圖中,我們會創建一系列的網站,都是前端在 Tomcat 里面,對外開放 8080 埠,資料庫使用 MySQL,開放 3306 埠,
為了方便運維,我們創建兩個安全組,將 Tomcat 所在的虛擬機放在安全組 A 里面,在安全組 A 里面,允許任意 IP 地址 0.0.0.0/0 訪問 8080 埠,但是對于 ssh 的 22 埠,僅僅允許管理員網段 203.0.113.0/24 訪問,
我們將 MySQL 所在的虛擬機放在安全組 B 里面,在安全組 B 里面,僅僅允許來自安全組 A 的機器訪問 3306 埠,但是對于 ssh 的 22 埠,同樣允許管理員網段 203.0.113.0/24 訪問,
這些安全組規則都可以自動下發到每個在安全組里面的虛擬機上,從而控制一大批虛擬機的安全策略,這種批量下發是怎么做到的呢?你還記得這幅圖嗎?

兩個 VM 都通過 tap 網卡連接到一個網橋上,但是網橋是二層的,兩個 VM 之間是可以隨意互通的,因而需要有一個地方統一配置這些 iptables 規則,
可以多加一個網橋,在這個網橋上配置 iptables 規則,將在用戶在界面上配置的規則,放到這個網橋上,然后在每臺機器上跑一個 Agent,將用戶配置的安全組變成 iptables 規則,配置在這個網橋上,
安全問題解決了,iptables 真強大!別忙,iptables 除了 filter,還有 nat 呢,這個功能也非常重要,
前面的章節我們說過,在設計云平臺的時候,我們想讓虛擬機之間的網路和物理網路進行隔離,但是虛擬機畢竟還是要通過物理網和外界通信的,因而需要在出物理網的時候,做一次網路地址轉換,也即 nat,這個就可以用 iptables 來做,
我們學過,IP 頭里面包含源 IP 地址和目標 IP 地址,這兩種 IP 地址都可以轉換成其他地址,轉換源 IP 地址的,我們稱為 Snat;轉換目標 IP 地址的,我們稱為 Dnat,
你有沒有思考過這個問題,TCP 的訪問都是一去一回的,而你在你家里連接 WiFi 的 IP 地址是一個私網 IP,192.168.1.x,當你通過你們家的路由器訪問 163 網站之后,網站的回傳結果如何能夠到達你的筆記本電腦呢?肯定不能通過 192.168.1.x,這是個私網 IP,不具有公網上的定位能力,而且用這個網段的人很多,茫茫人海,怎么能夠找到你呢?
所以當你從你家里訪問 163 網站的時候,在你路由器的出口,會做 Snat 的,運營商的出口也可能做 Snat,將你的私網 IP 地址,最終轉換為公網 IP 地址,然后 163 網站就可以通過這個公網 IP 地址回傳結果,然后再 nat 回來,直到到達你的筆記本電腦,
云平臺里面的虛擬機也是這樣子的,它只有私網 IP 地址,到達外網網口要做一次 Snat,轉換成為機房網 IP,然后出資料中心的時候,再轉換為公網 IP,

這里有一個問題是,在外網網口上做 Snat 的時候,是全部轉換成一個機房網 IP 呢,還是每個虛擬機都對應一個機房網 IP,最終對應一個公網 IP 呢?前面也說過了,公網 IP 非常貴,虛擬機也很多,當然不能每個都有單獨的機房網和公網 IP 了,因此這種 Snat 是一種特殊的 Snat,MASQUERADE(地址偽裝),
這種方式下,所有的虛擬機共享一個機房網和公網的 IP 地址,所有從外網網口出去的,都轉換成為這個 IP 地址,那又一個問題來了,都變成一個公網 IP 了,當 163 網站回傳結果的時候,給誰呢,再 nat 成為哪個私網的 IP 呢?
這就是 Netfilter 的連接跟蹤(conntrack)功能了,對于 TCP 協議來講,肯定是上來先建立一個連接,可以用“源 / 目的 IP+ 源 / 目的埠”唯一標識一條連接,這個連接會放在 conntrack 表里面,當時是這臺機器去請求 163 網站的,雖然源地址已經 Snat 成公網 IP 地址了,但是 conntrack 表里面還是有這個連接的記錄的,當 163 網站回傳資料的時候,會找到記錄,從而找到正確的私網 IP 地址,
這是虛擬機做客戶端的情況,如果虛擬機做服務器呢?也就是說,如果虛擬機里面部署的就是 163 網站呢?
這個時候就需要給這個網站配置固定的物理網的 IP 地址和公網 IP 地址了,這時候就需要詳細配置 Snat 規則和 Dnat 規則了,
當外部訪問進來的時候,外網網口會通過 Dnat 規則將公網 IP 地址轉換為私網 IP 地址,到達虛擬機,虛擬機里面是 163 網站,回傳結果,外網網口會通過 Snat 規則,將私網 IP 地址轉換為那個分配給它的固定的公網 IP 地址,
類似的規則如下:
- 源地址轉換 (Snat):iptables -t nat -A -s 私網 IP -j Snat --to-source 外網 IP
- 目的地址轉換 (Dnat):iptables -t nat -A -PREROUTING -d 外網 IP -j Dnat --to-destination 私網 IP
到此為止 iptables 解決了非法偷窺隱私的問題,
小結
- 云中的安全策略的常用方式是,使用 iptables 的規則,請記住它的五個階段,PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING,
- iptables 分為四種表,raw、mangle、nat、filter,其中安全策略主要在 filter 表中實作,而虛擬網路和物理網路地址的轉換主要在 nat 表中實作,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/195995.html
標籤:其他
