面试题答案
一键面试#!/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
脚本说明
- 日志文件:定义了日志文件路径
log_file
,用于记录异常事件。 - 邮件接收者:定义了管理员邮箱
admin_email
,用于接收异常通知。 - 工作时间定义:定义了工作时间范围
workday_start
和workday_end
,以及工作的日期workdays
。 - 检查登录情况函数
check_login
:- 使用
lastlog
命令获取所有用户的最后登录信息,并通过awk
提取用户名、IP和日期时间。 - 判断登录时间是否在工作时间内,如果不在,则记录异常登录信息到日志文件并发送邮件通知管理员。
- 使用
- 检查权限变更情况函数
check_permission_change
:- 使用
diff
命令对比当前/etc/passwd
文件和备份文件,查找权限变更。 - 如果发现普通用户权限提升到root级别(
uid
变为0),记录异常信息到日志文件并发送邮件通知管理员。 - 每次检查后备份当前
/etc/passwd
文件。
- 使用
- 主程序
main
:- 初始化
passwd
备份文件(如果不存在)。 - 调用
check_login
和check_permission_change
函数进行检查。
- 初始化
为了提高效率,尽量减少不必要的命令执行和文件读取操作,并且在日志记录和邮件发送时避免过多的IO操作。同时,该脚本可通过 crontab
定期执行,例如:
0 2 * * * /path/to/your/script.sh
上述 crontab
配置表示每天凌晨2点执行该脚本。