linux鉤子
⑴ 想實現一個linux內核安全功能模塊的技術思路是怎樣的
作者:橘子-實現網
鏈接:https://www.hu.com/question/21637060/answer/58362892
來源:知乎
著作權歸作者所有,轉載請聯系作者獲得授權。
用戶在執行系統調用時,先通過原有的內核介面依次執行慧卜雹功能性的錯誤檢查,接著進行傳統的DAC檢查,並在即將訪問內核的內部對象之前,通過LSM鉤子函數調用LSM。LSM再調用具體的訪問控制策略來決定訪問的合法性。訪問控制整體構架:<img src="https://pic2.mg.com/_b.jpg" data-rawwidth="804" data-rawheight="604" class="origin_image zh-lightbox-thumb" width="804" data-original="https://pic2.mg.com/_r.jpg">
LSM框架下訪問決策模塊包括selinux,smack,tomoyo,yama,apparmor.
每個決策模塊都是通過各自的XXX_init函數調用register_security()函數,注冊到LSM框架的模塊被載入成功後,就可以進行訪問控制操作。如果此時還有一個安全模塊要使用register_security()函數進行載入,則會出現錯誤,直到使用框架注銷後,下一個模塊才可以載入。<img src="https://pic2.mg.com/_b.jpg" data-rawwidth="420" data-rawheight="285" class="content_image" width="420">
Linux安全模塊(LSM)提供了兩類對安全鉤子函數的調用:一類管理內核對象的安全域,另一類仲裁對這些內核對象的訪問。對安全鉤子函數的調用通過鉤子來實現,鉤子是全局表security_ops中的函數指針,這個全局表的類型是security_operations結構,這個結構定義在include/linux/security.h這個頭文件中。
通過對security代碼進行一番簡單的分析,LSM啟動過程流圖:
<img src="https://pic2.mg.com/_b.jpg" data-rawwidth="1011" data-rawheight="213" class="origin_image zh-lightbox-thumb" width="1011"弊知 data-original="https://pic2.mg.com/_r.jpg">security_initcall只能調用selinux_init,smack_init ,tomoyo_init , yama_init 和apparmor_init中的一個,因為內核不允許多種安全機制同時一起工作。一旦一個安全模塊被載入,就成為系統的安全策略決策中心,而不會被後面的register_security()函數覆蓋,前帆直到這個安全模塊被使用unregister_security()函數向框架注銷。security_initcall只能調用selinux_init,smack_init ,tomoyo_init , yama_init 和apparmor_init中的一個,因為內核不允許多種安全機制同時一起工作。一旦一個安全模塊被載入,就成為系統的安全策略決策中心,而不會被後面的register_security()函數覆蓋,直到這個安全模塊被使用unregister_security()函數向框架注銷。
因此LSM框架下只能開啟一種安全機制,smack編譯進Linux內核的配置和要求:
(1)要求smack和selinux不能夠同時運行,不能同時存在於同一個運行中的內核;
查看內核是否開啟以下的功能(如果沒有則需要開啟):
CONFIG_NETLABEL=y
CONFIG_SECURITY=y
CONFIG_SECURITY_NETWORK=y
CONFIG_SECURITY_SMACK=y
CONFIG_SECURITY_SELINUX should not be
set
步驟:
make menuconfig
<img src="https://pic1.mg.com/_b.jpg" data-rawwidth="658" data-rawheight="461" class="origin_image zh-lightbox-thumb" width="658" data-original="https://pic1.mg.com/_r.jpg"><img src="https://pic3.mg.com/_b.jpg" data-rawwidth="658" data-rawheight="464" class="origin_image zh-lightbox-thumb" width="658" data-original="https://pic3.mg.com/_r.jpg"><img src="https://pic3.mg.com/_b.jpg" data-rawwidth="658" data-rawheight="468" class="origin_image zh-lightbox-thumb" width="658" data-original="https://pic3.mg.com/_r.jpg"><img src="https://pic4.mg.com/_b.jpg" data-rawwidth="662" data-rawheight="468" class="origin_image zh-lightbox-thumb" width="662" data-original="https://pic4.mg.com/_r.jpg">
make moles_install
make install
查看/proc/filesystems
可以看到smackfs,說明smack已經編進內核
<img src="https://pic2.mg.com/_b.jpg" data-rawwidth="146" data-rawheight="187" class="content_image" width="146">
執行如下的命令:
mkdir -p /smack
在文件/etc/fstab添加下面的一行
smackfs /smack smackfs defaults 0 0
然後執行下面的命令:
mount –a
然後就體驗一下它的功能了:
1. 比如在用戶test的home目錄下(/home/test),新建文件夾 mkdir testdir
cd testdir/
touch testfile
2. 給新建的testfile 打上TheOther標簽
setfattr
--name=security.SMACK64 --value=TheOther testfile
查看其標簽
getfattr
--only-values -n security.SMACK64 -e text testfile
可以看到標簽TheOther
<img src="https://pic3.mg.com/_b.jpg" data-rawwidth="698" data-rawheight="60" class="origin_image zh-lightbox-thumb" width="698" data-original="https://pic3.mg.com/_r.jpg">
3. echo TheOne
2>/dev/null > /proc/self/attr/current,當前執行的進程默認都會被打為/proc/self/attr/current下的標簽
4.配置策略echo -n "TheOne TheOther r---"> /sma ck/load
因為當前進程只要是沒有特殊配置過的都被打為TheOne,所以當轉換到普通用戶test下,cat testfile是可讀的
5.現在我將當前進程打為NotTheOne ,echo NotTheOne 2>/dev/null >
/proc/self/attr/current
當轉換到普通用戶test下,cat testfile則變成不可讀的了
6.如果你想單獨對某個進程打標簽,而不是對當前進程打,就
attr -s security.SMACK64 -V TheOne /bin/cat
此時cat被標為TheOne,根據策略可以看出,當轉換到普通用戶test下,cat testfile是可讀的
若attr -s
security.SMACK64 –V Not TheOne /bin/cat
根據策略可以看出,當轉換到普通用戶test下,cat testfile是不可讀的
(需要說明的一點是,當cat本身被標上標簽和/proc/self/attr/current打入標簽共存時,cat本身的標簽生效,而/proc/self/attr/current打入標簽沒有生效)
⑵ 基於Linux與ip6的多機互聯怎麼解決
IPv6運用AH和ESP對所傳輸的數據進行認證和加密,保證了數豎燃據的機密性、完整性和可靠性,實現了信息在傳輸過程的安全性。但IPv6並不能保障網路系統本身的安全及其提供的服務的可用性,也不能防止黑客的非法入侵和竊取私有數據。面對IPv6將要廣泛的應用,有必要將其和防火牆相結合來保障整個網路系統的安全。
目前Linux操作系統自2.2內核以來已提供對IPv6的支持,其性能穩定且安全性較高,因此本文以Linux為平台來研究設計針對IPv6的防火牆系統。
Linux內核對數據包的過濾處理
netfilter框架機制
netfilter是linux2.4內核以後實現數據包過濾處理的一個抽象的、通用化的功能框架,它提供了不同於BSD Socket介面的操作網路數據包的機制。在netfilter中,協議棧每種協議都定義了若干個鉤子(HOOK),而對應協議的數據包將按照一定的規則通過一些鉤子,每一個鉤子都是處畢纖蔽理函數掛載點。內核模塊可以在各個鉤子上注冊處理函數以操作經過對應鉤子的數據包。數據包經過所注冊的函數處理後,根據一定的策略返回給內核進行下一步的處理。
IPv6協議定義了五個鉤子:
(1)NF_IPv6_PRE_ROUTING:數據包在抵達路由之前經過這個鉤子。一般應用於防止拒絕服務攻擊和NAT。
(2)NF_IPv6_LOCAL_IN:目的地為本地主機的數據包經過這個鉤子,這個鉤子可以應用於防火牆。
(3)NF_IPv6_FORWARD:目的地非本地主機的數據包經過這個鉤子。
(4)NF_IPv6_POST_ROUTING:數據包在離開本地主機之前經過這個鉤子,包括源地址為本地主機和非本地主機的數據包。
(5)NF_IPv6_LOCAL_OUT:本地主機發出的數據包經過這個鉤子。這個鉤子可以應用於防火牆。
數據包從左邊進入系統,進行IP校驗以後,數據包經過第一個鉤子NF_IP6_PRE_ROUTING注冊函數進行處理,然後就進入路由代碼決定該數據包是需要轉發還是發給本機。若該數據包是發給本機的,則該數據經過鉤子NF_IP6_LOCAL_IN注冊函數的處理以後傳遞給上層協議。若該數據包應該被轉發則它被NF_IP6_FORWARD注冊函數處理。經過轉發的數據包經過最後一個鉤子NF_IP6_POST_ROUTING注冊函數的處理以後,再傳輸到網路上。本地產生的數據經過鉤子NF_IP6_LOCAL_OUT注冊函數處理以後,進行路由選擇處理,然後經過NF_IP6_POST_ROUTING注冊函數的處理以後發送到網路上。每個注冊函數處理完後,將返回一個整形常量,內核根據這個返回值來對數據包作下一步的處理,現在內核共定義了以下五個常量:
(1)NF_DROP表示丟棄此數據包,而不進入此後的處理;
(2)NF_ACCEPT表示接受此數據包,進入下一步的處理;
(3)NF_STOLEN表示異常分組;
(4)NF_QUEUE表示排隊到用戶空間,等待用戶處理;
(5)NF_REPEAT表示再次進入該鉤子函數作處理。
ip6tables數據包過濾系統
目前,基於Netfilter框架的、稱為ip6tables的IPv6數據包選擇系統在Linux2.4以上的內核中被應用,它可以讓用戶訪問內核過濾規則和命令。這種數據包選擇主要用於實現數據包過濾(filter表)、網路地址轉換(nat表)及數據包處理(mangle表)。Linux2.4內核提供的這三種數據包處理功能都基於Netfilter的鉤子函數和IP表。它們相互之手州間是獨立的模塊,但完美的集成到由Netfilter提供的框架中。
filter表格不對數據包進行修改,只對數據包進行過濾。它通過鉤子函數NF_IP6_LOCAL_IN、NF_IP6_FORWARD及NF_IP6_LOCAL_OUT接入Netfilter框架。NAT表格監聽三個Netfilter鉤子函數:
NF_IP6_PRE_ROUTING、NF_IP6_POST_ROUTING及NF_IP6_LOCAL_OUT,用於源NAT、目的NAT、偽裝(是源NAT的一個特例)及透明代理(是目的NAT的一個特例)。mangle表格在NF_IP6_PRE_ROUTING和NF_IP6_LOCAL_OUT鉤子中進行注冊。使用mangle表,可以實現對數據包的修改或給數據包附上一些額外數據。
ip6tables用戶命令基本上包含以下5部分:
(1)希望工作在哪個表(Filter、NAT、Mangle);
(2)希望使用⑴所指定的表的哪個鏈(INPUT、OUTPUT、FORWARD等);
(3)進行的操作(插入、添加、刪除、修改);
(4)對特定規則的目標動作;
(5)匹配數據包條件。ip6tables的語法為:
#ip6tables[-ttable] command [match] [target] [-ttable]有三種可用的表選項:filter、nat和mangle。該選項如果未指定,則filter用作預設表。filter表用於一般的信息包過濾,它包含INPUT、OUTPUT和FORWARD鏈。nat表用於要轉發的信息包,它包含PREROUTING、OUTPUT和POSTROUTING鏈。
PREROUTING鏈由指定信息包一到達防火牆就改變它們的規則所組成,而POSTROUTING鏈由指定正當信息包打算離開防火牆時改變它們的規則所組成。如果信息包及其頭內進行了任何更改,則使用mangle表。該表包含一些規則來標記用於高級路由的信息包,該表包含PREROUTING和OUTPUT鏈。
ip6tables的基本操作(command):-A表示在鏈尾添加一條規則,-I表示插入一條規則,-D表示刪除一條規則,-R表示替代一條規則,-L表示列出所有規則。
ip6tables基本目標動作(target)(適用於所有的鏈):ACCEPT表示接收該數據包,DROP表示丟棄該數據包,QUEUE表示排隊該數據包到用戶空間,RETURN表示返回到前面調用的鏈,FOOBAR表示用戶自定義鏈。
ip6tables基本匹配條件(match)(適用於所有的鏈):-p表示指定協議,-s表示源地址,-d表示目的地址,-i表示數據包輸入介面,-o表示數據包輸出介面。例如,識別IPv6的網路伺服器上的SSH連接時可以使用以下規則:
#ip6tables-AINPUT-ieth0-ptcp-s3ffe:ffff:100::1/128--dport22-jACCEPT
當然,還有其他對規則進行操作的命令,如清空鏈表,設置鏈預設策略,添加用戶自定義的鏈等,這里不再詳述。
INPUT、OUTPUT、FORWARD鏈是ip6tables內置的過濾鏈,每條鏈都可定義若干條過濾規則,構成了基本的ip6tables包過濾防火牆,
⑶ linux內核源碼中如何載入自己的鉤子函數
(但不總是)位於 /usr/src/linux-。我們不會研究得過於詳細,因為 Linux 源代碼經常會發生變化,但是,我們將嘗試讓給出的信息足以找出特定驅動程序或函數的位置。
Makefile:這個文件是整個源代碼樹的頂層 makefile。它定義了很多實用的變數和規則,比如默認的 gcc 編譯標記。
Documentation/:這個目錄中包含很多關於配置內核、運行 ramdisk 等任務的實用信息(但通常是過時的)。不過,與不同配置選項相應的幫助條目並不在這里 —— 它們在每個源代碼目錄的 Kconfig 文件中。
arch/:所有與體系結構相關的代碼都在這個目錄以及 include/asm- 目錄中。在此目錄中,每種體系結構都有自己的目錄。例如,用於基於 PowerPC 的計算機的代碼位於 arch/ppc 目錄中。在這些目錄里,可以找到底層內存管理、中斷處理、早期初始化、匯編常式,等等。
crypto/:這是內核本身所用的加密 API。
drivers/:按照慣例,在此目錄的子目錄中可以找到運行外圍設備的代碼。包括視頻驅動程序、網卡驅動程序、底層 SCSI 驅動程序,以及其他類似的驅動程序。例如,在 drivers/net 中可以找到大部分網卡驅動程序。將一類驅動程序組合在一起的某些更高層代碼,可能會(也可能不會)像底層驅動程序本身那些包含在同一目錄中。
fs/:通用文件系統的代碼(稱做 VFS,即 Virtual File System)和各個不同文件系統的代碼都可以在這個目錄中找到。ext2 文件系統是在 Linux 中最常廣泛使用的文件系統之一;在 fs/ext2 中可以找到讀取 ext2 格式的代碼。並不是所有文件系統都會編譯或運行;對某些尋找內核項目的人而言,更生僻的文件系統永遠都是理想的候選者。
include/:在 .c 文件的開頭所包含的大部分頭文件都可以在這個目錄中找到。 asm- 目錄下是與體系結構相關的包含(include )文件。部分內核構建過程創建從 asm 指定 asm- 的符號鏈接。這樣,無需將其固定編碼到 .c 文件 #include 就可以獲得用於那個體系結構的正確文件。其他目錄中包含的是 非-體系結構-相關 的頭文件。如果在不只一個 .c 文件中使用了某個結構體、常量或者變數,那麼它可能應該放入其中一個頭文件中。
init/:這個目錄中的文件包括 main.c、創建 早期用戶空間(early userspace) 的代碼,以及其他初始化代碼。可以認為 main.c 是內核「粘合劑(glue)」。在下一部分將深入討論 main.c。早期用戶空間提供了 Linux 內核引導起來時所需要的功能,而這些功能並不需要在內核本身運行。
ipc/:IPC 的意思是 進程間通信(interprocess communication)。它包含了共享內存、信號量以及其他形式 IPC 的代碼。
kernel/:不適合放在任何其他位置的通用內核級代碼位於此處。這里有高層系統調用代碼,以及 printk() 代碼、調度程序、信號處理代碼,等等。文件名包含很多信息,所以可以使用 ls kernel/,並非能常准確地猜到每個文件的功能。
lib/:這里是對所有內核代碼都通用的實用常式。常見的字元串操作、調試常式,以及命令行解析代碼都位於此處。
mm/:這個目錄中是高層次內核管理代碼。聯合使用這些常式以及底層的與體系結構相關的常式(通常位於 arch//mm/ 目錄中)來實現虛擬內存(Virtual memory,VM)。在這里會完成早期內存管理(在內存子系統完全建立起來之前需要它),以及文件的內存映射、頁高速緩存管理、內存分配、RAM 中頁的清除(還有很多其他事情)。
net/:這里是高層網路代碼。底層網路驅動程序與此層次代碼交換數據包,這個層次的代碼可以根據數據包將數據傳遞給用戶層應用程序,或者丟棄數據,或者在內核中使用它。net/core 包含大部分不同的網路協議都可以使用的代碼,和某些位於 net/ 目錄本身中的文件一樣。特定的網路協議在 net/ 的子目錄下實現。例如,在 net/ipv4 目錄中可以找到 IP(版本 4)代碼。
scripts/:這個目錄中包含的腳本可用於內核的構建,但並不將任何代碼加入到內核本身之中。例如,各種配置工具可以將它們的文件放在這里。
security/:在這里可以找到不同 Linux 安全模型的代碼,比如 NSA Security-Enhanced Linux 以及套接字和網路安全鉤子函數(hooks),以及其他安全選項。
sound/:這里放置的是音效卡驅動程序和其他與聲音相關的代碼。
usr/:此目錄中的代碼用於構建包含 root 文件系統映像的 cpio-格式 的歸檔文件,用於早期用戶空間。
⑷ linux的iptables里的--reject-with type中這些type的區別是什麼
iptables 的歷史以及工作原理
1.iptables的發展:
iptables的前身叫ipfirewall (內核1.x時代),這是一個作者從freeBSD上移植過來的,能夠工作在內核當中的,對數據包進行檢測的一款簡易訪問控制工具。但是ipfirewall工作功能極其有限(它需要將所有的規則都放進內核當中,這樣規則才能夠運行起來,而放進內核,這個做法一般是極其困難的)。當內核發展到2.x系列的時候,軟體更名為ipchains,它可以定義多條規則,將他們串起來,共同發揮作用,而現在,它叫做iptables,可以將規則組成一個列表,實現絕對詳細的訪問控制功能。
他們都是工作在用戶空間中,定義規則的工具,本身並不算是防火牆。它們定義的規則,可以讓在內核空間當中的netfilter來讀取,並且實現讓防火牆工作。而放入內核的地方必須要是特定的位置,必須是tcp/ip的協議棧經過的地方。而這個tcp/ip協議棧必須經過的地方,可以實現讀取規則的地方就叫做 netfilter.(網路過濾器)
作者一共在內核空間中選擇了5個位置,
1.內核空間中:從一個網路介面進來,到另一個網路介面去的
2.數據包從內核流入用戶空間的
3.數據包從用戶空間流出的
4.進入/離開本機的外網介面
5.進入/離開本機的內網介面
2.iptables的工作機制
從上面的發展我們知道了作者選擇了5個位置,來作為控制的地方,但是你有沒有發現,其實前三個位置已經基本上能將路徑徹底封鎖了,但是為什麼已經在進出的口設置了關卡之後還要在內部卡呢? 由於數據包尚未進行路由決策,還不知道數據要走向哪裡,所以在進出口是沒辦法實現數據過濾的。所以要在內核空間里設置轉發的關卡,進入用戶空間的關卡,從用戶空間出去的關卡。那麼,既然他們沒什麼用,那我們為什麼還要放置他們呢?因為我們在做NAT和DNAT的時候,目標地址轉換必須在路由之前轉換。所以我們必須在外網而後內網的介面處進行設置關卡。
這五個位置也被稱為五個鉤子函數(hook functions),也叫五個規則鏈。
1.PREROUTING (路由前)
2.INPUT (數據包流入口)
3.FORWARD (轉發管卡)
4.OUTPUT(數據包出口)
5.POSTROUTING(路由後)
這是NetFilter規定的五個規則鏈,任何一個數據包,只要經過本機,必將經過這五個鏈中的其中一個鏈。
3.防火牆的策略
防火牆策略一般分為兩種,一種叫「通」策略,一種叫「堵」策略,通策略,默認門是關著的,必須要定義誰能進。堵策略則是,大門是洞開的,但是你必須有身份認證,否則不能進。所以我們要定義,讓進來的進來,讓出去的出去,所以通,是要全通,而堵,則是要選擇。當我們定義的策略的時候,要分別定義多條功能,其中:定義數據包中允許或者不允許的策略,filter過濾的功能,而定義地址轉換的功能的則是nat選項。為了讓這些功能交替工作,我們制定出了「表」這個定義,來定義、區分各種不同的工作功能和處理方式。
我們現在用的比較多個功能有3個:
1.filter 定義允許或者不允許的
2.nat 定義地址轉換的
3.mangle功能:修改報文原數據
我們修改報文原數據就是來修改TTL的。能夠實現將數據包的元數據拆開,在裡面做標記/修改內容的。而防火牆標記,其實就是靠mangle來實現的。
小擴展:
對於filter來講一般只能做在3個鏈上:INPUT ,FORWARD ,OUTPUT
對於nat來講一般也只能做在3個鏈上:PREROUTING ,OUTPUT ,POSTROUTING
而mangle則是5個鏈都可以做:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
iptables/netfilter(這款軟體)是工作在用戶空間的,它可以讓規則進行生效的,本身不是一種服務,而且規則是立即生效的。而我們iptables現在被做成了一個服務,可以進行啟動,停止的。啟動,則將規則直接生效,停止,則將規則撤銷。
iptables還支持自己定義鏈。但是自己定義的鏈,必須是跟某種特定的鏈關聯起來的。在一個關卡設定,指定當有數據的時候專門去找某個特定的鏈來處理,當那個鏈處理完之後,再返回。接著在特定的鏈中繼續檢查。
注意:規則的次序非常關鍵,誰的規則越嚴格,應該放的越靠前,而檢查規則的時候,是按照從上往下的方式進行檢查的。
三.規則的寫法:
iptables定義規則的方式比較復雜:
格式:iptables [-t table] COMMAND chain CRETIRIA -j ACTION
-t table :3個filter nat mangle
COMMAND:定義如何對規則進行管理
chain:指定你接下來的規則到底是在哪個鏈上操作的,當定義策略的時候,是可以省略的
CRETIRIA:指定匹配標准
-j ACTION :指定如何進行處理
比如:不允許172.16.0.0/24的進行訪問。
iptables -t filter -A INPUT -s 172.16.0.0/16 -p udp --dport 53 -j DROP
當然你如果想拒絕的更徹底:
iptables -t filter -R INPUT 1 -s 172.16.0.0/16 -p udp --dport 53 -j REJECT
iptables -L -n -v #查看定義規則的詳細信息
四:詳解COMMAND:
1.鏈管理命令(這都是立即生效的)
-P :設置默認策略的(設定默認門是關著的還是開著的)
默認策略一般只有兩種
iptables -P INPUT (DROP|ACCEPT) 默認是關的/默認是開的
比如:
iptables -P INPUT DROP 這就把默認規則給拒絕了。並且沒有定義哪個動作,所以關於外界連接的所有規則包括Xshell連接之類的,遠程連接都被拒絕了。
-F: FLASH,清空規則鏈的(注意每個鏈的管理許可權)
iptables -t nat -F PREROUTING
iptables -t nat -F 清空nat表的所有鏈
-N:NEW 支持用戶新建一個鏈
iptables -N inbound_tcp_web 表示附在tcp表上用於檢查web的。
-X: 用於刪除用戶自定義的空鏈
使用方法跟-N相同,但是在刪除之前必須要將裡面的鏈給清空昂了
-E:用來Rename chain主要是用來給用戶自定義的鏈重命名
-E oldname newname
-Z:清空鏈,及鏈中默認規則的計數器的(有兩個計數器,被匹配到多少個數據包,多少個位元組)
iptables -Z :清空
2.規則管理命令
-A:追加,在當前鏈的最後新增一個規則
-I num : 插入,把當前規則插入為第幾條。
-I 3 :插入為第三條
-R num:Replays替換/修改第幾條規則
格式:iptables -R 3 …………
-D num:刪除,明確指定刪除第幾條規則
3.查看管理命令 「-L」
附加子命令
-n:以數字的方式顯示ip,它會將ip直接顯示出來,如果不加-n,則會將ip反向解析成主機名。
-v:顯示詳細信息
-vv
-vvv :越多越詳細
-x:在計數器上顯示精確值,不做單位換算
--line-numbers : 顯示規則的行號
-t nat:顯示所有的關卡的信息
五:詳解匹配標准
1.通用匹配:源地址目標地址的匹配
-s:指定作為源地址匹配,這里不能指定主機名稱,必須是IP
IP | IP/MASK | 0.0.0.0/0.0.0.0
而且地址可以取反,加一個「!」表示除了哪個IP之外
-d:表示匹配目標地址
-p:用於匹配協議的(這里的協議通常有3種,TCP/UDP/ICMP)
-i eth0:從這塊網卡流入的數據
流入一般用在INPUT和PREROUTING上
-o eth0:從這塊網卡流出的數據
流出一般在OUTPUT和POSTROUTING上
2.擴展匹配
2.1隱含擴展:對協議的擴展
-p tcp :TCP協議的擴展。一般有三種擴展
--dport XX-XX:指定目標埠,不能指定多個非連續埠,只能指定單個埠,比如
--dport 21 或者 --dport 21-23 (此時表示21,22,23)
--sport:指定源埠
--tcp-fiags:TCP的標志位(SYN,ACK,FIN,PSH,RST,URG)
對於它,一般要跟兩個參數:
1.檢查的標志位
2.必須為1的標志位
--tcpflags syn,ack,fin,rst syn = --syn
表示檢查這4個位,這4個位中syn必須為1,其他的必須為0。所以這個意思就是用於檢測三次握手的第一次包的。對於這種專門匹配第一包的SYN為1的包,還有一種簡寫方式,叫做--syn
-p udp:UDP協議的擴展
--dport
--sport
-p icmp:icmp數據報文的擴展
--icmp-type:
echo-request(請求回顯),一般用8 來表示
所以 --icmp-type 8 匹配請求回顯數據包
echo-reply (響應的數據包)一般用0來表示
2.2顯式擴展(-m)
擴展各種模塊
-m multiport:表示啟用多埠擴展
之後我們就可以啟用比如 --dports 21,23,80
六:詳解-j ACTION
常用的ACTION:
DROP:悄悄丟棄
一般我們多用DROP來隱藏我們的身份,以及隱藏我們的鏈表
REJECT:明示拒絕
ACCEPT:接受
custom_chain:轉向一個自定義的鏈
DNAT
SNAT
MASQUERADE:源地址偽裝
REDIRECT:重定向:主要用於實現埠重定向
MARK:打防火牆標記的
RETURN:返回
在自定義鏈執行完畢後使用返回,來返回原規則鏈。
七:狀態檢測:
是一種顯式擴展,用於檢測會話之間的連接關系的,有了檢測我們可以實現會話間功能的擴展
什麼是狀態檢測?對於整個TCP協議來講,它是一個有連接的協議,三次握手中,第一次握手,我們就叫NEW連接,而從第二次握手以後的,ack都為1,這是正常的數據傳輸,和tcp的第二次第三次握手,叫做已建立的連接(ESTABLISHED),還有一種狀態,比較詭異的,比如:SYN=1 ACK=1 RST=1,對於這種我們無法識別的,我們都稱之為INVALID無法識別的。還有第四種,FTP這種古老的擁有的特徵,每個埠都是獨立的,21號和20號埠都是一去一回,他們之間是有關系的,這種關系我們稱之為RELATED。
所以我們的狀態一共有四種:
NEW
ESTABLISHED
RELATED
INVALID
八:SNAT和DNAT的實現
由於我們現在IP地址十分緊俏,已經分配完了,這就導致我們必須要進行地址轉換,來節約我們僅剩的一點IP資源。那麼通過iptables如何實現NAT的地址轉換呢?
1.SNAT基於原地址的轉換
基於原地址的轉換一般用在我們的許多內網用戶通過一個外網的口上網的時候,這時我們將我們內網的地址轉換為一個外網的IP,我們就可以實現連接其他外網IP的功能。
所以我們在iptables中就要定義到底如何轉換:
定義的樣式:
比如我們現在要將所有192.168.10.0網段的IP在經過的時候全都轉換成172.16.100.1這個假設出來的外網地址:
iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j SNAT --to-source 172.16.100.1
這樣,只要是來自本地網路的試圖通過網卡訪問網路的,都會被統統轉換成172.16.100.1這個IP.
那麼,如果172.16.100.1不是固定的怎麼辦?
我們都知道當我們使用聯通或者電信上網的時候,一般它都會在每次你開機的時候隨機生成一個外網的IP,意思就是外網地址是動態變換的。這時我們就要將外網地址換成 MASQUERADE(動態偽裝):它可以實現自動尋找到外網地址,而自動將其改為正確的外網地址。所以,我們就需要這樣設置:
iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j MASQUERADE
這里要注意:地址偽裝並不適用於所有的地方。
2.DNAT目標地址轉換
對於目標地址轉換,數據流向是從外向內的,外面的是客戶端,裡面的是伺服器端通過目標地址轉換,我們可以讓外面的ip通過我們對外的外網ip來訪問我們伺服器不同的伺服器,而我們的服務卻放在內網伺服器的不同的伺服器上。
如何做目標地址轉換呢?:
iptables -t nat -A PREROUTING -d 192.168.10.18 -p tcp --dport 80 -j DNAT --todestination 172.16.100.2
目標地址轉換要做在到達網卡之前進行轉換,所以要做在PREROUTING這個位置上
九:控制規則的存放以及開啟
注意:你所定義的所有內容,當你重啟的時候都會失效,要想我們能夠生效,需要使用一個命令將它保存起來
1.service iptables save 命令
它會保存在/etc/sysconfig/iptables這個文件中
2.iptables-save 命令
iptables-save > /etc/sysconfig/iptables
3.iptables-restore 命令
開機的時候,它會自動載入/etc/sysconfig/iptabels
如果開機不能載入或者沒有載入,而你想讓一個自己寫的配置文件(假設為iptables.2)手動生效的話:
iptables-restore < /etc/sysconfig/iptables.2
則完成了將iptables中定義的規則手動生效
⑸ linux鉤子函數處理時間
處理的時間是2到3分鍾。
鉤子(Hook)處理的時間是2到3分鍾,是Windows消息處理機制的一個平台,應用程序可以在上面設置子程以監視指定窗口的某種消息,而且所監視的窗口可以是其他進程所創建的。當消息到達後,在目標窗口處理函數之前處理它。鉤子機制允許應用程序截獲處理window消息或特定事件。
⑹ Linux網路 - 數據包在內核中接收和發送的過程(轉)
本文將介紹在Linux系統中, 數據包是如何一步一步從網卡傳到進程手中的 以及 數據包是如何一步一步從應用程序到網卡並最終發送出去的 。
如果英文沒有問題,強烈建議閱讀後面參考里的文章,裡面介紹的更詳細。
本文只討論乙太網的物理網卡,不涉及虛擬設備,並且以一個UDP包的接收過程作為示例.
網卡需要有驅動才能工作,驅動是載入到內核中的模塊,負責銜接網卡和內核的網路模塊,驅動在載入的時候將自己注冊進網路模塊,當相應的網卡收到數據包時,網路模塊會調用相應的驅動程序處理數據。
下圖展示了數據包(packet)如何進入內存,並被內核的網路模塊開始處理:
軟中斷會觸發內核網路模塊中的軟中斷處理函數,後續流程如下
由於是UDP包,所以第一步會進入IP層,然後一級一級的函數往下調:
應用層一般有兩種方式接收數據,一種是recvfrom函數阻塞在那裡等著數據來,這種情況下當socket收到通知後,recvfrom就會被喚醒,然後讀取接收隊列的數據;另一種是通過epoll或者select監聽相應的socket,當收到通知後,再調用recvfrom函數去讀取接收隊列的數據。兩種情況都能正常的接收到相應的數據包。
了解數據包的接收流程有助於幫助我們搞清楚我們可以在哪些地方監控和修改數據包,哪些情況下數據包可能被丟棄,為我們處理網路問題提供了一些參考,同時了解netfilter中相應鉤子的位置,對於了解iptables的用法有一定的幫助,同時也會幫助我們後續更好的理解Linux下的網路虛擬設備。
ndo_start_xmit會綁定到具體網卡驅動的相應函數,到這步之後,就歸網卡驅動管了,不同的網卡驅動有不同的處理方式,這里不做詳細介紹,其大概流程如下:
在網卡驅動發送數據包過程中,會有一些地方需要和netdevice子系統打交道,比如網卡的隊列滿了,需要告訴上層不要再發了,等隊列有空閑的時候,再通知上層接著發數據。
⑺ Linux裡面k8s裡面kind:service代表什麼意思
1 Service 含義
K8s service可以理解為對一組Pod的抽象。類似於Nginx能夠把請求轉發 的 對應的服務上。
2 Service作用
2.1 pod使用時因某些問題重啟,從而導致pod 的IP發生變化,會導致舊的IP不能用,影響用戶對系統使用。service的出現很好 的 解決此問題,客戶端通過service 訪問pod,當podIP有變化也不會影響(service通過Label Selector跟pod綁定)。
2.2 對外暴露pod訪問請求埠。
2.3 固定IP。
2.4 負載均衡。
3 Service 工作機制
3.1 userspace代理模型流程
userspace指Linux操作系統的用戶空間(物理上為內存)。對於service會對外暴露埠號,用戶空間中的kube-proxy會監控service埠上請求,並把請求轉發到對應的pod上。
請求到達內核空間後經由套接字送往用戶空間的kube-proxy,並調度至後端pod。請求會在內核和用戶空間之間來回轉發導致效率不高。(如下圖)
3.2 iptables代理模型流程
kube-proxy負責跟蹤API Server上的Service和Endpoints對象的變動,並根據變動做出iptables的變動。
iptables捕捉到達clusterIP與埠的請求,並將請求轉發到當前service後端pod。
iptables模型不用將流量在用戶空間和內核空間來回切換,因而更加高效和可靠,不過其缺點是iptables代理模型不會在被挑中的後端Pod資源無響應時進行重定向。
3.3 ipvs代理模型
K8s從1.9版本引入ipvs代理模型,且從1.11版本起成為默認設置。
它和iptables模型很類似,唯一一點不同的是在其請求流量的調度功能由ipvs實現,餘下的功能仍由iptables完成。
ipvs是建立在netfilter的鉤子函數上,但它使用hash表作為底層數據結構並工作於內核空間,因此流量轉發速度特別快、規則同步性很好,
而且它支持眾多調度演算法,rr(輪詢)、lc(最小連接數)、dh(目標哈希)、sh(源哈希)、sed(最短期望延遲)、nq(不排隊調度)。
3 Service 類型
3.1 ClusterIp:默認類型,自動分配一個僅Cluster內部可以訪問的虛擬IP.
3.2 NodePort:在ClusterIP基礎上為Service在每台機器上綁定一個埠,這樣可以通過NodeIP:NodePort來訪問服務。
也可以這樣理解在於在 node 上暴露了一個埠,將向該埠的流量導入到 kube-proxy,然後由 kube-proxy 進一步到給對應的 pod。
k8s配置好對外訪問埠後,linux防火牆也需要通過命令配置(-A INPUT -m state --state NEW -m tcp -p tcp --dport 8080 -j ACCEPT)
3.3 LoadBalancer:在NodePort基礎上,藉助cloud provider創建一個外部負載均衡器,並將請求轉發到NodeIP:NodePort。
另一種理解調用cloud provider 去創建 LB 來向節點導流
3.4 ExternalName: 把集群外部的服務引入到集群內部來,在集群內部直接使用,沒有任何類型代理被創建,這只有kubernetes1.7 或更高版本的kube-dns才支持
4 port nodePort targetPod 區別
4.1 port service暴露在cluster ip上的埠,<cluster ip>:port 是提供給集群內部客戶訪問service的入口
4.2 nodePort 是kubernetes提供給集群外部客戶訪問service入口的一種方式(另一種方式是LoadBalancer),所以,<nodeIP>:nodePort 是提供給集群外部客戶訪問service的入口.
4.3 targetPort 是pod上的埠,從port和nodePort上到來的數據最終經過kube-proxy流入到後端pod的targetPort上進入容器
4 Service腳本創建
apiVersion: v1
kind: Service
metadata:
name: myService
spec:
selector:
app: tomcat
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
- name: https
protocol: TCP
port: 443
targetPort: 443
selector欄位中指定了為哪一個標簽的app進行負載均衡即暴露pod 的name為tomcat對外的訪問埠。
⑻ linux內核態,在LSM框架中的文件操作hook介面中如何獲取一個正在被操作的文件的內容(linux4.4版本)
LSM是Linux Secrity Mole的簡稱,即linux安全模塊。其是一種輕量級通用訪
問控制框架,適合於多種訪問控制模型在它上面以內核可載入模塊的形實現。用
戶可以根據自己的需求選擇合適的安全模塊載入到內核上實現。
LSM設計思想:
LSM的設計思想:在最少改變內核代碼的情況下,提供一個能夠成功實現強制訪
問控制模塊需要的結構或者介面。LSM避免了利用如在systrace系統調用中的出
現過的系統調用干預,因為它不能擴展到多處理器內核,並且它受制於參數替換
攻擊。還有LSM在設計時做了兩點考慮:對不使用的人來說盡量少引入麻煩,對
使用的人來說要帶來效率。以Linus Torvalds為代表的內核開發人員對Linux安
全模塊(LSM)提出了三點要求:
1、真正的通用,當使用一個不同的安全模型的時候,只需要載入一個不同的內
核模塊。
2、概念上簡單,對Linux內核影響最小,高效,並且。
3、能夠支持現存的POSIX.1e capabilities邏輯,作為一個可選的安全模塊。
還有,針對linux上提出的各種不同的Linux安全增強系統對Linux安全模塊(LSM
)提出的要求是:能夠允許他們以可載入內核模塊的形式重新實現其安全功能,
並且不會在安全性方面帶來明顯的損失,也不會帶來額外的系統開銷。
LSM框架結構:
LSM框架主要由五部分構成:
1、在特定的內核數據結構中加入安全域。
2、在內核源代碼中不同的關鍵點插入對安全鉤子函數的調用。
3、加入一個通用的安全系統調用。
4、提供了函數允許內核模塊注冊為安全模塊或者注銷。
5、5、將capabilities邏輯的大部分移植為一個可選的安全模塊。
安全域是一個void*類型的指針,它使得安全模塊把安全信息和內核內部對象聯
系起來。下面列出被修改加入了安全域的內核數據結構,以及各自所代表的內核
內部對象:
task_struct結構:代表任務(進程)
linux_binprm結構:代表程序
super_block結構:代表文件系統
inode結構:代表管道,文件,或者Socket套接字
file結構:代表打開的文件
sk_buff結構:代表網路緩沖區(包)
net_device結構:代表網路設備
kern_ipc_perm結構:代表Semaphore信號,共享內存段,或者消息隊列
msg_msg:代表單個的消息
Linux安全模塊(LSM)提供了兩類對安全鉤子函數的調用:一類管理內核對象的
安全域,另一類仲裁對這些內核對象的訪問。對安全鉤子函數的調用通過鉤子來
實現,鉤子是全局表security_ops中的函數指針,這個全局表的類型是
security_operations結構,這個結構定義在include/linux/security.h這個頭
文件中。
LSM介面的核心是security_ops,當系統啟動時,他們被初始化為傳統的DAC策略
。傳統DAC訪問控制是指控制系統中的主體(如進程)對系統中的客體(如文件
目錄、文件)的訪問(讀、寫和執行等)。自主訪問控制DAC 是指主體(進程,
用戶)對客體(文件、目錄、特殊設備文件、IPC等)的訪問許可權是由客體的屬
主或超級用戶決定的,而且此許可權一旦確定,將作為以後判斷主體對客體是否有
訪問許可權的依據。
在載入安全模塊時,我們必需先對模塊進行注冊,我們可以使用
register_security()函數向LSM注冊一個安全模塊。在我們的模塊被載入成
功後,就可以進行訪問控制操作。如果此時還有一個安全模塊要使用
register_security()函數進行載入,則會出現錯誤,直到使用
unregister_security()函數向框架注銷後,下一個模塊才可以載入。當然LS
M還提供了mod_reg_security()函數和mod_unreg_security()函數,可以連續注
冊多個安全模塊。如果有其他後來的模塊需要載入,可以通過mod_reg_security
()向第一個模塊注冊,形成支持不同策略的模塊棧。
註:以上出現的函數均基於2.6.22以前的版本,對於後續的版本,出現了
register_security()函數未被導出或者取消掉了unregister_security()函數。
LSM執行過程:
根據下圖的執行步驟:用戶在執行系統調用時,先通過原有的內核介面依次執行
功能性的錯誤檢查,接著進行傳統的DAC檢查,並在即將訪問內核的內部對象之
前,通過LSM鉤子函數調用LSM。LSM再調用具體的訪問控制策略來決定訪問的合
法性。圖三顯示了LSM鉤子的調用:
圖三:基於LSM的內核對象訪問過程
Lilinux安全模塊(LSM)主要支持"限制型"的訪問控制決策:當Linux內核授予
文件或目錄訪問許可權時,Linux安全模塊(LSM)可能會拒絕,而當 Linux內核拒
絕訪問時,可以跳過LSM。
========
使用LSM實現自己的訪問控制
首先對LSM 進行簡單介紹。雖然linux下的各位基本都知道一些,但是還要羅嗦
一下。
LSM中文全稱是linux安全模塊。英文全稱:linux security mole.
LSM是一種輕量級、通用的訪問控制框架,適合多種訪問控制模型以內核模塊的
形式實現。其特點是通用、簡單、高效、支持POSIX。1e能力機制。
LSM的架構圖如下:
通過系統調用進入內核之後,系統首先進行傳統的許可權檢查(傳統許可權檢查主要
是基於用戶的,用戶通過驗證之後就可以訪問資源),通過之後才會進行強制訪
問控制。(強制訪問控制是不允許主體干涉的一種訪問控制,其採用安全標識、
信息分級等信息敏感性進行訪問控制。並且通過比較主體的級別和資源的敏感性
來確定是否允許訪問。比如說系統設置A用戶不允許訪問文件B,即便A是文件B的
所有者,訪問也是受限制的。)從圖上看來,LSM實現訪問控制主要通過安全模
塊的鉤子函數實現。
LSM框架主要由五部分組成:這個網上資料很多。
在關鍵的特定內核數據結構中加入了安全域;
在內核源碼中不同的關鍵點處插入對安全鉤子函數的調用;
提供了一個通用的安全系統調用;
提供了注冊和注銷函數,使得訪問控制策略可以以內核模塊方式實現;
將capabilities邏輯的大部分功能移植為一個可選的安全模塊。
我們這里重點結合源碼對LSM框架進行解釋。我使用的源碼是3.5.4
首先介紹安全域欄位,它是一個空類型的指針,在內核中的很多內核結構中都存
在,比如inode、superblock、dentry、file等等。類型欄位為void *
security;
那麼安全域怎麼和安全模塊中的信息關聯起來?
當安全模塊載入之後,安全域中的指針便指向安全模塊中的安全信息。這里以
selinux為例進行介紹。
內核裡面security/selinux/include/objsec.h中定義了不同對象的安全信息,
格式為XXX_security_strut.
上面的文件的安全信息裡麵包含打開文件描述符時的安全ID、文件所有者的安全
ID等等。
要聯系安全模塊中安全信息和安全域需要幾個控制鉤子函數。這些鉤子函數實現
了對內核關鍵信息的設置和管理。這里主要介紹alloc_security、
free_security。
selinux裡面通過實現安全信息空間分配實現關聯。比如以文件安全信息為例
這里分配空間成功之後,通過file->f_security = fsec實現了關聯。
撤銷關聯是在安全模塊卸載之後調用file_free_security.
這里具體通過設置file->f_secrity為NULL,然後釋放安全信息結構實現。
現在來看看內核如何實現selinux的訪問控制。這里主要就是實現LSM裡面的鉤子
函數了。LSM裡面給出了結構體security_operations,裡面給出了很多鉤子函數
,實現了相關鉤子函數就可以實現訪問控制了。
上面的函數就實現了file_permission鉤子函數。可以看下inode結構體的獲得,
感受內核是通過文件->目錄項->inode。該函數主要實現自己的訪問控制策略就
OK 了。
哪selinux來說,在獲得文件安全ID之後,主要對掩碼和文件打開時相關的安全
信息進行檢測,符合就通過訪問控制。
selinux基本實現了LSM裡面的所有鉤子函數,待鉤子函數實現後,對LSM裡面鉤
子域進行填充就OK了。
做完以上這些還需要注冊安全模塊到LSM,這里注冊和注銷使用了
register_security和unregister_security。
比如selinux在注冊時使用語句register_security(&selinux_ops)實現。
接下來通過上面的分析我們可以實現簡單的基於LSM的訪問控制。
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/mole.h>
#include <linux/fs.h>
#include <linux/security.h>
#include <linux/types.h>
#include <asm/uaccess.h>
#include <linux/fcntl.h>
#include <linux/uaccess.h>
#include <linux/file.h>
#include <linux/namei.h>
static int lsm_test_file_permission(struct file *file,int mask)
{
int path=0;
struct file *filp;
struct nameidata nd;
path = path_lookup(FILENAME,LOOKUP_FOLLOW,&nd);
if(!mask)
return 0;
if(path)
{
printk("lookup file failed!\n");
return -1;
}
filp = filp_open("/home/yuyunchao/code/sb.c",O_RDONLY,0);
{
printk("open failed!\n");
}
return 0;
}
static struct security_operations lsm_test_security_ops = {
.file_permission = lsm_test_file_permission,
};
static int __init lsm_file_init(void)
{
if(register_security(&lsm_test_security_ops)){
printk("register error ..........\n");
return -1;
}
printk("lsm_file init..\n ");
return 0;
}
static void __exit lsm_file_exit(void)
{
if(unregister_security(&lsm_test_security_ops)){
printk("unregister error................\n");
return ;
}
printk("mole exit.......\n");
}
MODULE_LICENSE("GPL");
mole_init(lsm_file_init);
mole_exit(lsm_file_exit);
========
LSM(Linux Security Mole)應用方法(簡單例子)
LSM在內核中很多地方已經插入了hook函數,並且在security.c函數中聲明了
security_ops結構,要實現你自己的安全模塊,只需要定義你自己的struct
security_operations,並且用register_security注冊即可,下面舉個簡單例子
:
test.c代碼如下:
/*
* Test Linux Security Mole
*
* Author: penghuan <[email protected]>
*
* Copyright (C) 2010 UbuntuKylin, Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2, as
* published by the Free Software Foundation.
*
*/
#include <linux/security.h>
#include <linux/sysctl.h>
#include <linux/ptrace.h>
#include <linux/prctl.h>
#include <linux/ratelimit.h>
#include <linux/workqueue.h>
#include <linux/file.h>
#include <linux/fs.h>
#include <linux/dcache.h>
#include <linux/path.h>
int test_file_permission(struct file *file, int mask)
{
char *name = file->f_path.dentry->d_name.name;
if(!strcmp(name, "test.txt"))
{
file->f_flags |= O_RDONLY;
printk("you can have your control code here!\n");
}
return 0;
}
static struct security_operations test_security_ops = {
.name = "test",
.file_permission = test_file_permission,
};
static __init int test_init(void)
{
printk("enter test init!\n");
printk(KERN_INFO "Test: becoming......\n")
if (register_security(&test_security_ops))
panic("Test: kernel registration failed.\n");
return 0;
}
security_initcall(test_init);
將該文件以模塊的形式放到security/下編譯進內核,啟用新的內核後,當你操
作文件test.txt時,通過dmesg命令就能再終端看到」you can have your
control code here!「輸出
所以一般的做法是:定義你自己的struct security_operations,實現你自己的
hook函數,具體有哪些hook函數可以查詢include/linux/security.h文件,然後
調用register_security來用你的test_security_ops初始化全局的security_ops
指針
樓主,我剛開始研究LSM,但網上資料太少,您這個代碼,我編譯成ko文件老是
有警告,並且insmod時,說Unknown symbol register_security。我最近看了看
內核模塊變成,沒有對內核進行太深入的了解。不知能否把LSM的實驗步驟給出
的再詳細點,謝謝。
你需要把代碼編進內核
是需要把那段源碼拷到內核目錄下,然後重新編譯內核?。。沒有不編譯內核的
方法嗎?。。直接按照模塊進行編譯。另外那個test.txt放在哪個文件夾里?。
是需要把那段源碼拷到內核目錄下,然後重新編譯內核?。。沒有不編譯內核的
方法嗎?。。直接按照模塊進行 ...
是的,你去網上找下怎麼把模塊編進內核,lsm模塊不能以模塊方式載入,涉及
安全;test.txt是測試文件,當你把代碼編進內核後,用新內核啟動,然後操作
test.txt文件,就會有輸出,test.txt隨便放哪裡
樓主,您好,我剛開始學習lsm模塊,把您的模塊編譯進內核,新的內核載入後
,register_security總是失敗,請問下可能是什麼原因導致的。我的內核版本
是3.13.11。
register_security的返回值是-11
========
LSM在Linux中的實現方式
LSM(Linux Secure Model)一種輕量級訪問控制機制.
其實現方式有如在系統調用中加入一個後門....
方式如下:
static struct file *__dentry_open(struct dentry *dentry, struct
vfsmount *mnt,
struct file *f,
int (*open)(struct inode *, struct file *),
const struct cred *cred)
{
struct inode *inode;
int error;
...............................................................
error = security_dentry_open(f, cred); //LSM機制實現方式,在此加入了
一個LSM函數.
//security_dentry_open的實現如下,相當於一個介面,對一個函數指針再
//封裝一下.
//只返回是與否,這樣的控制信息.
if (error)
goto cleanup_all;
................................................................
return f;
cleanup_all:
.................................................................
return ERR_PTR(error);
}
//========簡單封裝一個指針結構體===========================
int security_dentry_open(struct file *file, const struct cred *cred)
{
int ret;
ret = security_ops->dentry_open(file, cred);
if (ret)
return ret;
return fsnotify_perm(file, MAY_OPEN);
}
========
利用LSM實現更安全的linux
LSM的全稱是Linux Security Moles,它是linux內核中用來支持更靈活的
安全策略的一個底層框架,雖然聽起來比較復雜,但是可以就把它理解成一組安
插在linux內核的鉤子函數和一些預留的被稱為安全域的數據結構,下面先說說
這個框架的由來吧。
linux本身的機制就保證了linux擁有更好的安全機制,但是在這個機制下面
,還是隱藏了許多的問題:
1、許可權粒度太大。用過linux的人應該對0644這樣的訪問許可權設置不陌生,
它對能夠操作這個文件的用戶做了限制,但是這個只是限制到了組,而沒有更進
一步的細分,當然,如果LSM只是用來限制這個的話,那麼也就太沒意思了,因
為實現文件更細的控制粒度,ACL就能夠很出色的完成,順便提一下,ACL有一個
分配的限制,如果哪位朋友需要用ACL進行粒度更細的訪問許可權控制的話,可能
需要注意一下這方面的東西。
2、root用戶的許可權太大。在linux中,root用戶就是至高無上的,他擁有對
機器的完全控制許可權,可以做他想做的一切事情。但是很多時候,我們可能並不
希望有root有這么大的許可權,比如在現在比較流行的雲存儲中,用戶肯定不希望
服務提供商能夠隨意訪問我們的文件,那麼這個時候,就需要對root用戶進行一
定的設置了。
由於這些問題的存在,所以出現了像SE Linux(Securiy Enhanced Linux )
這樣的增強補丁。但是每個系統對於具體安全細節的控制不盡相同, 所以Linus
Tovalds 提出應該要有一個 Linux 內核所能接受的安全框架來支持這些安全策
略,這個安全框架應該提供包含內核數據結構中的透明安全域以及用來控制、維
護安全域操作的安全鉤子,於是就有了LSM。
LSM在內核中的位置,可以用下圖來表示:
當用戶態程序調用某些操作系統提供的函數的時候,比如read()函數,其會
對應於內核中的一個系統調用,然後該首先會進行一些常規的錯誤檢測,接著進
行DAC(Discretionary Access Control)檢測,再接著它會進行LSM檢測。從上
圖中能夠看出來,LSM其實是一個非常底層的安全策略框架,利用LSM,可以接管
所有的系統調用,這樣,我們就能對包括root在內的所有用戶的許可權進行控制,
並且實現粒度更細的訪問許可權控制。
當系統初始化的時候,LSM就是一個空的框架,它不提供任何的檢測,其所
做的全部工作幾乎就是返回0,當然,有些不帶返回值的函數除外。而我們則可
以針對自己特定的需求來編寫LSM,然後將我們編寫的LSM鉤子函數,通過其數據
結構struct security_operations注冊到系統中去,這樣,我們的LSM檢測就開
始起作用了。
更多信息可參考《Linux就該這么學》
⑼ Gitlab+Jenkins通過鉤子實現自動部署web項目,圖文詳細教程
擴展參考:Jenkins+Gitlab通過腳本自動部署回滾web項目至集群
1):Gitlab伺服器:ubuntu 192.168.152.131 ---參考搭建:Linux安裝gitlab,docker安裝gitlab教程
2):Jenkins伺服器:ubunu 192.168.152.130 ---參考搭建:linux安裝Jenkins,或docker安裝Jenkins教程
在伺服器上生成ssh-keygen,用於配置web伺服器和Gitlab伺服器。
3):web伺服器:centos 192.168.152.150 ---已搭建好LNMP環境
4):開發者電腦:Windows+key密鑰 (用於提交代碼)
1:在gitlab創建項目Test Project
2.1): 配置一個開發者電腦的ssh公鑰到gitlab
配置一個開發者電腦的ssh公鑰到gitlab,這樣才能模擬開發上傳代碼到gitlab。
windows生成key過程及git安裝,可參考:Windows下git和github的使用圖文詳細教程_the丶only的博客-CSDN博客_github win
在windows測試clone,和提交代碼。
註:最新版git 已經將默認分支master改為main了。所以看到main,而不是master不要太奇怪
測試成功,在gitlab也顯示有index.html文件。
2.2): 配置jenkins公鑰到gitlab
同理,同樣需要jenkins公鑰,因為jenkins也需要拉去gitlab的代碼。
在 jenkins伺服器 上查看公鑰並復制添加到gitlab,並命名為jekins。
1:插件管理,安裝插件
jenkins本身沒什麼功能,主要是依靠插件來實現各種強大的功能。
基本需要添加的插件:Gitlab Hook、Build Authorization Token Root、Publish Over SSH、Gitlab Authentication、Gitlab、Git Parameter
可以在 Manage Jenkins >> Manage Plugins 查看管理插件。在Available 選項搜索安裝插件即可。
安裝完成後,重啟Jenkins。
2:添加需要部署的web主機
在 Manage Jenkins >> Configure System 中往下翻,找到 Publish over SSH 選項,點擊add ssh server。
在Jenkins伺服器上,查看私鑰,注,是私鑰,不是公鑰。
將私鑰填寫在key位置,還有添加web伺服器相關信息。
註:如果測試報錯如下
Failed to connect or change directory
jenkins.plugins.publish_over.BapPublisherException: Failed to add SSH key. Message [invalid privatekey: [B@2e54414f]
是因為默認用ssh-keygen命令,默認生成了OPENSSH 格式密鑰。而Jenkins暫時不支持這種私鑰,私鑰開頭結尾如下:
所以,需要生成rsa密鑰格式的。用開頭說的ssh-keygen加其他參數生成即可。
私鑰開頭結尾如下:
再次測試,顯示success,則成功。然後點擊save保存即可。
3:構建任務項目
首頁創建任務或者一個項目
命名為web-project,選擇為freestyle project 自由項目。然後ok確認。
3.1):源碼管理 Source Code Management
選擇源碼管理,添加gitlab的項目clone地址。
註:最後路徑選擇分支,我gitlab主分支名字為main,如果是master,則寫master,或者合並的其他分支。
在add添加用戶
添加完成後,選擇git用戶,這時沒有紅色提醒,說明已成功連接
3.2):構建觸發器 Build Triggers
現在Build Triggers,勾選build when....,其他默認,並記下鏈接 http://192.168.152.130:8080/project/web-project
點擊高級 advance 選項。
勾選filter branches regex選擇,填寫分支,生產token。其他默認
3.3):構建 Build
選擇Build 選項。選擇ssh
添加web伺服器
添加完畢,最後save保存。
1:添加鉤子webhooks.
選擇自己的項目Test Project,在設置setting里,選擇鉤子webhooks.
填寫剛才記下的http://192.168.152.130:8080/project/web-project和token值。
最後Add webhook完成:
2:如添加失敗,報錯,更改Network
註:如填寫失敗提示Url is blocked: Requests to the local network are not allowed
還需更改Network選項。
3:測試鉤子
添加完成後,下面會出現鉤子選擇。點擊test中的,push event。
出現successful,即添加成功。
在Jenkins也可以看到剛才的測試時間信息。
在開發電腦上測試提交,我這里為Windows電腦測試。
打開Git Bash,輸入以下命令:
提交成功,回到Jenkins,查看是否構建成功:
綠色顯示構建成功,無錯誤顯示。回到gitlab查看項目。
時間顯示剛才也提交成功,無錯誤。最後在瀏覽器輸入web地址測試,本人配置了web訪問埠8082。所以輸入IP加埠訪問。
內容也已經自動更新成功。
完結撒花!!!