小议用户操作日志记录

Author Avatar
xF0rk 4月 24, 2020

在企业 IT 运维中普遍存在系统账号密码使用、系统运维操作、外部人员访问等方面的安全隐患,在企业员工 SSH 登录操作时进行日志记录,可以让 IT 运维过程透明化,便于运维经验传承和运维安全事故的责任认定;同时通过操作命令日志记录,在机器被恶意攻击者入侵时,可以方便溯源定位攻击。

操作记录

随着企业业务不断发展壮大,运维安全问题越发严峻,企业内部管控要求需要能够知道哪个运维人员在什么时间通过什么 IP 访问了什么业务服务器,同时还需要知道在业务服务器上做了什么操作。默认情况下系统日志可读性较差、零散、可删除、篡改,并且账号与运维人员无法一一对应,导致企业管控缺乏有效的运维审计能力,通常企业内部会额外设置操作日志记录,增强内部事后追溯能力。

大多数企业的业务系统都是基于 Linux 系统架构、运行,而在 Linux 系统中用户可通过 SSH 或其他管理工具(例如 Puppet)对系统进行管理、配置。如下所示,企业员工可通过 SHELL 库函数 间接通过 系统调用 来访问 系统内核 及相关资源;也可直接通过相关 工具 直接通过 系统调用 实现与 系统内核 的交互操作。

  • SHELL 为用户提供对话环境,用户从键盘输入命令,SHELL 接收到用户输入的命令,将命令传送至操作系统执行,并将执行结果返回给用户;SHELL 还是一个命令解释器,解释用户输入的命令,支持变量、条件判断、循环条件等。常见的 SHELLsh (Bourne Shell)bash (Bourne Again Shell)csh (C Shell)zsh (Z Shell) 等,通常用户可通过 SSH 或终端获取 SHELL 对话环境;

  • 系统调用为管理操作提供了调用接口,例如 execveexecveat 提供命令执行接口,用户可直接通过远程或本地工具直接在目标机器执行命令,例如使用 VNC 图形化管理 Linux 系统、通过 Puppet 远程管理机器等;

记录方案

如上所示,根据用户远程管理系统方式和与内核交互模式不同,可在不同过程、阶段记录用户操作日志,实现指定机器的操作日志记录,以下将介绍在不同阶段进行操作日志记录方法

SSH 网关

SSH 网关,顾名思义就是能够将用户通过 SSH 通道所执行的操作命令转发至目标服务器,同时实时记录用户的所输入的命令和目标服务器的输出响应。如下通过 SSH 网关直接登录 10.211.55.3 目标服务器,并执行了命令 ifconfigwhoami

SSH 网关所记录的用户的操作日志及服务端响应输出

SHELL 特性

HISTORY 记录

Linux 结合 history 系统命令,将用户操作命令通过 rsyslog 写入到本地文件或发送到远程日志服务器,如下,在 /etc/profile.d 中添加 sshaudit.sh 进行配置

#/bin/bash

AUDIT_USER=`whoami`

AUDIT_USER_IP=`who -u am i 2>/dev/null| awk '{print $NF}'|sed -e 's/[()]//g'`
if [ "$AUDIT_USER_IP" = "" ];then
  AUTID_USER_IP=`hostname`
fi

export HISTSIZE=4096
export PROMPT_COMMAND='RETRN_VAL=$?;logger -p local4.info "$AUDIT_USER $AUDIT_USER_IP $(history 1 | sed "s/^[ ]*[0-9]\+[ ]*//") $RETRN_VAL"'

readonly AUDIT_USER
readonly AUDIT_USER_IP
readonly HISTSIZE
readonly PROMPT_COMMAND

logger 中的日志实时发送至远程日志服务器或写入到本地文件中,如下,在 /etc/rsyslog.conf 配置 rsyslog 中的日志写入到本地文件

local4.info                    /tmp/sshaudit/sshaudit.log

如下图所示, /tmp/sshaudit/sshaudit.log 中记录的操作日志

如下,可看到登录机器时终端环境变量中所设置的审计相关变量

SCRIPT 记录

Linux 中的 script 能够录制键盘输入、输出结果,并保存至相应的文件中,如下图所示,script 默认将操作记录存储至 typescript 文件中,打开 typescript 可看到所执行的操作日志

重编译 SHELL

Linux 系统中有多种类型的 SHELL 程序,此处以 bash 为例

下载 bash 源码,bash 从 4.1 版本开始支持 rsyslog 记录,下载 4.4.18 版本 bash 源码,修改 config-top.h 代码中 syslog 输出的日志类型及级别

应用编译配置及环境,执行 ./configure --prefix=/usr/local/bashaudit

执行命令 make && make install,实现代码编译并安装至指定目录

调整系统中 syslog 日志记录配置,将 bash 中的日志记录至 /tmp/sshaudit/bashaudit.log 文件中

通过编译的 bash 测试命令记录是否正常,执行命令 idwhoamiifconfig

如下,在定义的日志记录文件 /tmp/sshaudit/bashaudit.log 中成功记录所执行的测试命令

系统调用记录

为审计、记录用户操作命令,可在系统内核中定义相应的规则(HOOK 系统调用),过滤指定系统事件来实现用户操作的审计记录,常见的 HOOK 方法有 AuditdBPFLD_PRELOAD

AUDITD 操作记录

AUDITD 简介

系统中 auditdLinux 审计系统中用户空间的一个组件,负责接收内核中发生的事件(包括系统调用、文件访问等),并将相应的事件记录写入到磁盘,auditd 在系统中默认安装,框架结构如下所示。

Linux 系统内核记录用户、任务、系统调用结束事件日志,同时结合 Exclude 规则来过滤事件,将过滤后的事件发送至用户空间的应用程序,auditd 是核心守护进程,用于接受内核中产生的事件,并记录到 auditd.log 中,机器管理员可通过 ausearchaureport 来查看日志,auditd 启动时自动读取 auditd.conf 配置,同时加载 audit.rules 中的规则,控制内核中事件监听及过滤行为;同时也可直接通过 auditctl 来控制内核事件监听和过滤规则。

AUDITD 规则配置

如下所示,配置 auditd 过滤系统内核中 execveexecveat 系统调用的事件

使用工具 ausearch -i 查看、翻译(将十六进制转换成 ascii 文本) /var/log/auditd/auditd.log 中的事件日志,如下可获取目标机器所执行的命令

BPF 操作记录

BPF 简介

BPF 设计之初用于 Linux 系统内核流量数据包过滤,例如在使用 tcpdump 工具时可自定义表达式,内核将对应的表达式编译成 BPF 字节码在内核中虚拟机运行并过滤相关流量数据包。eBPF,(Extended BPF,也可直接称为 BPF),其允许过滤更多类型的事件日志,而不仅仅局限于流量数据包;BPF 可用于构建 SDNDDoS 防御、入侵检测工具,其工作流如下所示。

BPF 要求系统内核编译过程中开启 CONFIG_BPF_SYSCALL,同时内核版本至少为 4.4,内核中相关功能发布与其版本对应关系如下

BPF 编译配置

笔者使用 gobpf 项目主页 的测试用例 execsnoop 进行了测试,execsnoop 依赖 BCC 框架支撑 项目主页

编译相关依赖库过程比较复杂,同时对机器计算能力也有一定要求,笔者折腾了 很长很长很长很长很长 时间,官方文档说明可直接使用 yum 安装的 bcc 工具,但笔者实践的时候发现安装的依赖库库无法使用,排查确认发现是由于 bcc 的代码进行了调整,而在 yum 仓库中的发行版本未及时更新

编译 bcc 依赖库成功后安装如下

用户在另一个终端所执行的操作,可通过 execsnoop 模块进行监控、记录到相关操作日志如下

LD_PRELOAD 操作记录

LD_PRELOAD 简介

LD_PRELOADLinux 系统的环境变量(可在 /etc/ld.so.preload 文件中定义),其可影响程序运行时的链接库,允许在程序运行前优先加载动态链接库,可在主程序和动态链接库中加载其他动态链接库,甚至可覆盖正常的函数库,来实现对指定系统调用的监控记录,如下

LD_PRELOAD 编译配置

测试 LD_PRELOAD 所使用的代码如下,其主要监控 execve 方法调用,同时将所执行的命令通过 syslog 记录到 LOCAL6 INFO

修改系统中 /etc/rsyslog.conf 配置,将 LOCAL6 INFO 的日志记录到文件 /tmp/sshaudit/bashld.log

如下为日志记录文件中所记录的用户的操作

方案优劣

不同审计日志记录方案使用了不同的技术栈,各有所长,各有所短,企业管理员可结合实际业务情况进行选取,各方案优劣如下所示

方案 优劣
SSH 网关 系统用户权限配置简单,可从用户视角记录命令输入、执行输出;若将待执行内容写入脚本,然后再执行脚本,可绕过操作日志的记录,同时系统开发、维护成本较高,开源的方案有 Jumpserver、Teleport 等
HISTORY 记录 依赖于 SHELL 特性,配置简单,对系统无侵入性,但可轻易绕过,用户可从设置 HISTORY、HISTFILE、HISTSAVE 等环境变量干扰 HISTORY 正常记录功能
SCRIPT 记录 配置简单,对系统无侵入性,但可绕过,无法实现脚本的操作审计
重编译 SHELL 对系统用户的操作具有一定的侵入性,重依赖于系统的 SHELL 应用程序,可较简单绕过,例如系统通过重编译 BASH 来实现用户操作日志记录,则用户可使用 SH、ZSH 等来绕过操作审计
AUDITD 记录 系统中默认安装的审计工具,对系统性能影响较高,产生的操作审计日志较多,可审计监控脚本中的操作命令,用户绕过难度较高
BPF 记录 能够监控、审计用户或脚本中相关命令执行,对系统内核版本有一定的要求,用户绕过难度较高
LD_PRELOAD 记录 可审计监控脚本中的操作命令,但对系统侵入性过大,所有应用进程的调用都会使用动态链接库,对动态链接库的健壮性、可靠性有较高要求,用户也可较简单地绕过

参考链接

  1. Linux 用户空间审计工具 audit 链接
  2. Shell是什么? 链接