領事 + iptables = :3

2010年公司 戰爭遊戲 有 50 台伺服器和一個簡單的網路模型:後端、前端和防火牆。 伺服器數量增加,模型變得更加複雜:具有 ACL 的暫存、隔離 VLAN,然後是具有 VRF 的 VPN、在 L2 上帶有 ACL 的 VLAN、在 L3 上帶有 ACL 的 VRF。 頭在旋轉? 以後會更好玩的。

當伺服器數量達到 16 台時,面對如此多的異質網段,要想不流淚地工作就變得不可能了。 所以我們想出了另一個解決方案。 我們採用了 Netfilter 堆疊,將 Consul 新增到其中作為資料來源,這樣我們就得到了一個快速的分散式防火牆。 他們替換了路由器上的 ACL,並將其用作外部和內部防火牆。 為了動態管理該工具,我們開發了 BEFW 系統,該系統無所不在:從管理使用者對產品網路的存取到隔離網​​段。

領事 + iptables = :3

他會告訴您這一切是如何運作的以及為什麼您應該仔細研究這個系統。 伊万·阿加科夫 (安穆奧爾)是公司明斯克開發中心維護部門基礎設施安全小組的負責人。 Ivan 是 SELinux 粉絲,熱愛 Perl,並且編寫程式碼。 身為資安組的負責人,他定期與日誌、備份和研發一起工作,以保護Wargaming免受駭客攻擊,並確保公司所有遊戲伺服器的運作。

歷史信息

在告訴你我們是如何做到的之前,我首先要告訴你我們是如何做到這一點以及為什麼需要它。 為此,讓我們回到 9 年前:2010 年,《戰車世界》剛問世。 Wargaming 大約有 50 台伺服器。

領事 + iptables = :3
公司伺服器增長圖表。

我們有一個網路模型。 就當時而言,這是最佳的。

領事 + iptables = :3
2010年網路模型。

前端有壞人想要破壞我們,但它有防火牆。 後端沒有防火牆,但是那裡有50台伺服器,我們都知道。 一切都運作良好。

4 年間,伺服器群組成長了 100 倍,達到 5000 個。第一個孤立的網路出現了——暫存:它們無法投入生產,而且那裡運作的東西經常可能存在危險。

領事 + iptables = :3
2014年網路模型。

由於慣性,我們使用相同的硬件,所有工作都在隔離的 VLAN 上進行:ACL 寫入 VLAN,允許或拒絕某種連接。

2016年,伺服器數量達到8000台。Wargaming吸收了其他工作室,並出現了更多附屬網路。 它們似乎是我們的,但又不完全是:VLAN 通常不適用於合作夥伴,您必須使用帶有 VRF 的 VPN,隔離變得更加複雜。 ACL 絕緣混合物生長。

領事 + iptables = :3
2016年網路模型。

到2018年初,機器數量已增長到16台。有000個部分,我們沒有計算其餘部分,包括儲存財務資料的封閉部分。 容器網路 (Kubernetes)、DevOps、透過 VPN 連接的雲端網路(例如從 IVS)已經出現。 有很多規則——這很痛苦。

領事 + iptables = :3
2018年網路模型和隔離方法。

對於隔離,我們使用了:在 L2 上具有 ACL 的 VLAN、在 L3 上具有 ACL 的 VRF、VPN 等等。 太多了。

問題

每個人都生活在 ACL 和 VLAN 之中。 怎麼了? 哈羅德將回答這個問題,隱藏痛苦。

領事 + iptables = :3

問題很多,但有五個是大問題。

  • 新規則幾何漲價。 每條新規則的新增時間都比前一條規則長,因為需要先檢查是否已經存在這樣的規則。
  • 網段內沒有防火牆。 這些部分不知何故彼此分離,內部資源已經不足。
  • 這些規則被應用了很長時間。 操作員可以在一小時內手寫一條本地規則。 全球的一件事花了幾天的時間。
  • 審計規則的困難。 更準確地說,這是不可能的。 第一條規則早在 2010 年就已製定,大多數作者已不再為該公司工作。
  • 基礎設施控制水準低。 這是主要問題——我們不太了解我們國家正在發生什麼。

這就是 2018 年網路工程師聽到「需要更多 ACL」時的樣子。

領事 + iptables = :3

Решения

2018年初,決定做點什麼。

集成的價格不斷增長。 起點是大型資料中心停止支援隔離 VLAN 和 ACL,因為設備記憶體不足。

解決方案:我們消除了人為因素,並最大限度地自動化提供存取權限。

新規則的實施需要很長時間。 解決方案:加快規則的應用,使其分散式、並行。 這需要一個分散式系統,以便規則能夠自行傳遞,而無需 rsync 或 SFTP 到一千個系統。

網段內沒有防火牆。 當同一網路中出現不同的服務時,段內防火牆就開始出現。 解決方案:使用主機層級的防火牆—基於主機的防火牆。 幾乎所有地方都有 Linux,所有地方都有 iptables,這不是問題。

審計規則的困難。 解決方案:將所有規則放在一個地方以便審查和管理,這樣我們就可以審核一切。

對基礎設施的控制水準低。 解決方案:盤點所有服務以及它們之間的存取。

這更多的是一個管理過程,而不是一個技術過程。 有時我們每週發布 200-300 個新版本,特別是在促銷和假期期間。 而且,這僅適用於我們 DevOps 的一個團隊。 由於版本眾多,無法了解需要哪些連接埠、IP 和整合。 因此,我們需要經過專門培訓的服務經理,他們會詢問團隊:“到底有什麼,為什麼要提出來?”

在我們推出一切之後,2019 年的網路工程師開始看起來像這樣。

領事 + iptables = :3

領事

我們決定將在服務經理的幫助下找到的所有內容放入 Consul 中,然後從那裡編寫 iptables 規則。

我們是如何決定要這樣做的?

  • 我們將收集所有服務、網路和使用者。
  • 讓我們基於它們建立 iptables 規則。
  • 我們自動化控制。
  • ....
  • 利潤。

Consul不是一個遠端API,它可以在每個節點上運行並寫入iptables。 剩下的就是想出自動控制裝置來清理不必要的東西,大多數問題都會解決! 我們將邊走邊解決剩下的問題。

為什麼是領事?

已經很好地證明了自己。 2014-15 年,我們將其用作 Vault 的後端,在其中儲存密碼。

不遺失數據。 在使用過程中,Consul並沒有出現過一次意外遺失資料的情況。 這對於防火牆管理系統來說是一個巨大的優勢。

P2P連結加速變革的傳播。 有了P2P,所有的改變都來得很快,不需要等待幾個小時。

方便的 REST API。 我們也考慮了 Apache ZooKeeper,但它沒有 REST API,因此您必須安裝拐杖。

既可用作密鑰保管庫 (KV) 又可用作目錄(服務發現)。 您可以同時儲存服務、目錄和資料中心。 這不僅對我們來說很方便,對鄰近的團隊也很方便,因為在建立全球服務時,我們會胸懷大志。

用 Go 寫,是 Wargaming 堆疊的一部分。 我們喜歡這門語言,我們有很多 Go 開發人員。

強大的ACL系統。 在 Consul 中,您可以使用 ACL 來控制誰寫什麼。 我們保證防火牆規則不會與其他規則重疊,因此我們不會遇到任何問題。

但 Consul 也有其缺點。

  • 除非您有商業版本,否​​則無法在資料中心內擴充。 它只能透過聯盟來擴展。
  • 非常依賴網路品質和伺服器負載。 如果網路中存在任何延遲(例如速度不均勻),Consul 將無法作為繁忙伺服器上的伺服器正常運作。 這是由於 P2P 連接和更新分發模型。
  • 難以監控可用性。 以領事身份他可以說一切都很好,但他已經死了很久了。

我們在使用 Consul 時解決了大部分問題,這就是我們選擇它的原因。 該公司計劃提供替代後端,但我們已經學會如何處理問題,目前正在與 Consul 合作。

領事如何運作

有條件的資料中心我們會安裝三到五台伺服器。 一兩台伺服器將無法運作:當資料不符時,它們將無法組織法定人數並決定誰是對的,誰是錯的。 超過五個就沒有意義,生產力會下降。

領事 + iptables = :3

客戶端以任意順序連接到伺服器:相同的代理,僅帶有標誌 server = false.

領事 + iptables = :3

此後,客戶端收到 P2P 連線清單並在它們之間建立連線。

領事 + iptables = :3

在全球範圍內,我們連接多個資料中心。 他們還連接 P2P 並進行通訊。

領事 + iptables = :3

當我們想要從另一個資料中心檢索資料時,請求會從一個伺服器傳送到另一個伺服器。 這個方案被稱為 農奴協議。 Serf 協定和 Consul 一樣,都是由 HashiCorp 開發的。

關於 Consul 的一些重要事實

Consul 有描述其工作原理的文件。 我只會提供一些值得了解的精選事實。

領事服務器從選民中選擇一個主人。 Consul從每個資料中心的伺服器清單中選擇一個主伺服器,所有請求都只發送到它,而不管伺服器數量有多少。 Master凍結不會導致重新選舉。 如果未選擇主伺服器,則任何人都不會處理請求。

您想要水平縮放嗎? 抱歉,沒有。

對另一個資料中心的請求從一個主伺服器發送到另一個主伺服器,無論它來自哪個伺服器。 選定的主伺服器接收 100% 的負載,轉送請求的負載除外。 資料中心中的所有伺服器都有最新的資料副本,但只有一台伺服器做出回應。

擴充功能的唯一方法是在客戶端上啟用陳舊模式。

在陳舊模式下,您可以在沒有法定人數的情況下做出回應。 這是我們放棄資料一致性,但讀取速度比平常快一點,並且任何伺服器都會回應的模式。 當然,只能透過大師來錄製。

Consul 不會在資料中心之間複製數據。 當一個聯邦組裝起來時,每個伺服器將只有自己的資料。 對於別人,他總是求助於別人。

在事務之外不保證操作的原子性。 請記住,您不是唯一可以改變事情的人。 如果您有不同的需求,請使用鎖進行事務。

阻塞操作並不能保證鎖定。 請求從一個主伺服器發送到另一個主伺服器,而不是直接發送,因此不能保證當您阻塞時阻塞會起作用,例如,在另一個資料中心中。

ACL 也不保證存取(在許多情況下)。 ACL 可能無法運作,因為它儲存在一個聯合資料中心 - ACL 資料中心(主 DC)中。 如果 DC 不回答您,ACL 將無法運作。

一個凍結的主宰就會導致整個聯邦凍結。 例如,一個聯邦有10個資料中心,其中一個網路不好,一個master故障。 每個與他通信的人都會陷入一個循環:有請求,沒有答复,線程凍結。 無法知道什麼時候會發生,一兩個小時後整個聯邦就會崩潰。 你對此無能為力。

狀態、法定人數和選舉由單獨的線程處理。 重新選舉不會發生,狀態不會顯示任何內容。 你認為你有一位活著的領事,你問,但沒有任何反應 - 沒有答案。 同時,狀態顯示一切都很好。

我們遇到過這個問題,並且不得不重建資料中心的特定部分來避免它。

Consul Enterprise的商業版不存在上面的一些缺點。 它有許多有用的功能:選擇選民、分配、縮放。 只有一個「但是」——分散式系統的授權系統非常昂貴。

生活黑客: rm -rf /var/lib/consul ——一劑包治百病的藥劑。 如果某些內容對您不起作用,只需刪除您的資料並從副本下載資料即可。 最有可能的是,領事會工作。

北風衛士

現在我們來談談 Consul 中添加的內容。

北風衛士 是縮寫 BACKEndF忿怒W全部。 當我建立儲存庫時,我必須以某種方式命名該產品,以便將第一個測試提交放入其中。 這個名字仍然保留著。

規則模板

這些規則是用 iptables 語法寫的。

  • -N BEFW
  • -P 輸入下降
  • -A 輸入 -m 狀態—狀態相關、已建立 -j 接受
  • -A 輸入 -i lo -j 接受
  • -A 輸入 -j BEFW

所有東西都進入 BEFW 鏈,除了 ESTABLISHED, RELATED 和本機。 模板可以是任何東西,這只是一個例子。

BEFW 有什麼用?

服務

我們有一個服務,它總是有一個端口,一個它運行的節點。 從我們的節點,我們可以在本地詢問代理並發現我們有某種服務。 您也可以放置標籤。

領事 + iptables = :3

任何正在運行並註冊到 Consul 的服務都會變成 iptables 規則。 我們有 SSH - 開啟連接埠 22。Bash 腳本很簡單:curl 和 iptables,不需要其他任何東西。

客戶

如何不向所有人開放存取權限,而是選擇性地開放存取權限? 按服務名稱將 IP 清單新增至 KV 儲存。

領事 + iptables = :3

例如,我們希望第十個網路上的每個人都能夠存取 SSH_TCP_22 服務。 新增一個小的 TTL 字段? 現在我們有臨時許可證,例如一天的許可證。

存取權限

我們連接服務和客戶端:我們有一個服務,KV 儲存已為每個服務做好準備。 現在我們不是向所有人提供存取權限,而是選擇性地提供存取權限。

領事 + iptables = :3

如果我們每次寫幾千個IP來存取的話,我們會很累。 讓我們提出分組—KV 中的一個單獨的子集。 我們將其稱為別名(或群組)並根據相同的原理將群組儲存在那裡。

領事 + iptables = :3

讓我們連線:現在我們可以開啟SSH,不是專門針對P2P,而是針對整個群組或多個群組。 同樣,還有 TTL - 您可以新增到群組並暫時從群組中刪除。

領事 + iptables = :3

積分

我們的問題是人為因素和自動化。 目前為止我們都是這樣解決的。

領事 + iptables = :3

我們與 Puppet 合作,並將與系統(應用程式程式碼)相關的所有內容轉移給他們。 Puppetdb(常規 PostgreSQL)儲存在那裡運行的服務列表,可以透過資源類型找到它們。 在那裡您可以找到誰在哪裡申請。 為此,我們還有一個拉取請求和合併請求系統。

我們編寫了befw-sync,一個有助於傳輸資料的簡單解決方案。 首先,同步cookie由puppetdb存取。 在那裡配置了一個 HTTP API:我們請求我們擁有什麼服務,需要做什麼。 然後他們向領事提出請求。

有整合嗎? 是的:他們編寫了規則並允許接受 Pull 請求。 您是否需要某個連接埠或將主機新增到某個群組? Pull 請求、審查 - 不再需要「尋找 200 個其他 ACL 並嘗試對此採取措施」。

優化

使用空規則鏈 Ping 本機需要 0,075 毫秒。

領事 + iptables = :3

讓我們在該鏈上新增 10 個 iptables 位址。 結果,ping會增加000倍:iptables是完全線性的,處理每個位址需要一些時間。

領事 + iptables = :3

對於遷移數千個 ACL 的防火牆,我們有許多規則,這會帶來延遲。 這對於遊戲協議來說是不利的。

但如果我們把 ipset 中有 10 個位址 ping甚至會下降。

領事 + iptables = :3

關鍵是,無論有多少規則,ipset 的「O」(演算法複雜度)總是等於 1。 確實,有一個限制 - 規則不能超過 65535 條。現在我們接受這一點:您可以將它們組合起來,擴展它們,將兩個 ipset 合而為一。

存儲

迭代過程的邏輯延續是將有關服務的客戶端的資訊儲存在 ipset 中。

領事 + iptables = :3

現在我們有相同的SSH,我們不是一次寫入100個IP,而是設定我們需要通訊的ipset的名稱,以及以下規則 DROP。 可以轉換為一條規則“誰不在,DROP”,但更清晰。

現在我們有了規則和設定。 主要任務是在編寫規則之前先進行設置,因為否則 iptables 將不會編寫規則。

一般計劃

以圖表的形式來看,我所說的一切都是這樣的。

領事 + iptables = :3

我們承諾Puppet,一切都發送到主機,服務在這裡,ipset在那裡,任何沒有在那裡註冊的人都是不允許的。

允許否認

為了快速拯救世界或快速停用某人,在所有鏈的開頭我們創建了兩個 ipset: rules_allow и rules_deny。 怎麼運作的?

例如,有人正在使用機器人在我們的網路上創建負載。 以前,你必須從日誌中找到他的IP,並將其交給網路工程師,以便他們找到流量的來源並禁止他。 現在看起來不一樣了。

領事 + iptables = :3

我們將其發送給 Consul,等待 2,5 秒,就完成了。 由於 Consul 透過 P2P 快速分發,因此它可以在世界任何地方、任何地方工作。

有一次,由於防火牆的錯誤,我以某種方式完全停止了 WOT。 rules_allow - 這是我們針對此類情況的保險。 如果我們在防火牆的某個地方犯了錯誤,某處被阻止了,我們總是可以發送一個條件 0.0/0快速撿起所有東西。 稍後我們將手工修復所有內容。

其他套裝

您可以在空間中新增任何其他集合 $IPSETS$.

領事 + iptables = :3

為了什麼? 例如,有時有人需要 ipset 來模擬叢集某些部分的關閉。 任何人都可以帶任何套裝,給它們命名,然後領事就會把它們拿走。 同時,集合既可以參與iptables規則,也可以作為一個團隊 NOOP:一致性將由守護程式維護。

會員

以前是這樣的:使用者連接到網絡,透過網域接收參數。 在新一代防火牆出現之前,思科不知道如何了解使用者在哪裡以及IP在哪裡。 因此,只能透過電腦的主機名稱授予存取權限。

我們做了什麼? 當我們收到地址時,我們陷入了困境。 通常是 dot1x、Wi-Fi 或 VPN - 一切都經過 RADIUS。 對於每個用戶,我們按用戶名建立一個群組,並在其中放置一個 IP,其 TTL 等於其 dhcp.lease - 一旦過期,該規則就會消失。

領事 + iptables = :3

現在我們可以像其他群組一樣透過使用者名稱開放對服務的存取。 我們減輕了主機名稱變更帶來的痛苦,也減輕了網路工程師的負擔,因為他們不再需要思科。 現在,工程師自己在他們的伺服器上註冊存取權限。

絕緣

同時,我們開始拆除隔熱層。 服務經理進行了盤點,我們分析了所有網路。 讓我們將它們分成相同的群組,並在必要的伺服器上新增這些群組,例如拒絕。 現在,相同的暫存隔離最終出現在生產的 Rules_deny 中,但不在生產本身。

領事 + iptables = :3

該方案運行快速且簡單:我們從伺服器中刪除所有 ACL,卸載硬件,並減少隔離 VLAN 的數量。

完整性控制

以前,我們有一個特殊的觸發器,可以在有人手動更改防火牆規則時進行報告。 我正在編寫一個巨大的 linter 來檢查防火牆規則,這很困難。 Integrity 現在由 BEFW 控制。 他熱心地確保他所製定的規則不會改變。 如果有人改變了防火牆規則,一切都會變回來。 「我很快就設定了一個代理,這樣我就可以在家工作」——沒有更多這樣的選擇了。

BEFW 從服務控制 ipset,並在 befw.conf 中列出,即 BEFW 鏈中服務的規則。 但它不監控其他鍊和規則以及其他 ipset。

碰撞保護

BEFW 始終將最後一個已知的良好狀態直接儲存在 state.bin 二進位結構中。 如果有問題,它總是回滾到這個state.bin。

領事 + iptables = :3

這是針對 Consul 操作不穩定(當它沒有發送資料或有人犯了錯誤並使用了無法應用的規則時)的保險。 為了確保我們不會失去防火牆,如果任何階段發生錯誤,BEFW 都會回滾到最新狀態。

在危急情況下,這可以確保我們保留有效的防火牆。 我們開放所有灰色網絡,希望管理員能夠來修復它。 有一天我會將其放入配置中,但現在我們只有三個灰色網路:10/8、172/12 和 192.168/16。 在我們的 Consul 中,這是一個幫助我們進一步發展的重要功能。

在演示:報告中,Ivan演示了BEFW的演示模式。 觀看示範更方便 視頻。 提供演示原始碼 在 GitHub 上.

陷阱

我會告訴你我們遇到的錯誤。

ipset 新增設定 0.0.0.0/0。 如果將 0.0.0.0/0 加到 ipset 會發生什麼事? 所有IP都會被加入嗎? 可以上網嗎?

不,我們會遇到一個錯誤,導致我們停機兩個小時。 此外,該錯誤自 2016 年以來就不再起作用,它位於 RedHat Bugzilla 中,編號為#1297092,我們是從開發人員的報告中偶然發現的。

BEFW 現在有一條嚴格的規定: 0.0.0.0/0 變成兩個地址: 0.0.0.0/1 и 128.0.0.0/1.

ipset 恢復集 < 檔案。 當你告訴 ipset 時它會做什麼 restore? 你認為它的運作原理和 iptables 一樣嗎? 會恢復資料嗎?

沒有那樣的 - 它進行合併,舊地址不會去任何地方,你不會阻止訪問。

我們在測試隔離時發現了一個錯誤。 現在有一個相當複雜的系統 - 而不是 restore 保持 create temp, 然後 restore flush temp и restore temp。 交換結束時:為了原子性,因為如果你先這樣做 flush 此時,某個資料包到達,它將被丟棄,並且會出現問題。 所以這裡面有一點黑魔法。

領事 kv get -datacenter=other。 正如我所說,我們認為我們正在要求一些數據,但我們要么得到數據,要么得到錯誤。 我們可以透過本地的 Consul 來完成此操作,但在這種情況下,兩者都會凍結。

本地 Consul 用戶端是 HTTP API 的包裝器。 但它只是掛起並且不響應 Ctrl+C、Ctrl+Z 或任何其他操作 kill -9 在下一個控制台中。 我們在建立大型叢集時遇到了這個問題。 但我們還沒有解決方案;我們正準備在 Consul 中修復這個錯誤。

領事領導沒有回應。 我們資料中心的master沒有反應,我們想:“也許重選演算法現在可以工作了?”

不,這不起作用,監控也不會顯示任何內容:Consul 會說有承諾指數,已找到領導者,一切都很好。

我們該如何處理這個問題? service consul restart 每小時以 cron 形式執行。 如果你有 50 台伺服器,沒什麼大不了的。 當它們達到 16 個時,你就會明白它是如何運作的。

結論

結果,我們獲得了以下優勢:

  • 100%覆蓋所有Linux機器。
  • 速度。
  • 自動化。
  • 我們將硬體和網路工程師從奴役中解放出來。
  • 整合的可能性幾乎是無限的:即使使用 Kubernetes,即使使用 Ansible,甚至使用 Python。

缺點:領事,我們現在必須忍受它,錯誤的成本非常高。 舉個例子,有一次下午 6 點(俄羅斯的黃金時間),我正在編輯網路清單中的一些內容。 當時我們剛在 BEFW 建造隔熱層。 我在某個地方犯了一個錯誤,似乎我指示了錯誤的面具,但一切都在兩秒鐘內倒下了。 監視器亮起,值班人員跑過來:“我們什麼都有了!” 當部門主管向業務解釋為什麼會發生這種情況時,他的臉色變得灰白。

錯誤的成本是如此之高,以至於我們制定了自己的複雜預防程序。 如果您在大型生產網站上實現此功能,則無需透過 Consul 向每個人提供主代幣。 這會很糟糕地結束。

費用。 我一個人就寫了 400 小時的程式碼。 我的 4 人團隊每月花費 10 個小時為每個人提供支援。 與任何新一代防火牆的價格相比,它是免費的。

計劃。 長期計劃是尋找替代交通來替代或補充 Consul。 也許是卡夫卡或類似的東西。 但未來幾年我們將依靠 Consul 生活。

近期計劃:與 Fail2ban、監控、nftables 集成,可能與其他發行版、指標、高級監控、優化集成。 Kubernetes 支援也在計劃中,因為現在我們有幾個集群和願望。

更多來自計劃:

  • 尋找交通異常狀況;
  • 網路地圖管理;
  • Kubernetes 支援;
  • 為所有系統組裝軟體包;
  • 網路使用者介面。

我們不斷致力於擴展配置、增加指標和優化。

加入該項目。 該項目結果很酷,但不幸的是,它仍然是一個單人項目。 來到 GitHub上 並嘗試做某事:提交、測試、提出建議、給予評估。

同時我們正在準備 聖高負載++,將於 6 月 7 日至 XNUMX 日在聖彼得堡舉行,我們邀請高負載系統的開發人員 申請報告。 經驗豐富的演講者已經知道該怎麼做,但對於那些剛開始演講的人,我們至少建議 試試。 作為演講者參加會議有很多好處。 例如,您可以在最後閱讀哪些內容 本文.

來源: www.habr.com

添加評論