系统监控脚本

可以通过该脚本监控 Linux 系统中两个尤为棘手的地方——系统用户 shell 和有潜在危险的文件权限。

一、获得默认的shell审计功能

系统账户用于提供服务或执行特殊任务。一般来说,这类账户需要在 /etc/passwd 文件中有对应的记录,但禁止登录系统(root 账户是一个典型的例外)。

  • 防止有人使用这些账户登录的方法是,将其默认 shell 设置为 /bin/false、/usr/sbin/nologin 或 /sbin/nologin。
  • 当系统账户的默认 shell 从当前设置更改为 /bin/bash 时,就会出现问题
  • 虽然不良行为者在没有设置密码的情况下无法登录到该账户,但这仍会削弱系统的安全性
  • 因此,账户设置需要进行审计,以纠正不正确的默认 shell
  • 审计这种潜在问题的一种方法确定有多少账户的默认 shell 被设置为 falsenologin,然后定期检查这一数量。如果发现数量减少,则有必要进一步调查。
  • 首先,使用 cut 命令获取 /etc/passwd 文件中所有账户的默认 shell
# 1.对于/etc/passwd 文件,分隔符是冒号(:),账户的默认 shell 位于记录的第 7 个字段。
[root@VM-8-11-centos ~]# cut -d: -f7 /etc/passwd
/bin/bash
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/bin/sync
/sbin/shutdown
/sbin/halt
/sbin/nologin
...
[root@VM-8-11-centos ~]# 
  • 通过正则表达式过滤,只需要包含 false 和 nologin 的:
[root@VM-8-11-centos ~]# cut -d: -f7 /etc/passwd |
> grep -E "(false|nologin)"
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
...
[root@VM-8-11-centos ~]# 
  • 接下来,我们需要 wc 命令获取数量,通过 tee 命令写入报告文件,同时希望将这一信息显示给脚本用户:
# 1.系统中共有 21 个账户使用 false 或 nologin 作为默认 shell。
[root@VM-8-11-centos AuditReports]# cut -d: -f7 /etc/passwd |
> grep -E "(false|nologin)" | wc -l |
> tee mydefaultshell.rpt
21
[root@VM-8-11-centos AuditReports]# 
[root@VM-8-11-centos AuditReports]# cat mydefaultshell.rpt 
21
[root@VM-8-11-centos AuditReports]# 
  • 由于需要保留多份报告供以后比较,因此可以在报告名中加入日期
reportDir="/home/jan/scripts/AuditReports" 

# 2.使用 date 命令,将格式设置为以连字符分隔(%F)的当前日期。因为审计可能每天执行多次,所以我们还为时间戳添加了额外的时间标识信息(%s):自 1970 年 1 月 1 日以来的秒数。
reportDate="$(date +%F%s)" 
accountReport=$reportDir/AccountAudit$reportDate.rpt 
cat /etc/passwd | cut -d: -f7 | 
grep -E "(nologin|false)" | wc -l | 
tee $accountReport
  • 为了保护报告,需要设置不可变属性immutable attribute ),只要对文件设置了该属性,任何人都无法修改或删除此文件(以及一些其他特性)。要设置不可变属性,需要使用 chattr 命令,并且具有超级用户权限
# 1.设置不可变属性。
[root@VM-8-11-centos AuditReports]# sudo chattr +i mydefaultshell.rpt
[root@VM-8-11-centos AuditReports]# 

# 2.无法执行删除操作。
[root@VM-8-11-centos AuditReports]# rm -i mydefaultshell.rpt
rm: remove regular file ‘mydefaultshell.rpt’? y
rm: cannot remove ‘mydefaultshell.rpt’: Operation not permitted
[root@VM-8-11-centos AuditReports]# 

# 3.无法执行修改操作。
[root@VM-8-11-centos AuditReports]# echo "Hello" >> mydefaultshell.rpt
-bash: mydefaultshell.rpt: Permission denied
[root@VM-8-11-centos AuditReports]# 

# 4.查看文件内容。(未变化)
[root@VM-8-11-centos AuditReports]# cat mydefaultshell.rpt 
21
[root@VM-8-11-centos AuditReports]# 
  • 设置了不可变属性(有时也称作不可变位)之后,任何人都无法删除或修改该文件,哪怕具有超级用户权限也不行
  • 要想查看属性是否设置成功,可以使用 lsattr 命令,并在输出中查找 i
  • 要想移除不可变属性,需要再次使用 chattr 命令(具有超级用户权限),之后文件就能正常修改或删除了:
# 1.查看不可变属性。(输出中有 i 表示设置成功。)
[root@VM-8-11-centos AuditReports]# lsattr mydefaultshell.rpt
----i--------e-- mydefaultshell.rpt
[root@VM-8-11-centos AuditReports]# 

# 2.取消不可变属性。
[root@VM-8-11-centos AuditReports]# sudo chattr -i mydefaultshell.rpt
[root@VM-8-11-centos AuditReports]# 

# 3.再次查看不可变属性。(输出中没有 i 表示取消成功。)
[root@VM-8-11-centos AuditReports]# lsattr mydefaultshell.rpt
-------------e-- mydefaultshell.rpt
[root@VM-8-11-centos AuditReports]# 

# 4.执行修改操作。
[root@VM-8-11-centos AuditReports]# echo "Hello" >> mydefaultshell.rpt
[root@VM-8-11-centos AuditReports]# 

# 5.修改成功。
[root@VM-8-11-centos AuditReports]# cat mydefaultshell.rpt
21
Hello
[root@VM-8-11-centos AuditReports]# 

# 6.删除成功。
[root@VM-8-11-centos AuditReports]# rm -i mydefaultshell.rpt
rm: remove regular file ‘mydefaultshell.rpt’? y
[root@VM-8-11-centos AuditReports]# 
  • 我们的审计报告现在已经得到了保护,只剩下最后一个问题:将当前报告与上一份报告进行比较
  • ls 命令会按照从新到旧的顺序在单列中列出文件:
# 1.创建两份报告。
[root@VM-8-11-centos AuditReports]# reportDate="$(date +%F%s)"
[root@VM-8-11-centos AuditReports]# touch AccountAudit$reportDate.rpt
[root@VM-8-11-centos AuditReports]# 
[root@VM-8-11-centos AuditReports]# reportDate="$(date +%F%s)"
[root@VM-8-11-centos AuditReports]# touch AccountAudit$reportDate.rpt
[root@VM-8-11-centos AuditReports]# 

# 2.从新到旧排序。
[root@VM-8-11-centos AuditReports]# ls -1t AccountAudit*.rpt
AccountAudit2023-07-171689576240.rpt
AccountAudit2023-07-171689576199.rpt
[root@VM-8-11-centos AuditReports]# 
  • 之所以要以单列格式列出文件,是因为我们可以使用 sed 来获取次旧( the second oldest )报告的文件名进行比较:
prevReport="$(ls -1t $reportDir/AccountAudit*.rpt |
    sed -n '2p')"
    
# 如果没有次旧报告则提示。
if [ -z $prevReport ]; then
    echo
    echo "No previous false/nologin report exists to compare."
else
    echo
    echo "Previous report's false/nologin shells: "
    cat $prevReport
fi
#
  • 现在,所有的默认 shell 审计功能都已经完成,接下来可以看看权限审计功能的实现了。

二、权限审计功能

SUIDset user ID )和 SGIDset group ID )是两种很方便的权限设置,被 Linux 虚拟目录系统中的多个程序使用。然而,如果这些权限被无意甚至恶意地设置在程序上,导致其在不同的权限下运行,则会引发安全问题。因此,有必要在系统中对这两种潜在的“危险”权限进行审计,确保它们只被设置在该设置的地方。

  • 要找出具有这两种权限的文件和目录,需要使用 find 命令:
# 1.查找 SUID 和 SGID 两种权限的文本和目录。
# 超级用户权限,已根目录(/)为起点。
# -perm(permissions)选项可以使用八进制值指定要查找的具体权限。
# -perm 的值是/6000。八进制值 6 表示 find 要查找的权限是 SUID 和 SGID。
# 为了保持显示整洁,我们将错误消息(2)直接丢弃(/dev/null)。

[root@VM-8-11-centos AuditReports]# sudo find / -perm /6000 2>/dev/null
  • 注意事项:旧版本的 find 命令使用加号(+)表示忽略某些权限。如果你用的 Linux 版本比较旧,则可能需要把正斜线换成加号。

  • 可以将 find 命令中的 STDOUT 重定向到文件中,以便以后轻松查看。保存报告,随后与权限审计进行比较

reportDir="/home/christine/scripts/AuditReports"
reportDate="$(date +%F%s)"
permReport=$reportDir/PermissionAudit$reportDate.rpt
#
sudo find / -perm /6000 >$permReport 2>/dev/null
  • 权限审计报告现在已保存,我们可以将该报告的早期版本与当前版本进行比较,通知脚本用户两者之间的差异

  • 文件权限发生变化则表明,要么安装的新软件有此需求,要么文件被错误(或恶意)地设置为这些权限。

  • 为了进行比较,可以使用 diff 命令。此命令可以比较文件,并将两者之间的差异输出到 STDOUT。

  • 注意事项

    • diff 命令只会逐行对文件进行比较。
    • 因此,diff 会比较两份报告的第一行,然后是第二行、第三行,以此类推。
    • 如果由于要安装软件,添加了一个或一批新文件,而这些文件需要 SUID 权限或 SGID 权限,那么在下一次审计时,diff会显示大量的差异
    • 为了解决这个潜在的问题,可以在 diff 命令中使用 -q 选项或 –brief 选项,只显示消息,说明这两份报告存在不同。
  • 在进行比对之前,还需要核实另一份报告是否存在。相关代码如下:

prevReport="$(ls -1t $reportDir/PermissionAudit*.rpt |
    sed -n '2p')"
#
if [ -z $prevReport ]; then
    echo
    echo "No previous permission report exists to compare."
else
    echo
    echo "Differences between this report and the last: "
    #
    differences=$(diff $permReport $prevReport)
    #
    if [ -z "$differences" ]; then
        echo "No differences exist."
    else
        echo $differences
    fi
fi
  • 注意事项:不仅要检查另一份报告,还要查看两份报告之间是否确实存在差异。如果不存在差异,则仅显示 No differences exist。

三、创建脚本

现在,我们已经实现了审计脚本所有的主要功能,可以将它们组合在一起了。

  • 对于这个 bash shell 脚本,我们打算使用 getopts 并提供两个选项:-A 选项仅执行账户审计,-p 选项仅执行权限审计
  • 虽然可以通过组合这两个选项(-Ap)来执行两项审计,但如果没有指定任何选项,则也可以实现相同的效果,这算是为用户提供了一定的灵活性
  • 因而也可以通过 cronanacron 更轻松地将该脚本引入自动化环境。
  • 下面是完整的 Audit_System.sh 脚本:
#!/bin/bash
#
####################  初始化变量  ####################
runAccountAudit="false"
runPermAudit="false"
#
reportDir="/home/jan/scripts/AuditReports"
#

####################  获取选项  ####################
#
while getopts :Ap opt; do
    case "$opt" in
    A) runAccountAudit="true" ;;
    p) runPermAudit="true" ;;
    *)
        echo "Not a valid option."
        echo "Valid options are: -A, -p, or -Ap"
        exit
        ;;
    esac
done
#
# 如果没有选项,则将标记变量设置为true。
#
if [ $OPTIND -eq 1 ]; then

    runAccountAudit="true"
    runPermAudit="true"
fi
#

####################  执行账户审计  ####################
#
if [ $runAccountAudit = "true" ]; then
    echo
    echo "****** Account Audit *****"
    echo
    #
    # 确定当前的 false/nologin shell 计数。
    #
    echo "Number of current false/nologin shells: "
    #
    reportDate="$(date +%F%s)"
    accountReport=$reportDir/AccountAudit$reportDate.rpt
    #
    # 创建当前报表。
    cat /etc/passwd | cut -d: -f7 |
        grep -E "(nologin|false)" | wc -l |
        tee $accountReport
    #
    # 更改报告的属性。
    sudo chattr +i $accountReport
    #
    # 显示过去的 false/nologin shell 计数。
    #
    prevReport="$(ls -1t $reportDir/AccountAudit*.rpt |
        sed -n '2p')"
    if [ -z $prevReport ]; then
        echo
        echo "No previous false/nologin report exists to compare."
    else
        echo
        echo "Previous report's false/nologin shells: "
        cat $prevReport
    fi
fi
#
####################  权限审计  ####################
#
if [ $runPermAudit = "true" ]; then
    echo
    echo "****** SUID/SGID Audit *****"
    echo
    reportDate="$(date +%F%s)"
    permReport=$reportDir/PermissionAudit$reportDate.rpt
    #
    # 创建当前报表。
    echo "Creating report. This may take a while..."
    sudo find / -perm /6000 >$permReport 2>/dev/null
    #
    # 更改报告的属性。
    sudo chattr +i $permReport
    #
    # 与次旧权限报告进行比较。
    #
    prevReport="$(ls -1t $reportDir/PermissionAudit*.rpt |
        sed -n '2p')"
    #
    if [ -z $prevReport ]; then
        echo
        echo "No previous permission report exists to compare."
    else
        echo
        echo "Differences between this report and the last: "
        #
        differences=$(diff $permReport $prevReport)
        #
        if [ -z "$differences" ]; then
            echo "No differences exist."
        else
            echo $differences
        fi
    fi
fi
#
exit

四、运行脚本

  • 在运行该脚本之前,需要先创建审计报告目录。目录中要保存审计报告,在选择目录位置时一定要谨慎:
[root@VM-8-11-centos scripts]# mkdir AuditReports
[root@VM-8-11-centos scripts]# 
[root@VM-8-11-centos scripts]# ls AuditReports/
[root@VM-8-11-centos scripts]# 
  • 审计报告目录创建好之后,就可以启动脚本了。先使用 -A 选项执行账户默认 shell 审计
# 1.赋予执行权限。
[root@VM-8-11-centos scripts]# chmod u+x Audit_System.sh 
[root@VM-8-11-centos scripts]# 

# 2.执行脚本。(-A 选项仅执行账户审计。)
# 注意,系统中共有 21 个账户使用 false 或 nologin 作为默认 shell。另外,由于还没有其他的账户审计报告,因此脚本提醒我们没有可以进行比较的报告。
[root@VM-8-11-centos scripts]# ./Audit_System.sh -A

****** Account Audit *****

Number of current false/nologin shells: 
21

No previous false/nologin report exists to compare.
[root@VM-8-11-centos scripts]# 
  • 再用 -p 选项试试权限审计功能:
# 1.执行脚本。(-p 选项仅执行权限审计。)
[root@VM-8-11-centos scripts]# ./Audit_System.sh -p

****** SUID/SGID Audit *****

Creating report. This may take a while...

No previous permission report exists to compare.
[root@VM-8-11-centos scripts]# 

# 2.一切正常。AuditReports 目录中现在已经有了两份审计报告。
[root@VM-8-11-centos scripts]# ls -1 AuditReports/
AccountAudit2023-07-181689664305.rpt
PermissionAudit2023-07-181689664406.rpt
[root@VM-8-11-centos scripts]# 
  • 现在,让我们添加一个具有 SUID 权限的伪造文件,看看脚本是否能发现。这次也使用两个选项运行脚本(执行两项审计):
# 1.创建伪造文件。
[root@VM-8-11-centos scripts]# touch sneakyFile.exe
[root@VM-8-11-centos scripts]# 

# 2.设置 SUID 权限。
[root@VM-8-11-centos scripts]# chmod u+xs sneakyFile.exe
[root@VM-8-11-centos scripts]# 

# 3.执行脚本。(两项审计不仅都执行了,而且权限审计还发现了 sneakyFile.exe 的 SUID 权限。)
[root@VM-8-11-centos scripts]# ./Audit_System.sh -Ap

****** Account Audit *****

Number of current false/nologin shells: 
21

Previous report's false/nologin shells: 
21

****** SUID/SGID Audit *****

Creating report. This may take a while...

Differences between this report and the last: 
1d0 < /home/jan/scripts/sneakyFile.exe
[root@VM-8-11-centos scripts]# 
  • 脚本没有问题,可以开始考虑如何改进了。下面是一些参考建议

    • 添加额外的审计功能,比如有关新增账户登录失败的报告。
    • 限制保存在 AuditReports 目录中的报告数量
    • 使用校验和(详见 man SHA512sum)提高安全性,确保报告不会被篡改。
  • 注意事项

    • 虽然这个脚本对审计工作很方便,但不要把它当作入侵检测系统intrusion detection system,IDS)。
    • IDS 可以监视网络和/或系统中运行的应用程序,寻找可疑行为。
    • IDS 提供了各种功能,比如阻止攻击和报告发现的潜在恶意行为。
    • 如果担心意图不轨人员破坏系统,那么 IDS(比如 Snort、DenyHosts 和 Fail2ban)是你的最佳选择。

五、结束语


“-------怕什么真理无穷,进一寸有一寸的欢喜。”

微信公众号搜索:饺子泡牛奶

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值