偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

一次使用 eBPF LSM 來解決系統(tǒng)時間被回調(diào)的記錄

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

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

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

萬事開頭難:使用 eBPF LSM 進行行為監(jiān)控

為了精確定位修改系統(tǒng)時間的肇事者進程,利用 eBPF LSM(Linux Security Module)鉤子函數(shù)進行監(jiān)控,觀測是誰在調(diào)用 settime,收集調(diào)用進程的詳細信息,包括進程 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 程序以后,手動調(diào)用命令設(shè)置系統(tǒng)時間,eBPF 程序沒有任何輸出。經(jīng)過一番調(diào)試,發(fā)現(xiàn)問題出在 LSM(Linux Security Module)的配置上。通過檢查 LSM 配置狀態(tài):

cat /sys/kernel/security/lsm

capability,selinux

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

cat /sys/kernel/security/lsm

capability,yama,bpf

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

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

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

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

但是一頓操作下來,重啟后發(fā)現(xiàn) /sys/kernel/security/lsm 還是沒有 bpf 選項。查看 /proc/cmdline 也沒有對應(yīng)的內(nèi)核啟動時傳遞的啟動參數(shù)。

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

# 檢查內(nèi)核啟動參數(shù)
$ cat /proc/cmdline   # 未發(fā)現(xiàn)新增的 LSM 參數(shù)

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 未按預(yù)期生效

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

圖片圖片

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

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

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

# 查看默認內(nèi)核
grubby --default-kernel

# 查看所有內(nèi)核信息
grubby --info=ALL

# 修改默認內(nèi)核參數(shù)
grubby --args="xxx=xxx" --update-kernel=DEFAULT

# 刪除內(nèi)核參數(shù)
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 工具更新內(nèi)核參數(shù):

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

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

cat /sys/kernel/security/lsm

capability,yama,bpf

現(xiàn)在我們可以繼續(xù)使用 eBPF 程序來監(jiān)控系統(tǒng)時間修改行為。

使用 bpf 攔截

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

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

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

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

圖片圖片

由于沒有 vm-agent 亂改時間,現(xiàn)在系統(tǒng)的時間就正常了,經(jīng)過長時間的觀測,時鐘非常準確。

圖片圖片

小結(jié)

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

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

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

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轉(zhuǎn)讓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

服務(wù)器LinuxApache

2024-04-03 09:00:10

2013-12-24 13:59:03

2022-10-10 09:10:07

命令磁盤排查

2010-09-13 10:43:22

SQL Server

2019-10-08 17:06:20

Python旅行朋友圈

2021-08-31 10:41:21

參數(shù)調(diào)優(yōu)代碼

2022-09-14 15:40:03

接口解決
點贊
收藏

51CTO技術(shù)棧公眾號