日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

selinux学习

發(fā)布時間:2023/12/15 综合教程 24 生活家
生活随笔 收集整理的這篇文章主要介紹了 selinux学习 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、基本概念

1、TE模型的安全上下文

所有的操作系統(tǒng)訪問控制都基于主體、客體,以及與他們相關(guān)的訪問控制屬性。

在selinux中,訪問控制屬性叫做安全上下文。所有對象(文件、進(jìn)程間通信通道、套接字、網(wǎng)絡(luò)主機等)和主體(進(jìn)程)都有一個與之關(guān)聯(lián)的安全上下文。

一個安全上下文包含三個元素:用戶(user)、角色(role)和類型標(biāo)識符(type identifiers)

安全上下文的形式如下:user:role:type

對進(jìn)程來說:分別表示用戶、角色、類型標(biāo)識符也被稱為域

對客體來說:前兩項基本沒有實際用途,role通常為object_r,user通常位創(chuàng)建這個對象的進(jìn)程的user,對訪問控制沒有影響

顯示安全上下文

加上-Z能顯示主體、客體的上下文

ls -Z能顯示文件系統(tǒng)的安全上下文

ps -Z能顯示進(jìn)程的安全上下文

id -Z能顯示shell的安全上下文:joe:usr_r:usr_t

2、TE訪問控制

在SELinux中,默認(rèn)時沒有允許規(guī)則的,也沒有超級用戶。被允許的訪問必須由規(guī)則給出。

一條規(guī)則如下:

allow Source type(s) Target type(s): Object class(es) Permission(s)

比如這樣的訪問規(guī)則:

allow user_t bin_t : file {read execute getattr};

表示允許域為user_t的進(jìn)程對type為bin_t的文件具有讀、執(zhí)行、得到屬性的操作

3、角色的作用

SELinux也提供基于角色的訪問控制

通過以下語句指定role的type:

role user_r type passwd_t;

如果沒有以上這條語句,則:

安全上下文joe:user_r:passwd_t則不能被創(chuàng)建
exec調(diào)用則失敗,即便策略允許

二、架構(gòu)

1、內(nèi)核架構(gòu)

基于LSM(linux security module),為所有的內(nèi)核的資源提供強制訪問控制

LSM提供了一系列的鉤子函數(shù)

如果訪問被DAC拒絕,則會影響審計結(jié)果

SELinux的架構(gòu)如下所示:

策略決定包含在安全服務(wù)器中,與具體架構(gòu)無關(guān),便于移植

對象管理者時各對象的管理者,在LSM架構(gòu)中,是一系列的LSM鉤子,遍布在內(nèi)核的子系統(tǒng)中。

2、用戶空間的對象管理器

SELinux支持將對象管理器放到用戶態(tài),使用內(nèi)核的對象管理策略服務(wù)器來管理用戶態(tài)的對象

然而,支持用戶空間的對象管理器有一些弱點:

對于TE模型,還需要定義class
對于對象管理器的管理策略不再內(nèi)核之中

策略服務(wù)架構(gòu)如下:

AVC表示各種緩存

三、class

SELinux的客體除了有type,還有class,進(jìn)一步對客體的類型進(jìn)行劃分

SELinux中幾個常用的客體類別(class),及其權(quán)限

file:read、write、execute、getattr、create
dir:read、write、search、rmdir
process:signal、transition(域的轉(zhuǎn)換)、fork、getattr
socket:bind、listen、connect、accept
filesystem:mount、unmount

四、TE策略

在TE模型中,主體通常是正在運行的進(jìn)程,而不是用戶。客體可以是文件、進(jìn)程、socket等。

TE模型定義了一系列的規(guī)則來表示訪問是否允許,如果沒有規(guī)則,則所有的訪問都是不被允許的。

TE規(guī)則主要分為兩大類:access vector(AV)和type rules,AV允許審計,而type rules決定控制策略

1、類型(type)、屬性(attributes)、別名(aliases)

type:在selinux中,將對資源的訪問抽象為主體對客體的訪問,主體分為多個type,也叫做域,客體也分為多個type,每個type里還能更加細(xì)分出class,selinux的訪問規(guī)則就是基于type建立的規(guī)則,所以叫TE模型。

attributes:用來引用一組具有相同標(biāo)識符的一組類型

alases:對于策略而言,別名標(biāo)準(zhǔn)符和類型標(biāo)識符是一致的

一個type申明語句的格式如下,中括號中代表的是可選項:

type type_name [alias alias_set] [, attribute_set]

例子:typehttpd_user_content_t ,file_type

例子:

舉一個例子說明屬性的作用

假設(shè)現(xiàn)在新建了一個type為backup_t:

type backup_t;

需要對backup_t賦予所有文件的讀權(quán)限,如果系統(tǒng)中有shadow_t文件和httpd_user_content_t類型的文件,那么需要以下兩條的規(guī)則來賦予文件讀權(quán)限

allow backup_thttpd_user_content_t :file read

allowbackup_t shadow_t:file read

假設(shè)現(xiàn)在多了一個類型的文件,那么就需要重新為backup_t新增一條規(guī)則,這樣不僅麻煩而且錯誤率很高

現(xiàn)在有了一個屬性file_type

attribute file_type;

然后將所有具有file_type屬性的文件的讀權(quán)限賦予backup_t

allow backup_t file_type:file read;

這樣,以后每次有新的文件type出現(xiàn),只需要將新文件的type域file_type屬性關(guān)聯(lián)起來就行,backup_t會自動獲得讀權(quán)限

以上的例子簡單說明了屬性的使用,一個type可以關(guān)聯(lián)到多個屬性,將type和attribute關(guān)聯(lián)起來可以使用typeattribute,格式為:

typeattribute type_name attrib_name

別名用來保證兼容性,使用typealias來關(guān)聯(lián),格式如下:

typealias type_name alias alias_names;

2、AV(access rules)規(guī)則

AV規(guī)則有四類

allow:允許兩個類型之間的具體訪問

dontaudit:指定不記錄拒絕訪問的信息

auditallow:允許事件被記錄

neverallow:指定規(guī)則永遠(yuǎn)不會被賦予訪問權(quán)限

alow規(guī)則

格式:

allow source_type target_type :objectclass{permission}

例子:

allow user_d bin_t : file{read、execute、getattr}

允許user_d域的進(jìn)程對bin_t類型的普通文件進(jìn)行讀、寫、取屬性操作

AV規(guī)則通用語法

所有的AV規(guī)則的語法都同于上述的allow規(guī)則

在AV規(guī)則中使用屬性

以allow的例子為例,定義了file_type的屬性之后,可以將規(guī)則寫為:

allow user_d file_type: file{read、execute、getattr}

如果定義了主體的的type,則規(guī)則可以寫為:

allow domain file_type: file{read、execute、getattr}

多個type和attribute

如果有多個type和attribute存在,則可以用括號表示多個,并且type的attribute可以混用

allow {domain user_t} {file_type bin_t}: file{read、execute、getattr}

self

規(guī)則中可以出現(xiàn)self字樣,以下兩條規(guī)則等價

allow user_t user_t : process signal;

allow user_tself: process signal;

類型否定

類型否定用來在一系列的type中減去某個type,比如以下規(guī)則從exec_type中減去sbin_t

allow domain (exec_type -sbin_t): file{read、execute、getattr}

class的權(quán)限

allow user_tbin_t: {file dir} {read getattr}

等價于:

allow user_tbin_t: file {read getattr}

allow user_tbin_t: dir {read getattr}

通配符

allow user_tbin_t: dir *

表示賦予所有權(quán)限

取反操作符

allow user_tbin_t: file ~{read getattr}

表示除了read和getattr之外的權(quán)限全部賦予

審計規(guī)則

默認(rèn)情況下,允許的訪問時不被記錄的,而不允許的訪問會被記錄下,比如以下的兩個指令

dontaudit:指定不記錄拒絕訪問的信息

auditallow:允許事件被記錄

從不允許

neverallow:指定規(guī)則永遠(yuǎn)不會被賦予訪問權(quán)限

3、策略規(guī)則

策略規(guī)則中有兩類

type_transition:

type_change:

通用規(guī)則語義

rule_name  source_type  target_type  object_class  defult_type

例子:

type_transition user_t passwd_exec_t : process passwd_t;

以上規(guī)則表示,當(dāng)一個user_t域的進(jìn)程執(zhí)行類型為passwd_exec_t的文件時,進(jìn)程的type默認(rèn)轉(zhuǎn)移到passwd_t

注意:在以上的語法中,處了default_type不能使用集合,其他都能使用集合

type轉(zhuǎn)移

進(jìn)程在fork的時候繼承父進(jìn)程的type,而文件在在創(chuàng)建時繼承自容器的type,例如目錄

假設(shè)有如下規(guī)則:

type_transition user_t passwd_exec_t : process passwd_t;‘

在上述例子中,defult_type就是默認(rèn)要轉(zhuǎn)移的type

但是需要完成一個完整的轉(zhuǎn)移不僅僅需要上述的一條規(guī)則,總共需要3條。’

例子:

type為init_t的進(jìn)程fork一個子進(jìn)程,然后執(zhí)行type為appache_exec_t的文件,同時進(jìn)程的域需要轉(zhuǎn)移到apache_t

一共需要3條規(guī)則

1、原域必須對目標(biāo)類型有執(zhí)行權(quán)限(init_t對appache_exec_t有執(zhí)行權(quán)限)

2、原域必須對目標(biāo)域有轉(zhuǎn)移權(quán)限(init_t對apache_t有轉(zhuǎn)移權(quán)限)

3、目標(biāo)域必須對目標(biāo)文件類型有entrypoint權(quán)限(apache_t對appache_exec_t有entrypoint權(quán)限)

object轉(zhuǎn)移

type_transition passwd_t tmp_t : file passwd_tmp_t;

以上例子表示當(dāng)一個passwd_t進(jìn)程在tmp_t 目錄下創(chuàng)建一個文件時,文件的類型為passwd_tmp_t

需要的規(guī)則包括

1、tmp_t的增加名字,寫,搜索權(quán)限

2、passwd_tmp_t的寫和創(chuàng)建權(quán)限

type改變,type_change

type改變時用來指明重新執(zhí)行時的默認(rèn)類型,像type_transition一樣,指明默認(rèn)但是不允許,

type_change sysadm_t tty_device_t : chr_file sysadm_tty_device_t;

這個type_change規(guī)則聲明,當(dāng)代表sysadm_t重新標(biāo)記tty_device_t類型的字符文件時,應(yīng)該使用sysadm_tty_device_t類型。

這個規(guī)則是type_change規(guī)則最常用的一個例子,即在用戶登錄時重新標(biāo)記終端設(shè)備。

登錄程序?qū)⑼ㄟ^SELinux模塊的內(nèi)核接口查詢策略,傳入類型sysadm_t和tty_device_t,并接收類型sysadm_tty_device_t作為用于relabel更改的類型。

這種機制允許登錄過程在新的登錄會話期間代表用戶對tty設(shè)備進(jìn)行標(biāo)記,同時將類型的細(xì)節(jié)封裝在策略中,而不是硬編碼在應(yīng)用程序中。

五、用戶和角色

SELinux中的角色和用戶是其RBAC特性的基礎(chǔ)。大多數(shù)其他主流操作系統(tǒng)的安全特性主要集中于授予用戶訪問權(quán)限,或者直接授予用戶訪問權(quán)限,或者通過某種形式的組或角色機制授予用戶訪問權(quán)限。在SELinux中,通過TE allow規(guī)則將訪問權(quán)限授予類型。

角色充當(dāng)類型強制的支持特性,并與用戶一起提供一種方法,將基于類型的訪問控制與Linux用戶及其允許運行的程序綁定在一起。SELinux中的RBAC通過定義域類型和用戶之間的關(guān)系來控制Linux用戶的特權(quán)和訪問權(quán)限,從而進(jìn)一步限制了類型強制。

Linux和SELinux有不同的用戶標(biāo)識符,有時是相關(guān)的。Linux用戶是指/etc/passwd中定義的用戶帳戶SELinux用戶是指安全上下文中在SELinux策略中定義的用戶標(biāo)識符。

通過將域類型與一個或多個角色關(guān)聯(lián),我們間接地向用戶授予特權(quán)。RBAC策略語句不授予訪問權(quán)限。相反,RBAC通過控制安全上下文中域類型、角色和用戶的關(guān)聯(lián)來進(jìn)一步約束TE策略SELinux 沒有直接給“用戶”授權(quán)。SELinux的安全策略定義了一個用戶可以跟哪些角色關(guān)聯(lián)一個角色可以跟哪些域類型關(guān)聯(lián)

最終定義了一個用戶可以跟哪些域類型關(guān)聯(lián),用戶關(guān)聯(lián)的域類型才可以執(zhí)行該域類型的程序,才具有該域類型的權(quán)限。一個用戶要執(zhí)行一個可執(zhí)行程序時,會產(chǎn)生域切換;SELinux控制一個角色可以切換到哪些角色;SELinux控制角色與域類型的關(guān)聯(lián)進(jìn)而控制角色可以可以運行的程序角色的切換和角色與域類型的關(guān)聯(lián)控制了用戶的權(quán)限。

域從域類型為user_t的bash shell進(jìn)程轉(zhuǎn)換為運行域類型為passwd_t的密碼程序的進(jìn)程。我們?yōu)榱鞒贪踩舷挛奶砑恿擞脩艉徒巧糠值陌踩舷挛膉oe: user_r: user_t joe: user_r: passwd_t

這個例子演示了兩種RBAC策略語句:一個用戶聲明語句(user)和兩個角色聲明語句(role)。用戶語句“user joe roles {user_r}”將SELinux用戶joe與角色user_r關(guān)聯(lián)起來。該語句告訴SELinux,允許用戶joe和角色user_r在安全上下文中共存。如果沒有這條語句,圖中的user joe和role user_r進(jìn)程安全上下文將無效,SELinux將拒絕創(chuàng)建它們,從而拒絕域轉(zhuǎn)換嘗試。

這兩個角色語句將角色user_r與域類型user_t和passwd_t關(guān)聯(lián)起來。要使流程安全上下文有效,角色語句是必需的。如果沒有關(guān)聯(lián)類型passwd_t的role語句,即使TE策略允許,這個域轉(zhuǎn)換也會失敗。如果我們不希望user_r角色運行密碼程序,那么只需刪除這個角色語句,即使TE規(guī)則允許訪問,內(nèi)核也永遠(yuǎn)不會創(chuàng)建安全上下文。

1、role語句

除了object_r之外,SELinux沒有任何內(nèi)置角色。與類型一樣,角色也是在策略中聲明的,并通過一致的使用賦予其意義。

role有四個相關(guān)聯(lián)的語句:

1、role聲明語句

2、role允許語句

3、role轉(zhuǎn)移語句

4、role支配語句

角色聲明語句

格式為:

role role_name [types type_set];

角色聲明語句聲明角色標(biāo)識符并將類型與角色關(guān)聯(lián)起來。類型必須與角色關(guān)聯(lián),以便與角色在安全上下文中共存。給定角色標(biāo)識符的第一個角色語句除了關(guān)聯(lián)列出的類型外,還將聲明該角色。所有后續(xù)角色語句都關(guān)聯(lián)其他類型。單個角色的多個角色語句通常用于將角色語句放置在與其關(guān)聯(lián)的類型的聲明附近

角色允許語句

格式為:

allow role_set role_set;

SELinux提供了一種通過execve()系統(tǒng)調(diào)用在程序執(zhí)行期間更改角色的方法。這個特性在本質(zhì)上類似于域轉(zhuǎn)換,這會導(dǎo)致域類型的更改。角色允許規(guī)則(allow)通過指定允許哪些角色更改為其他角色來控制在程序執(zhí)行時可能發(fā)生的角色更改。

角色轉(zhuǎn)移規(guī)則

因為角色可以在程序執(zhí)行時以類似于類型的方式進(jìn)行更改,所以我們需要一種方法在策略語言中自動完成這種轉(zhuǎn)換。對于類型,我們使用type_transition規(guī)則來指定自動的默認(rèn)類型轉(zhuǎn)換。對于角色,我們有角色轉(zhuǎn)換規(guī)則(role_transition)。這個規(guī)則在目的和語法上與type_transition規(guī)則類似,只是它指定了在執(zhí)行文件時發(fā)生的默認(rèn)角色更改。

格式為:

role_transition role_set type_set role;

例子:

role_transition sysadm_r http_exec_t system_r;

此規(guī)則聲明,除非另有要求,否則當(dāng)角色為sysadm_r的進(jìn)程執(zhí)行類型為http_exec_t的文件時,SELinux應(yīng)該嘗試將角色更改為system_r。

角色支配語句

格式為:
dominance { role role_name { role_set} }

角色優(yōu)勢語句指定角色之間的層次關(guān)系。角色繼承它們所控制的角色的所有類型關(guān)聯(lián)。

表單角色“role_name”中指定的一個或多個角色;使用空格分隔的列表指定多個角色(例如,{role staff_r;sysadm_r作用;})

例子:

dominance { role a_r { role b_r; role c_r { role d_r; } } }

d_r關(guān)聯(lián)的角色只有它自己的類型

c_r它的類型和d_r的類型

d_r關(guān)聯(lián)的角色只有它自己的類型

a_r它自己的類型以及b_r、c_r和d_r中的所有類型

2、用戶和用戶語句

Linux和SELinux用戶標(biāo)識符是不同的,通常是不相關(guān)的。在SELinux中,Linux用戶標(biāo)識符和給定進(jìn)程的SELinux用戶標(biāo)識符可能不同。SELinux使用不同的用戶標(biāo)識符(而不是共享Linux的標(biāo)識符)的設(shè)計決策的動機是希望創(chuàng)建不可變的SELinux用戶標(biāo)識符。在標(biāo)準(zhǔn)Linux中,用戶標(biāo)識符的變化反映權(quán)限的變化(例如,更改為root)。在許多情況下,實際的和有效的用戶標(biāo)識符都會發(fā)生變化。這使得跟蹤哪個用戶登錄進(jìn)行審計、身份驗證和其他使用變得困難。分離Linux和SELinux用戶標(biāo)識符允許Linux用戶標(biāo)識符在不影響SELinux的情況下根據(jù)需要進(jìn)行更改。

user聲明語句(user)在策略中聲明一個用戶標(biāo)識符,并將其與一個或多個角色關(guān)聯(lián)。user語句是與SELinux用戶相關(guān)的惟一策略語句。用戶語句必須在所有類型和角色語句之后以及約束之前

格式如下:

user user_name roles role_set;

假設(shè)有如下規(guī)則:

user joe roles { user_r };

如果策略中尚未聲明用戶joe,則該語句聲明該用戶joe,并將角色user_r與該用戶關(guān)聯(lián)起來。

將SELinux的用戶和linux用戶關(guān)聯(lián)

登錄程序(例如,login, sshd)負(fù)責(zé)將Linux用戶映射到SELinux用戶。登錄時,如果有一個與Linux用戶標(biāo)識符完全相同的SELinux用戶標(biāo)識符,則匹配的SELinux用戶標(biāo)識符將成為初始shell進(jìn)程的安全上下文中的用戶標(biāo)識符。

在許多情況下,不希望在策略中定義每個普通用戶。對于SELinux(即user_r角色和user_t初始用戶域類型),普通用戶通常具有相同的特權(quán)。為了解決這個問題,SELinux有一個特殊的用戶標(biāo)識user_u,稱為泛型用戶。如果策略中定義了通用用戶user_u,那么如果策略中沒有匹配的SELinux用戶,那么所有Linux用戶都將映射到它。

對于語句:

user user_u roles { user_r };

這個語句定義了通用用戶user_u,并將其授權(quán)給角色user_r,就像我們前面為joe所做的那樣。

如果在策略中定義user_u,則將策略中未顯式定義的所有Linux用戶映射到user_u。例如,如果jane是一個Linux用戶標(biāo)識符,但是SELinux策略中沒有定義用戶jane,那么當(dāng)Linux用戶jane登錄時,初始shell進(jìn)程安全上下文中的用戶標(biāo)識符將是user_u。因為joe是在策略中定義的,所以該用戶的初始SELinux用戶標(biāo)識符將是joe,即使user_u也是在策略中定義的。

如果在策略中沒有定義泛型用戶user_u,那么在SELinux策略中沒有顯式定義的任何Linux用戶標(biāo)識符都將無法登錄,即使在許可模式下也是如此。

登錄時,初始shell進(jìn)程必須具有有效的安全上下文,包括用戶標(biāo)識符。如果策略中既沒有定義user_u,也沒有定義Linux用戶標(biāo)識符,則登錄過程無法創(chuàng)建有效的安全上下文(因為沒有用戶標(biāo)識符可供使用)。因此,如果您的策略中沒有包含user_u(這對于許多配置是有意義的),那么您必須顯式地將所有Linux用戶添加到SELinux策略中。

SELinux還有第二個特殊用戶,系統(tǒng)用戶system_u,它通常用于init等所有系統(tǒng)進(jìn)程,以及由init啟動的守護(hù)進(jìn)程。從技術(shù)上講,用戶system_u沒有特殊含義,在策略語言中沒有以任何方式進(jìn)行異常處理。但是,大多數(shù)現(xiàn)有的策略都包含這個用戶,并且系統(tǒng)通常在配置時希望這個SELinux用戶用于系統(tǒng)資源。通常,在策略中始終包含system_u是一個好主意

永遠(yuǎn)不要使用標(biāo)識符system_u創(chuàng)建Linux用戶帳戶。如果這樣做,該Linux用戶將能夠使用系統(tǒng)用戶標(biāo)識符登錄,系統(tǒng)用戶標(biāo)識符通常具有很高的特權(quán)(盡管仍然比普通Linux系統(tǒng)上的root權(quán)限小得多)。

六、約束

SELinux提供了一種約束機制來進(jìn)一步限制策略允許的訪問,而不管策略允許規(guī)則是什么。

為了理解約束的目的,讓我們重新看看SELinux Linux安全模塊(LSM)。

我們希望進(jìn)一步了解訪問決策邏輯在安全服務(wù)器中的工作方式。訪問向量緩存(AVC)由源安全標(biāo)識符(SID)、目標(biāo)SID和對象類三部分組成。SID是安全上下文的內(nèi)部參考

1、安全上下文和SID

SELinux實現(xiàn)了Flask安全體系結(jié)構(gòu),該體系結(jié)構(gòu)提供了實現(xiàn)增強訪問控制的框架,但仍然保持安全策略中立。這意味著AVC及其與LSM掛鉤的接口沒有專門綁定到類型強制(TE)和SELinux實現(xiàn)的其他安全策略。就AVC而言,安全標(biāo)識符是對一組安全憑據(jù)的不透明惟一引用。AVC緩存由源和目標(biāo)sid以及對象類標(biāo)識符索引決定。

SELinux安全服務(wù)器在內(nèi)部將安全上下文與SIDs聯(lián)系起來,因此,SELinux可以使用sid查找類型、用戶和角色標(biāo)識符,而AVC和LSM鉤子接口可以忽略這些細(xì)節(jié)。當(dāng)SELinux LSM鉤子請求訪問決策時,它們提供主題(源)和對象(目標(biāo))以及對象類的sid。AVC使用SID-SID-class三元組查找被允許的訪問,該訪問被存儲為位掩碼。當(dāng)緩存丟失發(fā)生時,AVC調(diào)用安全服務(wù)器函數(shù)security_compute_av()來確定允許的訪問。

該函數(shù)的訪問決策邏輯有兩個基本步驟:

1)為type-type-class三元組創(chuàng)建一個表示根據(jù)TE allow規(guī)則允許的對象權(quán)限的掩碼;

2)從允許掩碼中刪除任何約束不允許的權(quán)限。

第二個步驟允許將約束作為限制策略所允許的權(quán)限的一種方法。因此,正如您所看到的,約束進(jìn)一步限制了SELinux策略中允許的訪問。
SELinux有兩種類型的約束。
constraint語句是最常見的約束,允許您根據(jù)源和目標(biāo)安全上下文的用戶、角色和/或類型進(jìn)一步限制訪問。validatetrans語句是SELinux中最新添加的,它使您能夠基于舊的、新的和流程安全上下文進(jìn)一步限制對安全上下文更改事件的訪問。

2、約束語句

約束語句有三個元素:約束應(yīng)用到的對象類的集合、被約束類的權(quán)限集和約束的布爾表達(dá)式。約束由對象類組織并存儲在策略中。constraint語句允許您根據(jù)源和目標(biāo)安全上下文之間的關(guān)系定義約束,從而限制指定對象類的指定權(quán)限。約束語句的完整語法如下所示:

constrain class_set perm_set expression ;

class_set一個或多個對象類。

perm_set一個或多個權(quán)限。所有權(quán)限必須對

class_set中的所有對象類有效。表達(dá)式約束的布爾表達(dá)式。

布爾表達(dá)式語法支持以下關(guān)鍵字:

t1, r1, u1 Source type, role, and user
t2, r2, u2 Target type, role, and user

約束表達(dá)式語法還支持以下操作符:

= =集合成員的或等價的

=設(shè)置不屬于或不等于

eq (Role關(guān)鍵字)的等價

dom (Role關(guān)鍵字)支配由

incomp (Role關(guān)鍵字)支配的

domby (Role關(guān)鍵字)不可比較

例子:

constrain process transition (u1 == u2) ;

首先,注意它只應(yīng)用于流程對象類,并且只限制流程的轉(zhuǎn)換權(quán)限。回想一下,允許域轉(zhuǎn)換需要轉(zhuǎn)換權(quán)限;實際上,這個約束進(jìn)一步限制了域轉(zhuǎn)換。現(xiàn)在讓我們看看約束表達(dá)式(u1 == u2)。我們看到,它要求所有域轉(zhuǎn)換的源用戶標(biāo)識符和目標(biāo)用戶標(biāo)識符保持相同。allow rule 限制了域類型的切換; constrain 進(jìn)一步限制 process類型在域切換時:安全上下文中的用戶不能改變。

回想一下前面對訪問算法的描述。當(dāng)流程請求轉(zhuǎn)換權(quán)限時,AVC調(diào)用安全服務(wù)器以確定允許對三重源目標(biāo)類的訪問時,前面的約束將變得有效(對于流程對象類),并將檢查源和目標(biāo)安全上下文中的用戶標(biāo)識符。如果用戶標(biāo)識符不相同,則在將授予的訪問掩碼返回AVC之前,掩碼中表示轉(zhuǎn)換權(quán)限的位將被刪除。constraint語句允許您對安全上下文的三個元素(用戶、角色和類型)的任意組合表示約束。約束表達(dá)式將源(主題)流程和目標(biāo)(對象)的上下文相互比較,并/或使用顯式名稱(例如類型或角色標(biāo)識符)進(jìn)行比較。

例子:

constrain process transition (r1 == r2) ;

這個約束類似于前面的語句,只是它約束的是角色標(biāo)識符而不是用戶標(biāo)識符。關(guān)鍵字r1和r2分別表示源角色標(biāo)識符和目標(biāo)角色標(biāo)識符。這個約束要求角色標(biāo)識符不能在域轉(zhuǎn)換上更改。

因為這兩個約束與相同的對象類和權(quán)限相關(guān),約束表達(dá)式語法允許我們將它們組合成一個布爾表達(dá)式:

constrain process transition (u1 == u2 and r1 == r2) ;

讓我們進(jìn)一步看看我們的例子。在某些情況下,我們希望允許在域轉(zhuǎn)換上更改用戶和/或角色標(biāo)識符。例如,登錄過程需要將用戶和角色標(biāo)識符更改為登錄用戶的標(biāo)識符。登錄的SC:system_u:system_r:local_login_t當(dāng)前SC:user_u:user_r:user_t。另一個例子是允許您更改角色的程序,該程序必須能夠在域轉(zhuǎn)換期間更改角色標(biāo)識符。一般來說,這些程序是受信任的進(jìn)程,我們需要一種方法來允許它們更改用戶/角色標(biāo)識符,同時確保約束對所有其他程序都是活動的。為了實現(xiàn)這個目標(biāo),讓我們首先定義一種方法來識別那些受信任可以更改用戶和角色標(biāo)識符的域類型。特別地,讓我們假設(shè)策略中定義了兩個屬性:privuser和privrole。前者與允許更改用戶標(biāo)識符的所有類型相關(guān)聯(lián),后者與允許更改角色標(biāo)識符的類型相關(guān)聯(lián)。通過這些屬性,我們可以改變約束如下:

constrain process transition (u1 == u2 or t1 == privuser) ;
constrain process transition (r1 == r2 or t1 == privrole) ;

在這兩個語句中,t1都表示源類型。第一個語句只允許在源類型具有privuser屬性的情況下在域轉(zhuǎn)換中更改用戶標(biāo)識符。同樣,如果源類型具有privrole屬性,則可以更改角色

對于約束表達(dá)式,所有操作符的左側(cè)必須是允許的關(guān)鍵字之一(例如,u1或u2),并且可能永遠(yuǎn)不是類型、屬性、角色或用戶標(biāo)識符(或標(biāo)識符列表)。運算符的右側(cè)可以是一個關(guān)鍵字或一個或多個標(biāo)識符名稱。

3、標(biāo)簽轉(zhuǎn)換約束

SELinux支持第二條約束語句validatetrans。該語句是作為修改后的多級安全特性的一部分添加的,我們將在下一章中進(jìn)行討論。通過validatetrans語句,我們可以進(jìn)一步控制更改受支持對象的安全上下文的能力。

與constraint語句不同,validatetrans語句允許您將對象的新舊安全上下文相互關(guān)聯(lián),并/或與第三個安全上下文(試圖重新標(biāo)記對象的進(jìn)程的安全上下文)關(guān)聯(lián)起來。因此,為該語句添加了新的關(guān)鍵字,特別是t3、r3和u3,分別表示流程安全上下文的類型、角色和用戶。*1關(guān)鍵字表示舊的安全上下文,*2關(guān)鍵字表示新的安全上下文

注意不要混淆約束和validatetrans語句之間的關(guān)鍵字關(guān)聯(lián)。對于約束語句,t1表示源(或調(diào)用流程)類型,t2表示目標(biāo)(對象)類型。然而,在validatetrans語句中,t3現(xiàn)在是源流程類型,t1是“舊”類型,t2是“新”類型。

validatetrans語句通過與新舊安全上下文和流程的安全上下文定義基于約束的關(guān)系來限制更改指定受支持對象的安全上下文的能力。validatetrans語句的完整語法如下:

validatetrans class_set expression ;

布爾表達(dá)式語法支持以下關(guān)鍵字:

t1, r1, u1 Old type, role, and user
t2, r2, u2 New type, role, and user
t3, r3, u3 Process type, role, and user

約束表達(dá)式語法還支持以下操作符:

==集合成員的或等價的

=設(shè)置不屬于或不等于

eq(僅限Role關(guān)鍵字)的等價

dom(僅限Role關(guān)鍵字)支配

domby(僅限Role關(guān)鍵字)不受支配

incomp(僅限Role關(guān)鍵字)不可比較

假設(shè)我們有一個user_tmp_t類型,在我們的策略中,我們將其用作普通不受信任用戶程序的臨時文件的類型。我們可能希望確保具有更改所有文件標(biāo)簽權(quán)限的域不會意外地將user_tmp_t作為其類型的文件重新標(biāo)記為某些非常關(guān)鍵的類型(輸入shadow_t類型,這是/etc/shadow文件的類型)。這是我們的約束條件它提供了這樣的約束:

validatetrans {file lnk_file} ( t2 != shadow_t or t1 != user_tmp_t );

注意這個約束的幾個特性。我們同時包含普通文件和符號鏈接(lnk_file),因為我們不希望有人使用鏈接代替文件。該約束表示,要允許文件和符號鏈接對象更改安全上下文,只有在舊類型不是user_tmp_t的情況下,新類型才可能是shadow_t。如果舊類型是user_tmp_t,則新類型可能不是shadow_t。換句話說,任何域類型都不能被授權(quán)將用戶臨時文件重新標(biāo)記為影子密碼文件的類型。

要擴展這個示例,假設(shè)有一個域類型子集,我們希望允許它將user_tmp_t重新標(biāo)記為shadow_t。現(xiàn)在,我們創(chuàng)建一個屬性relabel_any,并將其分配給我們希望授予此特權(quán)的那些域類型。

validatetrans {file lnk_file}
(
  ( t3 == relabel_any) or
  ( t2 != shadow_t or t1 != user_tmp_t )
);

七、多級安全

在最近對SELinux的增強中,約束特性得到了擴展,以實現(xiàn)可選的多級安全(MLS)策略。MLS是另一種形式的強制訪問控制,它構(gòu)建在類型強制(TE)之上。在本章中,我們將探討可選的MLS策略特性。MLS是另一種強制訪問控制形式,適用于一些安全問題,特別是與政府機密數(shù)據(jù)控制相關(guān)的安全問題。在SELinux中,MLS是類型強制的可選擴展;沒有它,MLS特性就無法實現(xiàn)。

7.1 安全上下文和多級安全

啟用MLS時,將使用兩個附加字段擴展安全上下文:低安全級別和高安全級別。安全級別本身有兩個字段:敏感(sensitivity)性和一組類別(categories)。敏感性是嚴(yán)格分層的,反映了一個有序的數(shù)據(jù)敏感性模型,如政府分類控制中的絕密、機密和非機密。類別是無序的,反映了數(shù)據(jù)劃分的需要。基本思想是,您既需要足夠高的靈敏度間隙,又需要正確的類別來訪問數(shù)據(jù)。

不要混淆安全級別和敏感性。安全級別是單個敏感性和一組(零或多個)類別的組合。安全級別不是分層的,使用優(yōu)勢關(guān)系(dom、domby、eq、incomp)進(jìn)行比較

7.2 定義安全等級

使用靈敏度語句定義靈敏度,如下所示:

sensitivity s0;
sensitivity s1;
sensitivity s2;
sensitivity s3;

這些名稱是SELinux中典型的通用敏感命名約定。

敏感性語句還支持將附加別名與敏感性關(guān)聯(lián)的能力,敏感性將被視為與核心敏感性名稱相同的名稱。例如:

sensitivity s1 alias unclassified;

這些名稱是SELinux中典型的通用敏感命名約定。

由于敏感性必須是層次性相關(guān)的,我們必須在政策中使用支配性語句指定敏感性的層次性,如下所示:

dominance { s0 s1 s2 s3 }

優(yōu)勢語句按照從低到高的順序列出敏感性名稱。因此,在我們的例子中,s0小于s1, s1小于s2,以此類推。

類別的定義類似于使用類別語句定義敏感性。類別也可以有別名。下列語句是類別語句的例子:

category c0 alias blue;
category c1 alias red;
category c2 alias green;
category c3 alias orange;
category c4 alias white;

在策略語言中定義安全級別的最后一步是使用level語句定義允許的安全級別組合。level語句規(guī)定了如何將類別與敏感性聯(lián)系起來。請記住,單個敏感性和一組類別的組合構(gòu)成一個安全級別。下面是level語句的一些例子:

level s0:c0.c4;
level s1:c0.c4;
level s2:c0.c4;
level s3:c0.c4;

例子:
level s0:c0.c2;
level s1:c0.c2,c4;

在本例中,s0可能只與類別c0、c1和c2相關(guān)聯(lián);s1有c0 c1 c2 c4(但不是c3)現(xiàn)在,您應(yīng)該已經(jīng)注意到,點(.)表示類別的一個包含范圍,逗號(,)表示類別的一個非連續(xù)列表。level語句定義了哪些敏感性和類別的組合構(gòu)成SELinux策略中MLS部分可接受的安全級別

僅僅因為類別的范圍是使用范圍運算符(.)指定的,這并不意味著類別是分層相關(guān)的。相反,range操作符只是一種方便地引用一組類別的方法。范圍操作符的類別順序只是聲明它們的順序,與它們的名稱隱含的任何內(nèi)在順序無關(guān)。

7.3 安全上下文的MLS拓展

格式如下:

user:role:type:sensitivity[:category,...][ - sensitivity[:category,...]]

對于MLS SELinux系統(tǒng),安全上下文被擴展為包括兩個安全級別:低級別或當(dāng)前安全級別和高級別或清除安全級別。通常,低級別反映了流程的當(dāng)前安全級別或?qū)ο笾邪臄?shù)據(jù)的敏感性。高級別反映上下文中用戶標(biāo)識符的清除級別(從而確定任何安全上下文的當(dāng)前級別所允許的最高安全級別)或某些所謂的多級別對象所允許的最大數(shù)據(jù)范圍。

要使安全上下文有效,高級別必須始終控制低級別。此外,與敏感性相關(guān)的類別必須根據(jù)策略中的級別聲明有效。

例子:

level s0:c0.c2;
level s1:c0.c2,c4;

user_u、user_r和user_t是有效的用戶、角色和類型標(biāo)識符,以下安全上下文無效:

user_u:user_r:user_t:s0 -s0:c2,c4 (c4 is invalid for s0)
user_u:user_r:user_t:s0:c0 -s0:c2 (high does not dominate the low)

八、條件策略

這里,我們將探討通過策略語句創(chuàng)建的條件策略,這些策略允許我們根據(jù)環(huán)境定義啟用或禁用的規(guī)則。

8.1 概述

條件策略語句使我們能夠定義僅在條件表達(dá)式定義的情況下啟用的策略規(guī)則集,條件表達(dá)式是使用定義的變量和邏輯運算符構(gòu)造的邏輯表達(dá)式。讓我們看一個虛構(gòu)的例子。

假設(shè)我們有一臺移動計算機,并且希望定義策略規(guī)則,使其能夠訪問特定程序的域類型(例如,myprog_t),以便在計算機停靠時僅訪問有線以太網(wǎng)網(wǎng)絡(luò)接口,在計算機未停靠時僅訪問無線網(wǎng)絡(luò)接口。

為了達(dá)到這個目的,我們可以寫一個條件句,如:

bool docked true;
if (docked) {
  # rules to allow my_prog_t access to wired Ethernet device
} else {
  # rules to allow my_prog_t access to wireless device
}

我們所要做的就是在停靠/取消停靠設(shè)備時更改布爾值(例如,正在運行的服務(wù)可能會監(jiān)視此狀態(tài)并相應(yīng)地設(shè)置布爾值),以啟用適當(dāng)?shù)牟呗砸?guī)則集。

8.2 布爾變量

編寫條件策略的第一步是創(chuàng)建布爾變量。例如,假設(shè)我們想要配置策略,以便普通用戶使用ping程序的能力能夠被打開和關(guān)閉。我們需要定義一個布爾變量user_ping,我們將在條件表達(dá)式中使用它。

bool user_ping false;

我們使用bool語句來定義布爾變量。bool語句有兩個參數(shù),布爾值(user_ping)的名稱及其默認(rèn)值,可以為真,也可以為假。在這種情況下,默認(rèn)值(false)意味著普通用戶在默認(rèn)情況下不能使用ping,bool語句定義了條件布爾值及其默認(rèn)值。

bool bool_name default_value;

內(nèi)核通過selinux偽文件系統(tǒng)公開布爾值。這個偽文件系統(tǒng)是用戶空間和內(nèi)核中的SELinux Linux安全模塊(LSM)之間的主要接口。文件系統(tǒng)通常安裝在/selinux/上。當(dāng)前策略中定義的所有布爾變量將顯示為這個偽文件系統(tǒng)的布爾目錄中的文件。例如,您可以將上面定義的布爾值看作一個路徑名為/selinux/ boolies /user_ping的文件。

在運行的系統(tǒng)中更改布爾變量值的能力使我們能夠更改條件表達(dá)式的值,從而提供條件策略。因此,SELinux內(nèi)核必須使布爾變量可用于運行更改的進(jìn)程。這與策略的任何其他組件不同,后者一旦加載到內(nèi)核中,在加載新的整個策略之前都是靜態(tài)的。布爾值在運行的系統(tǒng)上可以單獨訪問和更改。

我們使用selinux文件系統(tǒng)中的布爾文件來查詢和設(shè)置布爾變量的當(dāng)前值。如果您查看布爾文件的內(nèi)容,您總是會看到一對數(shù)字(0或1表示false或true),如下所示:

# cat /selinux/booleans/user_ping
1 1

第一個數(shù)字表示布爾變量的當(dāng)前值;在這種情況下,1為真。第二個數(shù)字表示布爾變量的掛起值。當(dāng)前值是內(nèi)核用于布爾值和確定條件表達(dá)式值的實際值。掛起是布爾值的當(dāng)前值在提交布爾值更改時將被更改的值。我們通過更改布爾的掛起值,然后將更改提交給內(nèi)核,來更改布爾的當(dāng)前值。

我們通過向布爾文件寫入1或0來更改掛起的值,如下所示:

# cat /selinux/booleans/user_ping
1 1
# echo 0 > /selinux/booleans/user_ping
# cat /selinux/booleans/user_ping
1 0

掛起的值現(xiàn)在變?yōu)?,當(dāng)前值保持不變。這意味著,即使將布爾user_ping的掛起值更改為false(0),它的值仍然為true(1)。

原因是更改布爾值需要兩個步驟的提交過程。首先,更改想要更改的布爾值的掛起值,然后將掛起值提交到當(dāng)前值。這允許您更改多個布爾值,然后在一步中提交所有更改。文件/selinux/commit_pending_bools是將所有布爾值的掛起值提交為當(dāng)前值的接口。通過向該文件寫入1,可以實現(xiàn)提交,如下所示:

# echo 1 > /selinux/commit_pending_bools
# commit all pending values
# cat /selinux/booleans/user_ping
0 0

SELinux為查詢和更改布爾值提供了方便的命令,而無需記住它們的文件位置。getsebool命令將布爾值的狀態(tài)顯示為活動(TRue)或非活動(false)。例如:

# getsebool -a
docked > inactive
user_ping > active
...

我們還可以使用setsebool命令更改布爾值

# getsebool user_ping (* show current state *)
user_ping > active
# setsebool user_ping false (* change and commit current state*)
# getsebool user_ping (* show changed stated *)
user_ping > inactive

我們還可以使用setsebool命令,使用參數(shù)的另一種格式在一個事務(wù)中更改多個布爾值,如下所示:

# getsebool user_ping docked
user_ping > active
docked > inactive
# setsebool user_ping=0 docked=1
# getsebool user_ping docked
user_ping > inactive
docked > active

在策略文件中定義了布爾變量及其默認(rèn)狀態(tài)。在SELinux策略語言中包含布爾值之后,出現(xiàn)了一個問題,即如何在不重新創(chuàng)建策略的情況下更改布爾值的默認(rèn)狀態(tài)。因此引入了持久值的概念。SELinux實用程序使用的標(biāo)準(zhǔn)庫提供了一種方法,通過使用布爾值來維護(hù)文件,從而對布爾值進(jìn)行持久更改。init進(jìn)程使用此文件在系統(tǒng)初始化期間覆蓋策略默認(rèn)值。通過這種方式,我們可以更改在重新引導(dǎo)期間持續(xù)存在的布爾值的當(dāng)前值,而不必修改靜態(tài)SELinux策略。

8.3 條件語句

if (cond_expression)

{true_list}

[else {false_list}]

cond_expression

是一個條件表達(dá)式,由一個或多個布爾變量和邏輯運算符組成。表9-1列出了受支持的邏輯運算符。布爾變量必須使用bool語句定義。根據(jù)條件表達(dá)式的值有條件地啟用或禁用的規(guī)則列表。當(dāng)條件列表為真時,將啟用規(guī)則的真列表(禁用false)。反之亦然。false列表是可選的。

九、客體標(biāo)識

要使SELinux策略發(fā)揮作用,所有對象實例都必須使用安全上下文進(jìn)行標(biāo)記。在本節(jié)中,我們將討論將安全上下文應(yīng)用于對象實例的各種方法,包括在創(chuàng)建對象時如何分配安全上下文,以及稍后如何修改這些標(biāo)簽(稱為重標(biāo)號)。

9.1 基本含義

SELinux中的所有對象從創(chuàng)建到銷毀都有一個相關(guān)的安全上下文。此屬性對于SELinux執(zhí)行訪問控制的能力至關(guān)重要。讓我們看看文件/etc/shadow的安全上下文

# ls -Z /etc/shadow
-r------- root root system_u:object_r:shadow_t shadow

這個例子演示了為文件/etc/shadow顯示安全上下文的程序ls。與對象關(guān)聯(lián)的安全上下文(在本例中是system_u:object_r:shadow_t)是SELinux在訪問控制決策中使用的唯一屬性。從根本上說,這一點以及為所有對象分配正確的安全上下文非常重要。

SELinux策略語言包含一些特性,這些特性使標(biāo)記決策自動化并在很大程度上透明。文件和域轉(zhuǎn)換的類型轉(zhuǎn)換規(guī)則,有時,標(biāo)簽成為我們需要關(guān)注的問題。在系統(tǒng)管理、策略開發(fā)、系統(tǒng)安裝期間。作為政策制定者,我們必須仔細(xì)制定標(biāo)簽政策聲明,以便在運行時簡化標(biāo)簽管理。

對象在SELinux系統(tǒng)上的標(biāo)記有四種基本方式:

1、策略語句:SELinux策略語言包含一些特性,比如type_transition規(guī)則,它們?yōu)閷ο髽?biāo)記指定行為

2、硬編碼的默認(rèn):大多數(shù)對象類都在對象管理器中編碼了某種類型的默認(rèn)標(biāo)記行為。例如,默認(rèn)情況下,當(dāng)進(jìn)程創(chuàng)建新套接字時,新套接字具有與其創(chuàng)建進(jìn)程相同的安全上下文。

3、程序需要的標(biāo)記:對于一些對象類,SELinux提供了各種應(yīng)用程序編程接口(api),允許程序顯式地請求標(biāo)簽,包括新對象實例和現(xiàn)有對象實例

4、出事SID:SELinux有一組初始安全標(biāo)識符(初始sid),用于標(biāo)記一些對象,并在對象缺少或無效標(biāo)簽時用作故障安全標(biāo)簽

未完待續(xù)。。。

總結(jié)

以上是生活随笔為你收集整理的selinux学习的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。