歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux基礎 >> 關於Linux

基於Linux路由的訪問控制

聲明之後不是有iptables了嗎實現原理圖示和查找代碼並行執行的含義balance的思想和藝術聲明
關於訪問控制,人民已經討論了很多的方案,但是千萬不要覺得某種方案是放之四海而皆准的,沒有這樣的東西!RBAC根本不適宏內核協議棧的操作系統(UNIX,Linux,and so on...我可能在之前的文章把它們弄反了,...),但是這並不是每個人民中的一員都知道,包括我自己!
       總之,數據包在內核協議棧的處理過程中一定要符合“快,爽”的風格,不能導致後續的數據包排隊,因為不同的數據包可能屬於不同的“業務邏輯”。你不能假設後面數據包所代表的業務邏輯會容忍前面數據包耽擱太多的時間,每人簽署任何協議,對於網絡設備而言,每一個數據包都是平等的,如果高級一點的設備,每一個數據流都是平等的,記住,設備是為轉發數據而生,數據的目的地並不是此設備!
       所有的中間設備都TMD是浮雲,一個所謂的WEB加速服務器如果不是利用了cache,那它就是騙局!有什麼能和線速轉發更快的呢?沒有!CAO TMD的沒有!只要Client和Server中間有一台設備,那它就TMD增加了延遲,別指望它能減少延遲,除非上帝便秘!因此,我們在設計中間設備的時候,目標絕對不是神話般的減少延遲,而是“在你能控制的范圍內盡可能的快”,所以,應用程序的那種處理方式就不合適了,別指望用什麼庫可以提高效率,記住,最終的控制權永遠在運營商手中,永遠在那些不懂編程的網管手中,隨便一個人剪斷網線,再怎麼TCP也不能保證你能優雅的發送FIN,誰能控制網絡才能決定一切,網絡的效率永遠比端到端的程序的效率更重要!
       本文的目的在於,你能通過一種方式,盡可能保證本地的處理,不考慮別的。在周六的一天的大雨中,激動,悸動!我不屑於網管嘴裡的種種術語,也不怕編程,對於網管和程序員,也許奧托.馮.俾斯麥只能說,哀其不幸,怒其不爭!
       我雖然不懂OpenSSL,但是我是程序員!

之後
前面的一篇文章《Linux路由表的抽象擴展應用於nf_conntrack》中指出了可以用Linux的IP路由機制來實現訪問控制列表,即Linux的ACL,在那篇文章中,只是說明了實現的可行性,然而最終,我卻使用Linux的IP路由機制為任意的nf_conntrack保存了一個info字符串而已。本文來具體描述一下如何真的實現訪問控制。

不是有iptables了嗎
為何還要實現一套新的機制?因為:
1.iptables基於Netfilter實現,因此只能實現串行過濾,即一條一條的匹配;
2.匹配速度依賴於iptables規則的配置順序,無法在內核實現統一的優化處理;
3.我不喜歡iptables,它在多核時代已經過時了,雖然可以基於Netfilter開發一個並行版本,但是太難。
因此,為了解決上面的問題,我決定實現一套另外的不依賴Netfilter的訪問控制機制。很顯然,我的目標之一就是在匹配的過程中,多個核心可以被調度起來。

實現原理
實現一套針對IP數據報的訪問控制機制並不是簡單的事情,然而最基本的框架卻是很簡單,那就是基於一個數據包的源IP地址和目標IP地址來決定這個數據包可以做什麼。當然,除了IP地址之外,IP數據報文中的任意一個字段都可以參與匹配,甚至TCP/UDP協議頭的字段也可以參與匹配,是的,但是本文不涉及那種復雜的情況,那些都很容易從本文的思想中擴展出來,因此本文僅僅將IP地址作為匹配要素。
       如《Linux路由表的抽象擴展應用於nf_conntrack》所述,一個Action可以保存在一個路由項當中,但是如果引入另外一個匹配元素目標IP的時候,這個Action將不能再存在於路由項當中了,它將作為源IP地址關聯的路由項和目標IP地址關聯的路由項之間的媒介,指示“該源路由項包含的所有IP地址可以對該目標路由項包含的所有IP地址實施Action”。Action可以是通過,拒絕,地址轉換等所有可能的動作。如果不存在一個Action在兩個路由項之間關聯,則執行默認Action。可想而知,一個Action必須身兼兩職,一方面它加入源路由項的Action鏈表,另一方面它加入目標路由項的Action鏈表中以關聯二者。借用RBAC權限模型的術語,我可以把一個數據包的源IP地址看成是角色,而其訪問的目標IP地址則可以被看作是資源,這裡只是借用一下術語,真正的RBAC要比我這個復雜得多。一會兒我會說,我這個模型著眼在內核實現ACL的方式以及算法,而不是ACL模型本身。
       數據結構要比圖示更直接。由於每一個Action都會同時被鏈接到兩個鏈表,因此一個Action命名為Xnode即可:

[plain] view plaincopyprint?01.struct nf_action_node { 
02.        //struct list_head        list;   // 和算法相關,見注解1 
03.        struct hlist_node       nf_dst; 
04.        struct hlist_node       nf_src; 
05.        struct nf_fib_node      *dst_node; //反向指針,算法優化,見查找算法小節 
06.        struct nf_fib_node      *src_node; //反向指針,算法優化,見查找算法小節 
07.        int extra; 
08.        //int extra_len; 
09.        //char extra[0]; 
10.}; 
struct nf_action_node {
        //struct list_head        list;   // 和算法相關,見注解1
        struct hlist_node       nf_dst;

Copyright © Linux教程網 All Rights Reserved