linux安全模塊學習之LSM的介紹實現

相關背景介紹node

近年來Linux系統因爲其出色的性能和穩定性,開放源代碼特性帶來的靈活性和可擴展性,以及較低廉的成本,而受到計算機工業界的普遍關注和應用。linux

但在安全性方面,Linux內核只提供了經典的UNIX自主訪問控制(root用戶,用戶ID,模式位安全機制),以及部分的支持了POSIX.1e標準草案中的capabilities安全機制,這對於Linux系統的安全性是不足夠的,影響了Linux系統的進一步發展和更普遍的應用。安全

Linux安全模塊(LSM)是Linux內核的一個輕量級通用訪問控制框架。它使得各類不一樣的安全訪問控制模型可以以Linux可加載內核模塊的形式實現出來,用戶能夠根據其需求選擇適合的安全模塊加載到Linux內核中,從而大大提升了Linux安全訪問控制機制的靈活性和易用性。網絡

Linux安全模塊(LSM)的設計必須儘可能知足兩方面人的要求:讓不須要它的人儘量少的所以獲得麻煩;同時讓須要它的人所以獲得有用和高效的功能。數據結構

以Linus Torvalds爲表明的內核開發人員對Linux安全模塊(LSM)提出了三點要求:
• 真正的通用,當使用一個不一樣的安全模型的時候,只須要加載一個不一樣的內核模塊
• 概念上簡單,對Linux內核影響最小,高效,
• 可以支持現存的POSIX.1e capabilities邏輯,做爲一個可選的安全模塊
框架

另外一方面,各類不一樣的Linux安全加強系統對Linux安全模塊(LSM)提出的要求是:可以容許他們以可加載內核模塊的形式從新實現其安全功能,而且不會在安全性方面帶來明顯的損失,也不會帶來額外的系統開銷。socket

爲了知足這些設計目標,Linux安全模塊(LSM)採用了經過在內核源代碼中放置鉤子的方法,來仲裁對內核內部對象進行的訪問,這些對象有:任務,inode結點,打開的文件等等。函數

用戶進程執行系統調用,首先遊歷Linux內核原有的邏輯找到並分配資源,進行錯誤檢查,並通過經典的UNIX自主訪問控制,剛好就在Linux內核試圖對內部對象進行訪問以前,一個Linux安全模塊(LSM)的鉤子對安全模塊所必須提供的函數進行一個調用,從而對安全模塊提出這樣的問題」是否容許訪問執行?」,安全模塊根據其安全策略進行決策,做出回答:容許,或者拒絕進而返回一個錯誤。性能

Linux安全模塊(LSM)如今主要支持」限制型」的訪問控制決策:當Linux內核給予訪問權限時,Linux安全模塊(LSM)可能會拒絕,而當Linux內核拒絕訪問時,就直接跳過Linux安全模塊(LSM);而對於相反的」容許型」的訪問控制決策只提供了少許的支持。開放源代碼

對於模塊功能合成,Linux安全模塊(LSM)容許模塊堆棧,可是把主要的工做留給了模塊自身:由第一個加載的模塊進行模塊功能合成的最終決策。

實現方法介紹:對Linux內核的修改

Linux安全模塊(LSM)目前做爲一個Linux內核補丁的形式實現。其自己不提供任何具體的安全策略,而是提供了一個通用的基礎體系給安全模塊,由安全模塊來實現具體的安全策略。其主要在五個方面對Linux內核進行了修改: 

• 在特定的內核數據結構中加入了安全域
• 在內核源代碼中不一樣的關鍵點插入了對安全鉤子函數的調用
• 加入了一個通用的安全系統調用
• 提供了函數容許內核模塊註冊爲安全模塊或者註銷
• 將capabilities邏輯的大部分移植爲一個可選的安全模塊

對這五個方面的修改的簡要介紹

安全域是一個void*類型的指針,它使得安全模塊把安全信息和內核內部對象聯繫起來。下面列出被修改加入了安全域的內核數據結構,以及各自所表明的內核內部對象:

• task_struct結構:表明任務(進程)
• linux_binprm結構:表明程序
• super_block結構:表明文件系統
• inode結構:表明管道,文件,或者Socket套接字
• file結構:表明打開的文件

• sk_buff結構:表明網絡緩衝區(包)
• net_device結構:表明網絡設備
• kern_ipc_perm結構:表明Semaphore信號,共享內存段,或者消息隊列
• msg_msg:表明單個的消息

   另外,msg_msg結構,msg_queue結構,shmid_kernel結構被移到include/linux/msg.h和include/linux/shm.h這兩個頭文件中,使得安全模塊可使用這些定義。

Linux安全模塊(LSM)提供了兩類對安全鉤子函數的調用:一類管理內核對象的安全域,另外一類仲裁對這些內核對象的訪問。

對安全鉤子函數的調用經過鉤子來實現,鉤子是全局表security_ops中的函數指針,這個全局表的類型是security_operations結構,這個結構定義在include/linux/security.h這個頭文件中。

這個結構中包含了按照內核對象或內核子系統分組的鉤子組成的子結構,以及一些用於系統操做的頂層鉤子。在內核源代碼中很容易找到對鉤子函數的調用:其前綴是security_ops->。

Linux安全模塊(LSM)提供了一個通用的安全系統調用,容許安全模塊爲安全相關的應用編寫新的系統調用,其風格相似於原有的Linux系統調用socketcall(),是一個多路的系統調用。

這個系統調用爲security(),其參數爲(unsigned int id, unsigned int call, unsigned long *args),其中id表明模塊描述符,call表明調用描述符,args表明參數列表。

這個系統調用提供了一個sys_security()入口函數:其簡單的以參數調用sys_security()鉤子函數。

若是安全模塊不提供新的系統調用,就能夠定義返回-ENOSYS的sys_security()鉤子函數,可是大多數安全模塊均可以本身定義這個系統調用的實現。

在內核引導的過程當中,Linux安全模塊(LSM)框架被初始化爲一系列的虛擬鉤子函數,以實現傳統的UNIX超級用戶機制。

當加載一個安全模塊時,必須使用register_security()函數向Linux安全模塊(LSM)框架註冊這個安全模塊:這個函數將設置全局表security_ops,使其指向這個安全模塊的鉤子函數指針,從而使內核向這個安全模塊詢問訪問控制決策。

一旦一個安全模塊被加載,就成爲系統的安全策略決策中心,而不會被後面的register_security()函數覆蓋,直到這個安全模塊被使用unregister_security()函數向框架註銷:這簡單的將鉤子函數替換爲缺省值,系統回到UNIX超級用戶機制。

另外,Linux安全模塊(LSM)框架還提供了函數mod_reg_security()和函數mod_unreg_security(),使其後的安全模塊能夠向已經第一個註冊的主模塊註冊和註銷,但其策略實現由主模塊決定:是提供某種策略來實現模塊堆棧從而支持模塊功能合成,仍是簡單的返回錯誤值以忽略其後的安全模塊。這些函數都提供在內核源代碼文件security/security.c中。

Linux內核如今對POSIX.1e capabilities的一個子集提供支持Linux安全模塊(LSM)設計的一個需求就是把這個功能移植爲一個可選的安全模塊。POSIX.1e capabilities提供了劃分傳統超級用戶特權並賦給特定的進程的功能。

Linux安全模塊(LSM)保留了用來在內核中執行capability檢查的現存的capable()接口,但把capable()函數簡化爲一個Linux安全模塊(LSM)鉤子函數的包裝,從而容許在安全模塊中實現任何須要的邏輯。

Linux安全模塊(LSM)還保留了task_struck結構中的進程capability集(一個簡單的位向量),而並無把它移到安全域中去。Linux內核對capabilities的支持還包括兩個系統調用:capset()和capget()。

Linux安全模塊(LSM)一樣保留了這些系統調用但將其替換爲對鉤子函數的調用,使其基本上能夠經過security()系統調用來從新實現。

Linux安全模塊(LSM)已經開發而且移植了至關部分的capabilities邏輯到一個capabilities安全模塊中,但內核中仍然保留了不少原有capabilities的殘餘。

這些實現方法都最大程度的減小了對Linux內核的修改影響,而且最大程度保留了對原有使用capabilities的應用程序的支持,同時知足了設計的功能需求。

之後要使capabilities模塊徹底獨立,剩下要作的主要步驟是:把位向量移到task_struct結構中合適的安全域中,以及從新定位系統調用接口。

相關文章
相關標籤/搜索