1. 程式人生 > 實用技巧 >熱門技術中的應用-雲端計算中的網路3-雲中網路安全

熱門技術中的應用-雲端計算中的網路3-雲中網路安全

在今天的內容開始之前,我先賣個關子。文章結尾,我會放一個超級彩蛋,所以,今天的內容你一定要看到最後哦!

上一節我們看到,做一個小區物業維護一個大家共享的環境,還是挺不容易的。如果都是自覺遵守規則的住戶那還好,如果遇上不自覺的住戶就會很麻煩。

就像公有云的環境,其實沒有你想的那麼純淨,各懷鬼胎的黑客到處都是。掃描你的埠呀,探測一下你啟動的什麼應用啊,看一看是否有各種漏洞啊。這就像小偷潛入小區後,這兒看看,那兒瞧瞧,窗戶有沒有關嚴了啊,窗簾有沒有拉上啊,主人睡了沒,是不是時機潛入室內啊,等等。

假如你建立了一臺虛擬機器,裡面明明跑了一個電商應用,這是你非常重要的一個應用,你會把它進行安全加固。這臺虛擬機器的作業系統裡,不小心安裝了另外一個後臺應用,監聽著一個埠,而你的警覺性沒有這麼高。

虛擬機器的這個埠是對著公網開放的,碰巧這個後臺應用本身是有漏洞的,黑客就可以掃描到這個埠,然後通過這個後臺應用的埠侵入你的機器,將你加固好的電商網站黑掉。這就像你買了一個五星級的防盜門,卡車都撞不開,但是廁所窗戶的門把手是壞的,小偷從廁所裡面就進來了。

所以對於公有云上的虛擬機器,我的建議是僅僅開放需要的埠,而將其他的埠一概關閉。這個時候,你只要通過安全措施守護好這個唯一的入口就可以了。採用的方式常常是用 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 的表和鏈加入到上面的過程圖中,就形成了下面的圖和過程。

  1. 資料包進入的時候,先進 mangle 表的 PREROUTING 鏈。在這裡可以根據需要,改變資料包頭內容之後,進入 nat 表的 PREROUTING 鏈,在這裡可以根據需要做 Dnat,也就是目標地址轉換。
  2. 進入路由判斷,要判斷是進入本地的還是轉發的
  3. 如果是進入本地的,就進入 INPUT 鏈,之後按條件過濾限制進入。
  4. 之後進入本機,再進入 OUTPUT 鏈,按條件過濾限制出去,離開本地。
  5. 如果是轉發就進入 FORWARD 鏈,根據條件過濾限制轉發
  6. 之後進入 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 表中實現。