SElinux 導致 Keepalived 檢測腳本無法執行

哈嘍大家好,我是咸魚

今天我們來看一個關于 Keepalived 檢測腳本無法執行的問題

一位粉絲后臺私信我,說他部署的 keepalived 集群 vrrp_script 模塊中的腳本執行失敗了,但是手動執行這個腳本卻沒有任何問題

在這里插入圖片描述
這個問題也是咸魚第一次遇到,為了能讓更多的小伙伴以后不會踩這個坑,便有了今天這篇文章

前言

在正式開始之前,我們先來簡單復習一下 Keepalived 中的資源檢測功能

vrrp_script 模塊

Keepalived 中,vrrp_script 模塊是用于定義和配置虛擬路由冗余協議(VRRP)的自定義腳本檢查,這個模塊專門用于對集群中的服務資源進行監控

vrrp_script 模塊搭配使用的是 track_script 模塊,這個模塊中可以引入監控腳本、命令組合、Shell 語句來實現對服務資源的監控

track_script 通過調用 vrrp_script,可以靈活地定義需要監測的服務或資源,例如網絡連接、服務狀態、系統資源等

當監測到故障時,Keepalived 可以觸發狀態轉移,將主節點切換到備用節點,以確保服務的高可用性

  • 通過 killall -l 命令監測

killall 命令會發送一個信號給進程,以信號 0 為例,如果發現進程關閉或者異常,將返回狀態碼 1,反之進程運行正常,狀態碼返回0

vrrp_script nginx_check {script "killall -0 nginx"interval 2
}track_script {nginx_check
}
  • 通過端口監測

檢測端口的運行狀態也是較常見的監控方式

vrrp_script nginx_check {script "</dev/tcp/127.0.0.1/80"interval 2fall 2rise 1
}track_script {nginx_check
}

其中 fall表示檢測到失敗的最大次數(如果請求失敗兩次,就認為該節點發生了故障)

rise 表示如果請求一次成功,就認為該節點恢復正常

  • 通過 shell 語句監測
vrrp_script nginx_check {script "if [ $(pidof nginx | wc -l) -eq 0 ]; then exit 1; else exit 0; fi"interval 2fall 2rise 1
}track_script {nginx_check
}
  • 通過腳本監測
vrrp_script nginx_check {script "/etc/keepalived/nginx_check.sh"interval 2fall 2rise 1
}track_script {nginx_check
}

問題

在介紹完了 keepalived 的監測功能之后,我們來看下這個問題

我根據他的描述復現了這個場景:keepalived 通過監測上游網絡來判斷該節點是否正常運行,如果到上游的網絡不通,則認為該節點發生了故障

檢測腳本如下:

[root@localhost ~]# cat /etc/keepalived/check.sh 
#!/bin/bash
# 檢查上行鏈路
check_route="192.168.149.135"
ping -c 3 $check_route >/dev/null 2>&1
result=$?
echo "${date}----checking..... result:${result}" >> /tools/log.log
if [ $? -eq 0 ]; thenexit 0          # 正常
elseexit 1          # 鏈路異常
fi

一切準備就緒之后啟動 keepalived 服務發現報 Keepalived_vrrp[2653]: /etc/keepalived/check.sh exited with status 1

[root@localhost ~]# systemctl status keepalived.service 
● keepalived.service - LVS and VRRP High Availability MonitorLoaded: loaded (/usr/lib/systemd/system/keepalived.service; disabled; vendor preset: disabled)Active: active (running) since 三 2023-08-14 23:53:49 CST; 4min 56s ago...
814 23:53:49 localhost.localdomain Keepalived_vrrp[2653]: /etc/keepalived/check.sh exited with status 1
...

說明腳本沒有執行成功,返回狀態碼 1 了,我嘗試著手動執行,發現腳本沒有任何問題

[root@localhost ~]# sh /etc/keepalived/check.sh 
[root@localhost ~]# echo $?
0

排查

首先看一下 /var/log/messages(如果 keepalived 沒有專門指定日志文件路徑,這個便是默認的日志文件路徑)

...
Aug 14 23:53:49 localhost Keepalived_vrrp[17889]: SECURITY VIOLATION - scripts are being executed but script_security not enabled
...
Aug 14 23:53:49 localhost Keepalived_vrrp[17889]: /etc/keepalived/check.sh exited with status 1
...

SECURITY VIOLATION - scripts are being executed but script_security not enabled 這條信息引起了我的注意

”安全違規-腳本正在執行,但 script_security 未啟用“,看輸出應該是 keepalived 進程想要執行該腳本,但是受到了安全限制

既然是跟系統安全相關的,我們就先來看看這個腳本的權限吧

# 查看腳本權限
[root@localhost ~]# ll /etc/keepalived/check.sh 
-rwxr-xr-x. 1 root root 281 89 15:52 /etc/keepalived/check.sh# 查看是 keepalived 進程的屬主
[root@localhost ~]# ps -ef | grep keep
root      19163      1  0 01:00 ?        00:00:00 /usr/sbin/keepalived -D
...

由上面的輸出我們可以得知 keepalived 進程的屬主是 root ,而 root 用戶是可以去執行這個腳本的(有 x 權限)

權限沒問題,我們再來查看下 /var/log/audit/audit.log

/var/log/audit/audit.log 是一個存儲系統審計日志的文件

這個文件記錄了系統中發生的各種安全事件、用戶操作和系統行為,以及與安全相關的信息

系統審計日志是用來監控系統活動、檢測潛在的安全問題和追蹤系統事件的重要工具之一

...
type=SYSCALL msg=audit(1692033018.624:12555): arch=c000003e syscall=4 success=no exit=-13 a0=190abc0 a1=7ffd028eafc0 a2=7ffd028eafc0 a3=7ffd028eaae0 items=0 ppid=19472 pid=19473 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm="check.sh" exe="/usr/bin/bash" subj=system_u:system_r:keepalived_t:s0 key=(null)type=AVC msg=audit(1692033018.624:12555): avc:  denied  { getattr } for  pid=19473 comm="check.sh" path="/usr/bin/ping" dev="dm-0" ino=50555278 scontext=system_u:system_r:keepalived_t:s0 tcontext=system_u:object_r:ping_exec_t:s0 tclass=file permissive=0
...

我們現在來看一下上面日志輸出表示什么

先看第一段:

type=SYSCALL: 這個部分是系統調用事件類型。arch=c000003e syscall=4 success=no exit=-13: 這里描述了系統調用的詳細信息,包括系統調用號、是否成功等

  • subj=system_u:system_r:keepalived_t:s0:描述了進程的安全上下文信息
  • 后面內容則是一些更多與系統調用相關的信息,如參數、進程信息、用戶信息等

再看第二段:

type=AVC: 這個部分指示了事件類型為 AVC(Access Vector Cache),是 SELinux 的訪問控制事件,

  • avc: denied { getattr }: 表示操作是一個 getattr(獲取屬性)操作,但是被拒絕。
  • pid=19473 comm="check.sh": 進程 ID 是 19473,進程名稱是 check.sh
  • path="/usr/bin/ping": 文件路徑是 /usr/bin/ping,表示被操作的文件。
  • scontext=system_u:system_r:keepalived_t:s0: 發起操作的進程的安全上下文。
  • tcontext=system_u:object_r:ping_exec_t:s0: 被操作文件的安全上下文。
  • tclass=file: 被操作對象的類型是文件。
  • permissive=0: 表示 SELinux 不是處于寬松模式

總結一下:

這個是 SELinux 的審計日志,這兩條日志記錄了一個操作,即 keepalived 進程試圖通過執行 check.sh" 腳本訪問 /usr/bin/ping 文件,但被 SELinux 拒絕了

解決

排查到這思路就逐漸清晰起來了,這是因為 SELinux 權限導致的,在解決這個問題之前,我們先來簡單復習一下 SELinux (后面我會專門寫一篇文章來介紹 SELinux)

SELinux(Security Enhanced Linux,安全強化的 Linux) ,由美國國家安全局(NSA)開發的

為什么要開發 SELinux

我們知道系統的賬戶主要分為系統管理員(root)和普通用戶,這兩種身份能否使用系統上面的文件資源則與 rwx 權限設置有關

所以當某個進程想要對文件進行讀寫操作時,系統就會根據該進程的屬主和屬組去比對文件權限,只有通過權限檢查,才能夠進一步操作文件

這種方式被稱為自主訪問控制(Discretionary Access Control, DAC),DAC 是 Linux 操作系統中的一種基本權限控制機制,用于限制用戶對系統資源的訪問權限

但是 DAC 的一大問題就是當用戶獲取到進程之后,他可以通過這個進程與自己所獲得的權限去處理對應的文件資源

萬一用戶對系統不熟悉,就很容易導致資源誤用的問題出現

舉個例子,你們公司的新人為了自身方便,將網頁所在目錄 /var/www/html 目錄的權限設置成了 777,則代表所有進程都可以對該目錄進行讀寫

如果黑客接觸到了某個進程,就極有可能向你的系統里面寫入某些東西

為了避免 DAC 的問題,便有了 SELinux

SELinux MAC 機制

SELinux 引入了強制訪問控制(Mandatory Access Control, MAC)機制

強制訪問控制(MAC,Mandatory Access Control)是 Linux 操作系統中一種更加嚴格和細粒度的訪問控制機制,用于加強對系統資源的保護和控制

MAC 有趣的地方在于它可以針對特定的進程與特定的文件資源來管理權限,即使你是 root 用戶,在使用不同的進程時你所能獲取的權限也不一定是 root

在這里插入圖片描述
安全上下文

前面我們知道,SELinux 是通過 MAC 的方式來管理進程的權限的

它控制的主體是【進程】,而【目標】則是該【進程】能否讀取的文件資源

  • 主體

SELinux 主要管理的就是進程,進程和主體可以畫上等號

  • 目標

主體能否讀寫的目標一般就是文件資源

除了策略指定之外,主體與目標的安全上下文必須一致才能夠順利讀寫

安全上下文有點類似于文件系統的 rwx ,如果設置錯誤,主體就無法讀寫目標資源了

在這里插入圖片描述
安全上下文存放在文件的 inode 內,可以通過 ll -Z 命令去查看(前提是 SELinux 是開啟著的)

回到我們的案例上來,日志輸出說進程 check.sh 試圖獲取 /usr/bin/ping 的屬性(getattr)操作,但被 SELinux 拒絕了

但是我們發現沒有這個進程

[root@localhost ~]# ps -ef | grep check

也就是說,由于 SELinux 權限問題 ,keepalived 一開始想要調用 check.sh 腳本就失敗了

我們分別來看一下 keepalived 進程和 check.sh 的安全上下文

[root@localhost ~]# ps -eZ | grep keepalived 
system_u:system_r:keepalived_t:s0 19609 ?       00:00:00 keepalived[root@localhost ~]# ll -Z /etc/keepalived/check.sh 
-rwxr-xr-x. root root system_u:object_r:etc_t:s0       /etc/keepalived/check.sh

可以看到 keepalived 進程的安全上下文類型為 keepalived_t;而 check.sh 的安全上下文是 etc_t

即——主體與目標的安全上下文并不一致,就算有 rwx 權限也無法執行

  • 解決方案一:關閉 SELinux

簡單粗暴,直接關閉 SELinux ,就沒有這么多亂七八糟的限制了

# 以 CentOS 7 為例
# 臨時關閉
[root@localhost ~]# setenforce 0#永久關閉,將 SELINUX=enforcing 改為 SELINUX=disabled,然后保存退出
[root@localhost ~]# sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
  • 解決方案二(失敗了):修改 check.sh 的安全上下文與 keepalived 一致

我想把 check.sh 的安全上下文改成與 keepalived 一致,可是失敗了,有小伙伴知道原因嗎

[root@localhost ~]# chcon -t keepalived_t  /etc/keepalived/check.sh
chcon: 改變"/etc/keepalived/check.sh" 的環境到"system_u:object_r:keepalived_t:s0" 失敗: 權限不夠
  • 解決方案三:修改 check.sh 的安全上下文

依舊是修改 check.sh 的安全上下文,不過這次參考了資料

[root@localhost ~]# chcon -t keepalived_unconfined_script_exec_t  /etc/keepalived/check.sh

keepalived_unconfined_script_exec_t 是一個在 SELinux 中用于標識 Keepalived 執行未限制腳本的上下文,這個上下文允許 Keepalived 進程在執行腳本時繞過一些 SELinux 限制,從而可以在需要的情況下執行腳本

  • 解決方案四:將腳本轉移到 /usr/libexec/keepalived 目錄中
# keepalived 配置
vrrp_script nginx_check {script "/usr/libexec/keepalived/check.sh"interval 2fall 2rise 1
}

這個目錄的安全上下文是 keepalived_unconfined_script_exec_t,與解決方案三同理

[root@localhost ~]# ll -Z /usr/libexec/keepalived/ -d
drwxr-xr-x. root root system_u:object_r:keepalived_unconfined_script_exec_t:s0 /usr/libexec/keepalived/
  • 解決方案五: keepalived 全局配置添加 enable_script_security 字段

加了這個字段意味著如果腳本路徑的任一部分對于非 root 用戶來說,都具有可寫權限,則不會以 root 身份運行腳本

以非 root 身份運行的腳本就能夠通過 SELinux 的審查嗎?這一塊我不太懂,有懂的小伙伴可以告訴我

global_defs {...enable_script_security...
}

參考資料:

https://github.com/acassen/keepalived/issues/1322

https://serverfault.com/questions/709428/track-script-doesnt-work-after-keepalived-update

https://www.mankier.com/8/keepalived_selinux

https://linux.vbird.org/linux_basic/centos7/0440processcontrol.php#selinux

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/39704.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/39704.shtml
英文地址,請注明出處:http://en.pswp.cn/news/39704.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

《安富萊嵌入式周報》第320期:鍵盤敲擊聲解碼, 軍工級boot設計,開源CNC運動控制器,C語言設計筆記,開源GPS車輛跟蹤器,一鍵生成RTOS任務鏈表

周報匯總地址&#xff1a;嵌入式周報 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬漢嵌入式論壇 - Powered by Discuz! 視頻版&#xff1a; https://www.bilibili.com/video/BV1Cr4y1d7Mp/ 《安富萊嵌入式周報》第320期&#xff1a;鍵盤敲擊…

【智慧工地源碼】:人工智能、BIM技術、機器學習在智慧工地的應用

智慧工地云平臺是專為建筑施工領域所打造的一體化信息管理平臺。通過大數據、云計算、人工智能、BIM、物聯網和移動互聯網等高科技技術手段&#xff0c;將施工區域各系統數據匯總&#xff0c;建立可視化數字工地。同時&#xff0c;圍繞人、機、料、法、環等各方面關鍵因素&…

理解持續測試,才算理解DevOps

軟件產品的成功與否&#xff0c;在很大程度上取決于對市場需求的及時把控&#xff0c;采用DevOps可以加快產品交付速度&#xff0c;改善用戶體驗&#xff0c;從而有助于保持領先于競爭對手的優勢。 作為敏捷開發方法論的一種擴展&#xff0c;DevOps強調開發、測試和運維不同團…

centos如何安裝libssl-dev libsdl-dev libavcodec-dev libavutil-dev ffmpeg

在 CentOS 系統上安裝這些包可以按照以下步驟進行&#xff1a; 打開終端&#xff0c;使用 root 或具有管理員權限的用戶登錄。 使用以下命令安裝 libssl-dev 包&#xff1a; yum install openssl-devel使用以下命令安裝 libsdl-dev 包&#xff1a; yum install SDL-devel使用以…

Go 安裝配置

介紹Ubuntu20.04 安裝和配置Go 1.安裝Go 去這個地方下載Go https://go.dev/doc/install 如果之前安裝過&#xff0c;可以參考這個&#xff08;沒有可以忽略&#xff09; 下載完成后執行 sudo tar -C /usr/local -xzf go1.21.0.linux-amd64.tar.gz 然后修改環境變量 sudo ge…

css3-grid:grid 布局 / 基礎使用

一、理解 grid 二、理解 css grid 布局 CSS Grid布局是一個二維的布局系統&#xff0c;它允許我們通過定義網格和網格中每個元素的位置和尺寸來進行頁面布局。CSS Grid是一個非常強大的布局系統&#xff0c;它不僅可以用于構建網格布局&#xff0c;還可以用于定位元素&#xf…

ahooks.js:一款強大的React Hooks庫及其API使用教程(一)

一、ahooks.js簡介二、ahooks.js安裝三、ahooks.js API介紹與使用教程1. useRequest2. useAntdTable3. useSize4. useBoolean5. useToggle6. useHover7. useDebounce8. useEventListener9. useFusionTable10. useKeyPress11. useLoading12. usePrevious13. useForm14. useUpdat…

代碼審計-ASP.NET項目-未授權訪問漏洞

代碼審計必備知識點&#xff1a; 1、代碼審計開始前準備&#xff1a; 環境搭建使用&#xff0c;工具插件安裝使用&#xff0c;掌握各種漏洞原理及利用,代碼開發類知識點。 2、代碼審計前信息收集&#xff1a; 審計目標的程序名&#xff0c;版本&#xff0c;當前環境(系統,中間件…

Flink源碼之State創建流程

StreamOperatorStateHandler 在StreamTask啟動初始化時通過StreamTaskStateInitializerImpl::streamOperatorStateContext會為每個StreamOperator 創建keyedStatedBackend和operatorStateBackend&#xff0c;在AbstractStreamOperator中有個StreamOperatorStateHandler成員變量…

Web framework-Gin

一、Gin Go Web--Go Module 軟件框架&#xff08;software framework&#xff09;&#xff0c;通常指的是為了實現某個業界標準或完成特定基本任務的軟件組件規范&#xff0c;也指為了實現某個軟件組件規范時&#xff0c;提供規范所要求之基礎功能的軟件產品。 框架就是&#…

機器學習|Softmax 回歸的數學理解及代碼解析

機器學習&#xff5c;Softmax 回歸的數學理解及代碼解析 Softmax 回歸是一種常用的多類別分類算法&#xff0c;適用于將輸入向量映射到多個類別的概率分布。在本文中&#xff0c;我們將深入探討 Softmax 回歸的數學原理&#xff0c;并提供 Python 示例代碼幫助讀者更好地理解和…

HarmonyOS NEXT新能力,一站式高效開發HarmonyOS應用

2023年8月6日華為開發者大會2023&#xff08;HDC.Together&#xff09;圓滿收官&#xff0c;伴隨著HarmonyOS 4的發布&#xff0c;華為向開發者發布了匯聚所有最新開發能力的HarmonyOS NEXT開發者預覽版&#xff0c;并分享了圍繞“一次開發&#xff0c;多端部署” “可分可合&a…

代碼隨想錄算法訓練營第60天|動態規劃part17| 647. 回文子串、516.最長回文子序列、動態規劃總結篇

代碼隨想錄算法訓練營第60天&#xff5c;動態規劃part17&#xff5c; 647. 回文子串、516.最長回文子序列、動態規劃總結篇 647. 回文子串 647. 回文子串 思路&#xff1a; 暴力解法 兩層for循環&#xff0c;遍歷區間起始位置和終止位置&#xff0c;然后還需要一層遍歷判斷…

【mysql】—— 表的增刪改查

目錄 序言 &#xff08;一&#xff09;Create操作 1、單行數據 全列插入 2、多行數據 指定列插入 3、插入否則更新 4、直接替換 &#xff08;二&#xff09;Retrieve操作 1、SELECT 列 1??全列查詢 2??指定列查詢 3??查詢字段為表達式 4??為查詢結果指定…

數據結構——堆

數據結構——堆 堆堆簡介堆的分類 二叉堆過程插入操作 刪除操作向下調整&#xff1a; 增加某個點的權值實現參考代碼&#xff1a;建堆方法一&#xff1a;使用 decreasekey&#xff08;即&#xff0c;向上調整&#xff09;方法二&#xff1a;使用向下調整 應用對頂堆 其他&#…

Python Flask+Echarts+sklearn+MySQL(評論情感分析、用戶推薦、BI報表)項目分享

Python FlaskEchartssklearnMySQL(評論情感分析、用戶推薦、BI報表)項目分享 項目背景&#xff1a; 隨著互聯網的快速發展和智能手機的普及&#xff0c;人們越來越傾向于在網上查找餐廳、購物中心、酒店和旅游景點等商戶的點評和評分信息&#xff0c;以便做出更好的消費決策。…

YOLOv8 : 網絡結構

一. YOLOv8網絡結構 1. Backbone YOLOv8的Backbone同樣參考了CSPDarkNet-53網絡&#xff0c;我們可以稱之為CSPDarkNet結構吧&#xff0c;與YOLOv5不同的是&#xff0c;YOLOv8使用C2f(CSPLayer_2Conv)代替了C3模塊(如果你比較熟悉YOLOv5的網絡結構&#xff0c;那YOLOv8的網絡…

【GitHub】Pycharm本地項目打包上傳到Github倉庫的操作步驟

文章目錄 1、Pycharm端的設置操作2、Github端的設置操作3、Pycharm上配置Github4、Git本地項目至GitHub倉庫5、前往Github中查看確認6、常見報錯 1、Pycharm端的設置操作 通過CtrlAltS快捷組合鍵的方式&#xff0c;打開設置&#xff0c;導航到版本控制一欄中的Git&#xff0c;…

Gin安裝解決國內go 與 熱加載

get 方式安裝超時問題&#xff0c;國內直接用官網推薦的下面這個命令大概率是安裝不成功的 go get -u github.com/gin-gonic/gin 可以在你的項目目錄下執行下面幾個命令&#xff1a; 比如我的項目在E:\Oproject\zl cmd E:\Oproject\zl>就在目錄下執行 go env -w GO111…

回歸預測 | MATLAB實現GRU門控循環單元多輸入多輸出

回歸預測 | MATLAB實現GRU門控循環單元多輸入多輸出 目錄 回歸預測 | MATLAB實現GRU門控循環單元多輸入多輸出預測效果基本介紹程序設計往期精彩參考資料 預測效果 基本介紹 MATLAB實現GRU門控循環單元多輸入多輸出&#xff0c;數據為多輸入多輸出預測數據&#xff0c;輸入10個…