成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

一次使用 eBPF LSM 來解決系統時間被回調的記錄

開發 前端
vm-agent 應該是虛擬機的一個管理進程,可能的原因是物理機的時間慢 2min 左右,然后通過 vm-agent 來調整了當前主機所有虛擬機的時間。

最近遇到一個客戶環境運行的虛擬機環境時間不準的問題,雖然環境中都部署了 ntp/chronyd 進行時間同步,校準了時間,但是隔一段時間系統時間仍會被意外調慢約 2 分鐘。于是做了一個分析。大概包含下面這些內容:

  • 如何使用 eBPF LSM 編程攔截特定的操作
  • 如何修改 grub 內核啟動參數
  • grub 修改后未生效怎么辦
  • grub bls 技術是什么,grubby 命令使用
  • rust eBPF 編程實踐

萬事開頭難:使用 eBPF LSM 進行行為監控

為了精確定位修改系統時間的肇事者進程,利用 eBPF LSM(Linux Security Module)鉤子函數進行監控,觀測是誰在調用 settime,收集調用進程的詳細信息,包括進程 ID、進程名稱,以便后面做攔截。這里依然使用 rust aya 進行 eBPF 編程。

#[lsm]
pub fn hook_settime(ctx: LsmContext) -> i32 {
    let comm_bytes = match ctx.command() {
        Ok(bytes) => { bytes }
        Err(_) => { return 0; }
    };

    let len = comm_bytes.iter()
        .position(|&x| x == 0)
        .unwrap_or(comm_bytes.len());

    if len > 0 {
        let comm_str = unsafe { core::str::from_utf8_unchecked(&comm_bytes[..len]) };
        info!(&ctx, "lsm called: settime {}/{}", ctx.pid(), comm_str);
    }

    0
}

但是運行以后的 eBPF 程序以后,手動調用命令設置系統時間,eBPF 程序沒有任何輸出。經過一番調試,發現問題出在 LSM(Linux Security Module)的配置上。通過檢查 LSM 配置狀態:

cat /sys/kernel/security/lsm

capability,selinux

可以到當前系統僅啟用了 capability 和 selinux 模塊,缺少必需的 bpf 模塊支持。正確配置下的 LSM 輸出應該包含:

cat /sys/kernel/security/lsm

capability,yama,bpf

按常規步驟修改了 GRUB 配置 /etc/default/grub,在 GRUB_CMDLINE_LINUX 末尾新增 lsm 配置選項

lsm=ndlock,lockdown,yama,integrity,apparmor,bpf

接下來調用 grub2-mkconfig 命令更新 grub 配置,隨后重啟

grub2-mkconfig -o /boot/grub2/grub.cfg

但是一頓操作下來,重啟后發現 /sys/kernel/security/lsm 還是沒有 bpf 選項。查看 /proc/cmdline 也沒有對應的內核啟動時傳遞的啟動參數。

# 檢查當前 LSM 模塊狀態
$ cat /sys/kernel/security/lsm
capability,selinux    # 顯示配置未生效

# 檢查內核啟動參數
$ cat /proc/cmdline   # 未發現新增的 LSM 參數

BOOT_IMAGE=(hd0,msdos1)/vmlinuz-5.10.134-16.2.an8.x86_64 root=UUID=7b851053-3729-47c6-a73e-aec3083f4a82 ro resume=UUID=8c6bad2a-6a76-491d-99a2-90cbccf2ba33 rhgb quiet cgroup.memory=nokmem crashkernel=0M-2G:0M,2G-8G:192M,8G-:256M

從 dmesg 中啟動日志也可以同步確認。

$ dmesg -T | less

...
[三 11月  6 08:45:01 2024] Linux version 5.10.134-16.2.an8.x86_64 (mockbuild@anolis-build-02.openanolis.cn) (gcc (GCC) 8.5.0 20210514 (Anolis 8.5.0-18.0.4), GNU ld version 2.30-119.0.2.an8.2) #1 SMP Mon Mar 4 16:14:16 CST 2024
[三 11月  6 08:45:01 2024] Command line: BOOT_IMAGE=(hd0,msdos1)/vmlinuz-5.10.134-16.2.an8.x86_64 root=UUID=7b851053-3729-47c6-a73e-aec3083f4a82 ro resume=UUID=8c6bad2a-6a76-491d-99a2-90cbccf2ba33 rhgb quiet cgroup.memory=nokmem crashkernel=0M-2G:0M,2G-8G:192M,8G-:256M

...

為什么修改了 /etc/default/grub 未按預期生效

這里暫時不知道為什么沒有生效,去 /boot 目錄搜索相關的關鍵字,看下是不是有其它的配置文件

圖片圖片

找到了 /boot/loader/entries 文件,經過確認,這是因為這個 Linux 發行版比較新,引入了 BLS(Boot Loader Specification)功能。

BLS 是一個新的啟動加載項配置規范,旨在統一和簡化 Linux 系統的啟動配置管理。它由 Fedora/Red Hat 推出,現已被多個主流 Linux 發行版采用,配置文件位于 /boot/loader/entries/ 目錄。它可以不再需要手動編輯 grub.cfg 文件,同時支持多個內核版本的獨立配置。

可以使用 grubby 工具進行修改,常見的操作如下:

# 查看默認內核
grubby --default-kernel

# 查看所有內核信息
grubby --info=ALL

# 修改默認內核參數
grubby --args="xxx=xxx" --update-kernel=DEFAULT

# 刪除內核參數
grubby --update-kernel=ALL --remove-args="quiet"

比如 grubby info 命令可以看到當前的 grub 列表

grubby --info=ALL

index=0
kernel="/boot/vmlinuz-5.10.134-16.2.an8.x86_64"
args="ro resume=UUID=8c6bad2a-6a76-491d-99a2-90cbccf2ba33 rhgb quiet $tuned_params cgroup.memory=nokmem crashkernel=0M-2G:0M,2G-8G:192M,8G-:256M"
root="UUID=7b851053-3729-47c6-a73e-aec3083f4a82"
initrd="/boot/initramfs-5.10.134-16.2.an8.x86_64.img $tuned_initrd"
title="Anolis OS (5.10.134-16.2.an8.x86_64) 8"
id="de564eb41d9d4440b67b167404b867a4-5.10.134-16.2.an8.x86_64"

index=1
kernel="/boot/vmlinuz-0-rescue-de564eb41d9d4440b67b167404b867a4"
args="ro crashkernel=auto resume=UUID=8c6bad2a-6a76-491d-99a2-90cbccf2ba33 rhgb quiet"
root="UUID=7b851053-3729-47c6-a73e-aec3083f4a82"
initrd="/boot/initramfs-0-rescue-de564eb41d9d4440b67b167404b867a4.img"
title="Anolis OS (0-rescue-de564eb41d9d4440b67b167404b867a4) 8"
id="de564eb41d9d4440b67b167404b867a4-0-rescue"

有了這些知識,更新 grub 就變簡單了

# 使用 grubby 工具更新內核參數:

grubby --args="lsm=lockdown,capability,landlock,yama,apparmor,bpf" --update-kernel=DEFAULT

系統重啟后,通過檢查 LSM 配置確認更改已生效:

cat /sys/kernel/security/lsm

capability,yama,bpf

現在我們可以繼續使用 eBPF 程序來監控系統時間修改行為。

使用 bpf 攔截

在成功啟用 LSM BPF 支持后,我們快速定位到了時間異常調整的源頭,是因為虛擬機的 vm-agent 進程在定時做修改。(圖中的另外一個 date 是我在手動調用 date 修改時間)

圖片圖片

接下來要做的就是匹配 vm-agent,然后攔截它。

const VM_AGENT_BYTES: &'static [u8] = b"vm-agent";

#[lsm]
pub fn hook_settime(ctx: LsmContext) -> i32 {
    let comm_bytes = match ctx.command() {
        Ok(bytes) => { bytes }
        Err(_) => { return 0; }
    };

    let len = comm_bytes.iter()
        .position(|&x| x == 0)
        .unwrap_or(comm_bytes.len());

    if len == VM_AGENT_BYTES.len() && &comm_bytes[..len] == VM_AGENT_BYTES {
        info!(&ctx, "match vm-agent, return -1");
        return -1;
    }
    0
}

userspace 端的代碼比較簡單,加載 eBPF 程序,然后永久等待。

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    std::env::set_var("RUST_LOG", "debug");
    env_logger::init();

    let mut ebpf = aya::Ebpf::load(aya::include_bytes_aligned!(concat!(
        env!("OUT_DIR"),
        "/time-backward"
    )))?;

    if let Err(e) = aya_log::EbpfLogger::init(&mut ebpf) {
        warn!("failed to initialize eBPF logger: {}", e);
    }

    let btf = Btf::from_sys_fs()?;
    let program: &mut Lsm = ebpf.program_mut("hook_settime").unwrap().try_into()?;
    program.load("settime", &btf)?;
    program.attach()?;

    let ctrl_c = signal::ctrl_c();
    println!("Waiting for Ctrl-C...");
    ctrl_c.await?;
    println!("Exiting...");

    Ok(())
}

這樣實現以后,就有效阻止了 vm-agent 的修改時間操作(下面是一個模擬的、假的名為 vm-agent 的程序去設置時間的操作被拒絕)。

# 攔截效果驗證
./vm-agent +%T -s "10:07:48"
./vm-agent: cannot set date: Operation not permitted
10:07:48

把程序放到虛擬機中運行,就可以攔截掉搞事情的 vm-agent 了。

圖片圖片

由于沒有 vm-agent 亂改時間,現在系統的時間就正常了,經過長時間的觀測,時鐘非常準確。

圖片圖片

小結

vm-agent 應該是虛擬機的一個管理進程,可能的原因是物理機的時間慢 2min 左右,然后通過 vm-agent 來調整了當前主機所有虛擬機的時間。

ebpf 代碼很簡單,但是往往是它運行的環境需要比較小心的去準備。ps: 又學到了一點 grub 的好像沒什么用的知識。

責任編輯:武曉燕 來源: 張師傅的博客
相關推薦

2014-08-01 14:06:45

2021-12-12 18:12:13

Hbase線上問題

2020-04-08 10:30:19

Linux 攻擊 安全

2023-03-29 09:36:32

2018-01-15 14:50:49

APP轉讓App賬號

2010-04-01 22:16:21

2023-04-13 12:00:00

MySQLSQL線程

2012-02-01 16:48:54

后門Putty

2021-01-22 05:35:19

Lvm模塊Multipath

2010-09-07 11:16:14

SQL語句

2011-05-06 10:32:06

硬盤鍵盤

2011-06-28 10:41:50

DBA

2013-09-13 09:27:42

服務器LinuxApache

2013-12-24 13:59:03

2022-10-10 09:10:07

命令磁盤排查

2024-04-03 09:00:10

2010-09-13 10:43:22

SQL Server

2019-10-08 17:06:20

Python旅行朋友圈

2022-09-14 15:40:03

接口解決

2021-03-05 22:41:55

CDH集群CDH集群
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美日韩一区二区在线 | 亚洲成人福利在线观看 | 91九色视频在线 | 久草新在线 | 久久国产精品91 | 人妖videosex高潮另类 | 久久久激情视频 | 在线观看成年人视频 | 伊人中文字幕 | 不卡在线视频 | 夜夜艹| 福利精品| 午夜爽爽爽男女免费观看 | 亚洲精品视频免费观看 | 欧美一区二区三区在线 | 久青草影院 | 亚洲精品成人 | 在线免费av电影 | 免费在线国产视频 | 精品国产青草久久久久福利 | av中文字幕在线播放 | 黄色亚洲网站 | 亚洲免费在线视频 | 91精品www| 精品久久久久久久久久久久久久 | 成人免费网站 | 国产精品久久久久aaaa九色 | 91精品国产综合久久久亚洲 | 蜜桃av鲁一鲁一鲁一鲁 | 日韩精品人成在线播放 | 日韩爱爱网| 久久久久久免费精品一区二区三区 | 日本污视频 | 天天射视频 | 久草精品视频 | 久久精品福利 | 国产精品久久久久久久久久久免费看 | 国产精品激情 | 在线一区二区三区 | 午夜精品一区二区三区三上悠亚 | 亚洲国产成人精品女人久久久野战 |