LVS-TUN模式集羣在開啓防火牆狀況下的一次調試之旅

目錄

1、集羣說明2、預備知識3、問題描述4、排查流程5、回顧總結html

1、集羣說明

  • OS: CentOS7.2
  • DS(LVS): 10.1.61.114
  • LVS-MODE: TUN
  • VIP: 10.1.61.82
  • RS1(Nginx): 10.1.62.105
  • RS2(Nginx): 10.1.62.106
  • PORT: 80
  • 防火牆: DS、RS一、RS2均安裝 firewalld,且開放80端口(tcp,udp)

2、預備知識

  1. firewalld 是 iptables 的前端控制器,用於實現持久的網絡流量規則。前端

  2. firewalld 自身並不具有防火牆的功能,而是和 iptables 同樣須要經過內核的 netfilter 來實現,也就是說 firewalld 和 iptables 同樣,他們的做用都是用於維護規則,而真正使用規則幹活的是內核的 netfilter,只不過 firewalld 和 iptables 的結構以及使用方法不同罷了。網絡

  3. netfilter 有五鏈四表,說明以下。
    五鏈:app

    • PREROUTING:數據包進入路由表以前
    • INPUT:經過路由表後目的地爲本機
    • FORWARD:經過路由表後,目的地不爲本機
    • OUTPUT:由本機產生,向外轉發
    • POSTROUTIONG:發送到網卡接口以前。

    四表:curl

    • filter表,負責過濾數據包,也就是防火牆實現"防火"的功能,iptables命令中若是沒有指定 -t,即默認爲此表。filter表中只有OUTPUT/FORWARD/INPUT鏈。
    • nat表,實現網絡地址轉換的表。能夠轉換源地址、源端口、目標地址、目標端口。NAT表中的鏈是PREROUTING/POSTROUTING/OUTPUT。
    • mangle表,拆解報文,作出修改,並從新封裝。mangle表中包含全部的鏈。
    • raw表,加速數據包穿過防火牆的表。只有PREROUTING/OUTPUT表。
  4. 四個表的優先級由高到低的順序爲:raw → mangle → nat → filter,好比說 PRROUTING 鏈上,即有 mangle 表,也有 nat 表,那麼先由 mangle 處理,而後由 nat 表處理。tcp

  5. Linux 上的防火牆是由 netfilter 實現的,可是 netfilter 的功能不只僅只有「防火」,通常能夠認爲「防火」的功能只是 filter 表的功能。學習

    瞭解上述知識後,咱們能夠把數據包經過防火牆的流程總結爲下圖。
    url

    特此說明:圖片借用自朱雙印博客,這位大佬的博客裏有一套 iptables 系列教程,想學習詳細知識的能夠直接去他博客看,連接:www.zsythink.net
    特此說明:圖片借用自朱雙印博客,這位大佬的博客裏有一套 iptables 系列教程,想學習詳細知識的能夠直接去他博客看,連接:www.zsythink.net

3、問題描述

集羣部署完成後,訪問 VIP:PORT 遭到拒絕(Connection refused)。spa

直接訪問 RS1:PORT 和 RS2:PORT 都可以正常訪問 Nginx 服務(因爲我未寫入index.html,因此返回404頁面是正常現象)。.net

4、排查流程

關閉 DS 防火牆,未解決問題。恢復開啓 DS 防火牆後,再嘗試關閉 RS1 防火牆,RS1 服務正常返回,RS2 依舊是鏈接拒絕。

猜想 Client → DS 這條鏈路是正常的,問題出如今 DS → RS 這條鏈路上。

恢復開啓 RS1 的防火牆,登錄至 DS 機器上,使用命令ipvsadm -L -n查看鏈接狀態來驗證猜測。

ipvsadm -L -n 命令結果小科普:
對於 TCP 協議而言,ActiveConn 列是活動鏈接數,也就是tcp鏈接狀態的 ESTABLISHED ,而 InActConn 列是指除了 ESTABLISHED 之外的,全部的其它狀態的 tcp 鏈接。

當前 InActConn 和 ActiveConn 均爲0。

在 Client 端繼續使用命令for i in {1..100}; do curl 10.1.61.82:80; sleep 0.5; done循環請求 VIP:PORT,而後在 DS 上使用命令ipvsadm -L -n再次查看鏈接狀態。發現 InActConn 數值發生了改變,說明 DS 是收到了 Client 端的數據包的,ActiveConn 爲0是由於 DS → RS 被拒,因此 tcp 鏈接未能創建。

目前已定位到數據包出現問題的鏈路是在 DS → RS ,OK,那就抓個包看看唄。

在DS上使用命令tcpdump -i any host 10.1.62.105截獲 RS1 收到和發出的全部數據包(在 Client 依然用老方法循環請求 VIP:PORT ),能夠看到 DS 發給 RS1 的數據包被 RS1 用一個協議爲 ICMP 的數據包拒絕了。等等,這個數據包的內容咋這麼眼熟(ICMP host prohibited),好像用 iptables 查看規則時見過。

我立刻登錄到RS1,直接用命令iptables --line -vnL INPUT查看 INPUT 鏈中的規則(--line可顯示規則的編號,數據包在鏈中是順着規則編號往下逐步匹配的;-v顯示詳細信息;-n不解析IP地址;-L指定鏈名;不指定-t默認顯示 filter 表)。

能夠看到第七條 REJECT 規則就是用 icmp-host-prohibited 做爲數據包內容拒絕的。啊哈?DS 發給 RS1 的數據包被最後一條規則匹配到了?爲何沒被前面的規則處理掉?我不是開啓了80端口嗎?

雖然一堆疑問,不過仍是先確認下 DS 發給 RS1 的數據包是否是真被第七條規則匹配處理了。這裏我採用的方法是,在 Client 端循環請求 VIP:PORT 的先後分別用命令iptables --line -vnL INPUT查看第七條規則的 pkts(該規則匹配到的數據包數量)數值是否發生了變化,果真 pkts 發生了增加,說明數據包真的是被第七條規則匹配到而且 REJECT 掉了。

額,我用命令iptables --line -vnL查看了全部 Chain(鏈) 的規則,找到我開放80端口的那兩條規則又確認了一下,發現 dport 是80,協議爲 tcp 的那條規則 pkts 一直是0,並無變化(這條規則在 INPUT 鏈中是被第五條規則匹配的,規則雖然是在 IN_public_allow 鏈的,但瞭解過 iptables 自定義鏈相關知識後,就會明白這其實是一個調用鏈的關係:INPUT_ZONES → IN_public → IN_public_allow,從下圖的每一個 Chain 的 target 也能看出來)。

再次確認下,這條規則源地址、目標地址、端口、協議等等都沒有問題,並且最開始我也直接訪問 RS1:PORT 確認過 Nginx 服務是沒有問題的,能夠正常返回,因此我懷疑從 DS → RS1 的數據包並非一個 tcp 包,因此沒有被此規則匹配並處理。

而後又返回去查了下 LVS-TUN 模式的數據包處理流程。

ipvs 工做在 INPUT 鏈,它在原有的 IP 報文外再次封裝多一層 IP 頭,內部 IP 頭 (源地址爲 CIP,目標 IP 爲 VIP),外層 IP 頭 (源地址爲 DIP,目標 IP 爲 RIP),而後將封裝好的數據包從 DS 發往 RS 。

到這,我已經恍然大悟了,它確實不是一個 tcp 包,再翻到以前從 DS 上抓取 RS1 的數據包內容,能夠看到 DS → RS1 的數據包協議爲 ipip-proto-4。

因此,處理方法也很明確了,放行這個 ipip 協議的數據包。個人處理方法是在 RS1 上使用命令iptables -t filter -I INPUT -p ipv4 -j ACCEPT增長一條對全部協議類型爲 ipip 的數據包ACCEPT的規則(這裏的 prot 顯示的 4 表明 ipv4 的協議號,想要查看協議名與協議號的對應關係能夠在這裏查找Protocol Numbers)。

記住必定要在 INPUT 鏈第七條以前,我這裏是直接插入到了第一條,我以前看一篇博文上用的是-A INPUT,這表示 append(追加) 一條規則,會出如今最後,這樣設置的規則數據包根本就匹配不到,由於它已經被在你前面的那條REJECT規則匹配並拒絕掉了。

最後咱們再從 Client 端請求驗證一下規則是否生效,能夠看到 RS1 已經正常返回了,且 RS1 上的第一條規則 pkts 也發生了增加,說明數據包已被匹配且正確處理。

RS2 也設置相同的過濾規則,而後再次驗證,兩臺 RS 均正常返回,over。

5、回顧總結

  1. 不少搭建 LVS 集羣的文章都會前置聲明關閉防火牆或者使用iptables -F命令將 iptables 規則清空,以避免發生通訊問題。實際上大多數狀況下你確實能夠這樣作,可是萬一輩子產環境就要開防火牆呢,萬一設置的某幾條 iptables 規則很是重要,你啪一條命令給人全清了,是否是得寫個事故報告。

  2. 個人排查流程真的是像文章中同樣如此順利嗎?其實並非,由於這個問題出現時,我既不清楚 iptables 相關知識(一兩年前簡單的看過,而後忘光了),也不清楚 ipvs 的工做原理,就是拿來主義,因此剛開始排查的時候和無頭蒼蠅同樣,一頓瞎比操做,後來仍是滾回去補了 iptables 和 ipvs 的相關知識。因此其實排查流程中的第4步開始都已是次日的事了。

  3. 若是懂了 iptables 相關知識(五鏈四表、規則管理、匹配條件、擴展模塊、自定義鏈等等)。清楚命令及命令結果中每一個參數的意思很是重要,像遇到此類防火牆問題,你均可以用文中的排查流程去走一遍,無非就是規則匹配問題。

  4. 分析網絡問題,簡單的抓包能夠達到事半功倍的效果,配合 Wireshark 一塊兒食用味道更佳。

相關文章
相關標籤/搜索