如何加強 Linux 系統的安全性,第一部分: Linux 安全模塊(LSM)簡介

http://www.ibm.com/developerworks/cn/linux/l-lsm/part1/

1.相關背景介紹:爲何和是什麼

近年來Linux系統因爲其出色的性能和穩定性,開放源代碼特性帶來的靈活性和可擴展性,以及較低廉的成本,而受到計算機工業界的普遍關注和應用。但在安全性方面,Linux內核只提供了經典的UNIX自主訪問控制(root用戶,用戶ID,模式位安全機制),以及部分的支持了POSIX.1e標準草案中的capabilities安全機制,這對於Linux系統的安全性是不足夠的,影響了Linux系統的進一步發展和更普遍的應用。html

有不少安全訪問控制模型和框架已經被研究和開發出來,用以加強Linux系統的安全性,比較知名的有安全加強Linux(SELinux),域和類型加強(DTE),以及Linux入侵檢測系統(LIDS)等等。可是因爲沒有一個系統可以得到統治性的地位而進入Linux內核成爲標準;而且這些系統都大多以各類不一樣的內核補丁的形式提供,使用這些系統須要有編譯和定製內核的能力,對於沒有內核開發經驗的普通用戶,得到並使用這些系統是有難度的。在2001年的Linux內核峯會上,美國國家安全局(NSA)介紹了他們關於安全加強Linux(SELinux)的工做,這是一個靈活的訪問控制體系Flask在Linux中的實現,當時Linux內核的創始人Linus Torvalds贊成Linux內核確實須要一個通用的安全訪問控制框架,但他指出最好是經過可加載內核模塊的方法,這樣能夠支持現存的各類不一樣的安全訪問控制系統。所以,Linux安全模塊(LSM)應運而生。node

Linux安全模塊(LSM)是Linux內核的一個輕量級通用訪問控制框架。它使得各類不一樣的安全訪問控制模型可以以Linux可加載內核模塊的形式實現出來,用戶能夠根據其需求選擇適合的安全模塊加載到Linux內核中,從而大大提升了Linux安全訪問控制機制的靈活性和易用性。目前已經有不少著名的加強訪問控制系統移植到Linux安全模塊(LSM)上實現,包括POSIX.1e capabilities,安全加強Linux(SELinux),域和類型加強(DTE),以及Linux入侵檢測系統(LIDS)等等。雖然目前Linux安全模塊(LSM)仍然是做爲一個Linux內核補丁的形式提供,可是其同時提供Linux 2.4穩定版本的系列和Linux 2.5開發版本的系列,而且頗有但願進入Linux 2.6穩定版本,進而實現其目標:被Linux內核接受成爲Linux內核安全機制的標準,在各個Linux發行版中提供給用戶使用。linux

 

2.設計思想介紹:得讓兩方面都滿意

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

以Linus Torvalds爲表明的內核開發人員對Linux安全模塊(LSM)提出了三點要求:數據結構

  • 真正的通用,當使用一個不一樣的安全模型的時候,只須要加載一個不一樣的內核模塊
  • 概念上簡單,對Linux內核影響最小,高效,而且
  • 可以支持現存的POSIX.1e capabilities邏輯,做爲一個可選的安全模塊

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

爲了知足這些設計目標,Linux安全模塊(LSM)採用了經過在內核源代碼中放置鉤子的方法,來仲裁對內核內部對象進行的訪問,這些對象有:任務,inode結點,打開的文件等等。用戶進程執行系統調用,首先遊歷Linux內核原有的邏輯找到並分配資源,進行錯誤檢查,並通過經典的UNIX自主訪問控制,剛好就在Linux內核試圖對內部對象進行訪問以前,一個Linux安全模塊(LSM)的鉤子對安全模塊所必須提供的函數進行一個調用,從而對安全模塊提出這樣的問題"是否容許訪問執行?",安全模塊根據其安全策略進行決策,做出回答:容許,或者拒絕進而返回一個錯誤。socket

另外一方面,爲了知足大多數現存Linux安全加強系統的須要,Linux安全模塊(LSM)採起了簡化設計的決策。Linux安全模塊(LSM)如今主要支持大多數現存安全加強系統的核心功能:訪問控制;而對一些安全加強系統要求的其餘安全功能,好比安全審計,只提供了的少許的支持。Linux安全模塊(LSM)如今主要支持"限制型"的訪問控制決策:當Linux內核給予訪問權限時,Linux安全模塊(LSM)可能會拒絕,而當Linux內核拒絕訪問時,就直接跳過Linux安全模塊(LSM);而對於相反的"容許型"的訪問控制決策只提供了少許的支持。對於模塊功能合成,Linux安全模塊(LSM)容許模塊堆棧,可是把主要的工做留給了模塊自身:由第一個加載的模塊進行模塊功能合成的最終決策。全部這些設計決策可能暫時影響了Linux安全模塊(LSM)的功能和靈活性,可是大大下降了Linux安全模塊(LSM)實現的複雜性,減小了對Linux內核的修改和影響,使得其進入Linux內核成爲安全機制標準的可能性大大提升;等成爲標準後,能夠改變決策,增長功能和靈活性。函數

 

3.實現方法介紹:對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結構中合適的安全域中,以及從新定位系統調用接口。

 

4.接口說明:給內核開發人員和安全研究人員使用的鉤子

Linux安全模塊(LSM)對於內核開發人員和安全研究人員的價值就在於:可使用其提供的接口將現存的安全加強系統移植到這一框架上,從而可以以可加載內核模塊的形式提供給用戶使用;或者甚至能夠直接編寫適合本身須要的安全模塊。Linux安全模塊(LSM)提供的接口就是鉤子,其初始化時所指向的虛擬函數實現了缺省的傳統UNIX超級用戶機制,模塊編寫者必須從新實現這些鉤子函數來知足本身的安全策略。下面簡要介紹Linux安全模塊(LSM)提供的鉤子,詳細狀況請參考源代碼,特別是include/linux/security.h頭文件中security_operations結構的定義。至於具體如何根據本身須要的安全策略編寫安全模塊,能夠參考SELinux,DTE,LIDS等系統的安全模塊實現。

首先是任務鉤子,Linux安全模塊(LSM)提供了一系列的任務鉤子使得安全模塊能夠管理進程的安全信息而且控制進程的操做。模塊可使用task_struct結構中的安全域來維護進程安全信息;任務鉤子提供了控制進程間通訊的鉤子,例如kill();還提供了控制對當前進程進行特權操做的鉤子,例如setuid();還提供了對資源管理操做進行細粒度控制的鉤子,例如setrlimit()和nice()。

其次是程序裝載鉤子。不少安全模塊,包括Linux capabilities,SELinux,DTE都須要有在一個新程序執行時改變特權的能力。所以Linux安全模塊(LSM)提供了一系列程序裝載鉤子,用在一個execve()操做執行過程的關鍵點上。linux_binprm結構中的安全域容許安全模塊維護程序裝載過程當中的安全信息;提供了鉤子用於容許安全模塊在裝載程序前初始化安全信息和執行訪問控制;還提供了鉤子容許模塊在新程序成功裝載後更新任務的安全信息;還提供了鉤子用來控制程序執行過程當中的狀態繼承,例如確認打開的文件描述符。

再次是進程間通訊IPC鉤子。安全模塊可使用進程間通訊IPC鉤子來對System V IPC的安全信息進行管理,以及執行訪問控制。IPC對象數據結構共享一個子結構kern_ipc_perm,而且這個子結構中只有一個指針傳給現存的ipcperms()函數進行權限檢查,所以Linux安全模塊(LSM)在這個共享子結構中加入了一個安全域。爲了支持單個消息的安全信息,Linux安全模塊(LSM)還在msg_msg結構中加入了一個安全域。Linux安全模塊(LSM)在現存的ipcperms()函數中插入了一個鉤子,使得安全模塊能夠對每一個現存的Linux IPC權限執行檢查。因爲對於某些安全模塊,這樣的檢查是不足夠的,Linux安全模塊(LSM)也在單個的IPC操做中插入了鉤子。另外還有鉤子支持對經過System V消息隊列發送的單個消息進行細粒度的訪問控制。

下面是文件系統鉤子。對於文件操做,定義了三種鉤子:文件系統鉤子,inode結點鉤子,以及文件鉤子。Linux安全模塊(LSM)在對應的三個內核數據結構中加入了安全域,分別是:super_block結構,inode結構,file結構。超級塊文件系統鉤子使得安全模塊可以控制對整個文件系統進行的操做,例如掛載,卸載,還有statfs()。Linux安全模塊(LSM)在permission()函數中插入了鉤子,從而保留了這個函數,可是也提供了不少其餘inode結點鉤子來對單個inode結點操做進行細粒度訪問控制。文件鉤子中的一些容許安全模塊對read()和write()這樣的文件操做進行額外的檢查;還有文件鉤子容許安全模塊控制經過socket IPC接收打開文件描述符;其餘的文件鉤子對像fcntl()和ioctl()這樣的操做提供細粒度訪問控制。

接下來是網絡鉤子。對網絡的應用層訪問使用一系列的socket套接字鉤子來進行仲裁,這些鉤子基本覆蓋了全部基於socket套接字的協議。因爲每一個激活的用戶socket套接字有伴隨有一個inode結構,因此在socket結構或是更底層的sock結構中都沒有加入安全域。socket套接字鉤子對有關進程的網絡訪問提供了一個通用的仲裁,從而顯著擴展了內核的網絡訪問控制框架(這在網絡層是已經由Linux內核防火牆netfilter進行處理的)。例如sock_rcv_skb鉤子容許在進入內核的包排隊到相應的用戶空間socket套接字以前,按照其目的應用來對其進行仲裁。另外Linux安全模塊(LSM)也爲IPv4,UNIX域,以及Netlink協議實現了細粒度的鉤子,之後還可能實現其餘協議的鉤子。網絡數據以包的形式被封裝在sk_buff結構(socket套接字緩衝區)中游歷協議棧,Linux安全模塊(LSM)在sk_buff結構中加入了一個安全域,使得可以在包的層次上對經過網絡層的數據的安全信息進行管理,並提供了一系列的sk_buff鉤子用於維護這個安全域的整個生命週期。硬件和軟件網絡設備被封裝在一個net_device結構中,一個安全域被加到這個結構中,使得可以在設備的層次上維護安全信息。

最後是其餘的鉤子。Linux安全模塊(LSM)提供了兩種其餘系列的鉤子:模塊鉤子和頂層的系統鉤子。模塊鉤子用來控制建立,初始化,清除內核模塊的內核操做。系統鉤子用來控制系統操做,例如設置主機名,訪問I/O端口,以及配置進程記賬。雖然如今的Linux內核經過使用capability檢查對這些系統操做提供了一些支持,可是這些檢查對於不一樣操做差異很大而且沒有提供任何參數信息。

 

5.模塊說明:給普通用戶使用的現成的安全功能

Linux安全模塊(LSM)對於普通用戶的價值就在於:能夠提供各類安全模塊,由用戶選擇適合本身須要加載到內核,知足特定的安全功能。Linux安全模塊(LSM)自己只提供加強訪問控制策略的機制,而由各個安全模塊實現具體特定的安全策略。下面簡要介紹一些已經實現的安全模塊。

SELinux。這是一個Flask靈活訪問控制體系在Linux上的實現,而且提供了類型加強,基於角色的訪問控制,以及可選的多級安全策略。SELinux原來是做爲一個內核補丁實現的,如今已經使用Linux安全模塊(LSM)從新實現爲一個安全模塊。SELinux能夠被用來限制進程爲最小特權,保護進程和數據的完整性和機密性,而且支持應用安全需求。

DTE Linux。這是一個域和類型加強在Linux上的實現。就像SELinux同樣,DTE Linux原來是做爲一個內核補丁實現的,如今已經使用Linux安全模塊(LSM)從新實現爲一個安全模塊。當這個安全模塊被加載到內核上時,類型被賦給對象,域被賦給進程。DTE策略限制域之間和從域到類型的訪問。

Openwall 內核補丁的LSM移植。Openwall內核補丁提供了一系列的安全特性集合來保護系統免受例如緩衝區溢出和臨時文件競爭這樣的攻擊。有安全模塊正在被開發出來以支持Openwall補丁的一個子集。

POSIX.1e capabilities。Linux內核中已經存在有POSIX.1e capabilities邏輯,可是Linux安全模塊(LSM)把這個邏輯劃分到了一個安全模塊中。這樣的修改使得不須要的用戶能夠從他們的內核中把這個功能略去;也使得capabilities邏輯的開發能夠脫離內核開發得到更大的獨立性。

LIDS。這是中國人謝華剛發起的項目。開始時做爲一個入侵檢測系統開發,後來逐漸演變爲使用訪問控制系統的形式來進行入侵預防,它經過描述一個給定的程序能夠訪問哪些文件來進行訪問控制。一樣的,LIDS原來是做爲一個內核補丁實現的並附帶了一些管理工具,如今已經使用Linux安全模塊(LSM)從新實現爲一個安全模塊。

固然還有缺省的傳統超級用戶機制。這個安全模塊是Linux安全模塊(LSM)缺省的,實現了傳統的UNIX超級用戶特權機制。

 

6.具體使用方法說明:step by step

Linux安全模塊(LSM)目前做爲一個Linux內核補丁的形式實現,在GPL許可證下發布供用戶自由使用。

首先用戶能夠在http://lsm.immunix.org/lsm_download.html下載到對應於Linux 2.4穩定版本和Linux 2.5開發版本的LSM補丁,放在某個目錄下,例如是目錄/path/to/linux-2.4.x,經過執行下面的命令來使LSM補丁做用在Linux內核上:

# cd /path/to/linux-2.4.x
# zcat /path/to/patch-2.4.x-lsm.gz | patch -p1

而後用戶能夠在http://lsm.immunix.org/lsm_modules.html鏈接到已經實現安全模塊的站點,下載到所須要的安全模塊,將安全模塊加載到Linux內核中,這樣用戶須要的安全策略就能夠起做用了,從而加強了系統的安全性。具體安全模塊的安裝方法這裏就略過了,各個安全模塊都會提供詳細的安裝說明文件,用戶能夠參考這些文件,例如SELinux的安全模塊安裝說明文件在:http://www.nsa.gov/selinux/doc/readme.html,又如LIDS的安全模塊安裝說明文件在:http://www.lids.org/install.html。

若是用戶有Linux內核和安全的相關背景知識和開發經驗,想根據本身須要的安全策略編寫安全模塊。能夠在http://lsm.immunix.org/lsm_bk.html跟蹤查看Linux安全模塊(LSM)的源代碼和現有安全模塊的源代碼,參考其實現方法編寫本身的安全模塊。這樣在知足本身安全需求的同時,也能夠爲Linux安全模塊(LSM)的發展做出一些貢獻,使其早日被Linux內核接受成爲Linux內核安全機制的標準,使更多的用戶得益。

 

7.結束語:將來的標準

Linux安全模塊(LSM)的原由是:一方面Linux內核現有的安全機制是不足夠的;另外一方面現存的安全加強系統又各自爲戰而且難以使用。Linux安全模塊(LSM)比較好的解決了這個問題:一方面補丁比較小,對內核源代碼的修改影響很少,所帶來的負載也不大;另外一方面對現存的安全加強系統提供了比較好的接口支持,並已經有很多很好的安全模塊可使用。Linux安全模塊(LSM)目前仍然是做爲一個Linux內核補丁的形式提供,可是其同時提供Linux 2.4穩定版本的系列和Linux 2.5開發版本的系列,而且頗有但願進入Linux 2.6穩定版本。咱們期待着那一天:Linux安全模塊(LSM)被Linux內核接受成爲Linux內核安全機制的標準,在各個Linux發行版中提供給愈來愈多的用戶使用。

相關文章
相關標籤/搜索