MST

星途 面试题库

面试题:Bash脚本的复杂权限管理与系统状态监测

编写一个Bash脚本,用于定期检查系统中所有用户的登录情况和权限变更情况。若发现有异常登录(例如,非工作时间登录)或者权限异常变更(如普通用户权限提升到root级别),脚本要能发送邮件通知系统管理员,并详细记录相关事件。脚本需要考虑系统资源消耗和执行效率问题。
17.7万 热度难度
编程语言Bash

知识考点

AI 面试

面试题答案

一键面试
#!/bin/bash

# 定义日志文件路径
log_file="/var/log/user_audit.log"

# 定义邮件接收者
admin_email="admin@example.com"

# 定义工作时间(假设为周一到周五的9点到18点)
workday_start="09:00"
workday_end="18:00"
workdays="1 2 3 4 5"

# 检查登录情况
check_login() {
    lastlog | awk '{if(NR>2) print $1, $3, $4}' | while read user ip date_time; do
        day=$(date -d "$date_time" +%u)
        hour=$(date -d "$date_time" +%H:%M)
        if [[ " ${workdays[*]} " != *" $day "* ]] || [[ "$hour" < "$workday_start" || "$hour" > "$workday_end" ]]; then
            echo "异常登录: 用户 $user 于 $date_time 从 $ip 登录" | tee -a $log_file
            echo "异常登录: 用户 $user 于 $date_time 从 $ip 登录" | mail -s "系统异常登录通知" $admin_email
        fi
    done
}

# 检查权限变更情况
check_permission_change() {
    diff <(getent passwd | awk -F: '{print $1, $3}') <(cat /var/log/passwd_backup) | grep '>' | while read line; do
        user=$(echo $line | awk '{print $2}')
        new_uid=$(echo $line | awk '{print $4}')
        if [ "$new_uid" -eq 0 ]; then
            echo "权限异常变更: 用户 $user 权限提升到root级别" | tee -a $log_file
            echo "权限异常变更: 用户 $user 权限提升到root级别" | mail -s "系统权限异常变更通知" $admin_email
        fi
    done
    # 备份当前passwd文件
    cp /etc/passwd /var/log/passwd_backup
}

# 主程序
main() {
    # 初始化passwd备份文件
    if [ ! -f /var/log/passwd_backup ]; then
        cp /etc/passwd /var/log/passwd_backup
    fi

    check_login
    check_permission_change
}

main

脚本说明

  1. 日志文件:定义了日志文件路径 log_file,用于记录异常事件。
  2. 邮件接收者:定义了管理员邮箱 admin_email,用于接收异常通知。
  3. 工作时间定义:定义了工作时间范围 workday_startworkday_end,以及工作的日期 workdays
  4. 检查登录情况函数 check_login
    • 使用 lastlog 命令获取所有用户的最后登录信息,并通过 awk 提取用户名、IP和日期时间。
    • 判断登录时间是否在工作时间内,如果不在,则记录异常登录信息到日志文件并发送邮件通知管理员。
  5. 检查权限变更情况函数 check_permission_change
    • 使用 diff 命令对比当前 /etc/passwd 文件和备份文件,查找权限变更。
    • 如果发现普通用户权限提升到root级别(uid 变为0),记录异常信息到日志文件并发送邮件通知管理员。
    • 每次检查后备份当前 /etc/passwd 文件。
  6. 主程序 main
    • 初始化 passwd 备份文件(如果不存在)。
    • 调用 check_logincheck_permission_change 函数进行检查。

为了提高效率,尽量减少不必要的命令执行和文件读取操作,并且在日志记录和邮件发送时避免过多的IO操作。同时,该脚本可通过 crontab 定期执行,例如:

0 2 * * * /path/to/your/script.sh

上述 crontab 配置表示每天凌晨2点执行该脚本。