Centos基线自动化检查脚本

news2024/11/26 2:40:00

此脚本是一个用于检查Linux系统安全配置的Bash脚本。它通过多项安全标准对系统进行评估,主要检查以下内容:

  • IP地址获取:脚本首先获取主机的IP地址,确保其以10.115开头。

  • 密码策略检查:
    检查最小密码长度(PASS_MIN_LEN),确保至少为12。
    检查密码最大生存周期(PASS_MAX_DAYS),确保为90天。
    检查密码复杂度策略,确保满足特定要求。

  • 用户权限与账户管理:
    检查是否限制普通用户使用su命令切换到root用户。
    确认是否存在普通用户账户。
    检查是否删除了不必要的工作账户(如listen, gdm等)。

  • 系统安全配置:
    检查文件和目录的默认权限(umask),确保为027。
    检查命令行界面的超时退出设置(TMOUT),确保为300秒。
    确保启用了syslog日志审计。
    确认日志文件的权限设置。

  • FTP与SSH配置:
    检查FTP匿名用户是否禁用,VSFTP是否禁用匿名登录。
    确保root用户的FTP登录被禁用。
    检查SSH服务的状态,确保其启用。
    危险文件检查:查找潜在危险文件(如/etc/hosts.equiv等)并确认其不存在。

  • Telnet检查:确认Telnet服务未启用,检查相关配置文件。

  • 服务与端口管理:检查不必要的服务和端口是否关闭。

  • DNS配置检查:确保DNS配置符合指定的标准。

最后,脚本会输出不合格项和检查失败项的详细信息,并提供检查的汇总,包括总检查项数、合格数、不合格数和检查失败数。
该脚本适用于系统管理员定期审计和加强Linux系统的安全性。

脚本代码:

#!/bin/bash

# 初始化计数器
total_checks=0
pass_checks=0
fail_checks=0
not_found_checks=0
declare -a results

# 获取主机的IP地址(以10.123开头)
ip_address=$(ip addr | awk '/inet / && /10\.123\./ {gsub(/\/[0-9]+/, "", $2); print $2}')
echo "主机IP:$ip_address"

# 检查口令最小长度
total_checks=$((total_checks + 1))
PASS_MIN_LEN=$(grep '^PASS_MIN_LEN' /etc/login.defs | awk '{print $2}')
if [[ -n $PASS_MIN_LEN ]]; then
    if [[ $PASS_MIN_LEN -ge 12 ]]; then
        pass_checks=$((pass_checks + 1))
    else
        results+=("PASS_MIN_LEN ($PASS_MIN_LEN) 不符合标准")
        fail_checks=$((fail_checks + 1))
    fi
else
    results+=("PASS_MIN_LEN 未找到")
    not_found_checks=$((not_found_checks + 1))
fi

# 检查口令生存周期
total_checks=$((total_checks + 1))
PASS_MAX_DAYS=$(grep '^PASS_MAX_DAYS' /etc/login.defs | awk '{print $2}')
if [[ -n $PASS_MAX_DAYS ]]; then
    if [[ $PASS_MAX_DAYS -eq 90 ]]; then
        pass_checks=$((pass_checks + 1))
    else
        results+=("PASS_MAX_DAYS ($PASS_MAX_DAYS) 不符合标准")
        fail_checks=$((fail_checks + 1))
    fi
else
    results+=("PASS_MAX_DAYS 未找到")
    not_found_checks=$((not_found_checks + 1))
fi

# 检查密码复杂度策略
total_checks=$((total_checks + 1))
PAM_CONFIG="/etc/pam.d/system-auth"

# 检查未注释的密码复杂度策略
if grep -q "^[^#]*password\s\+requisite\s\+pam_pwquality.so" "$PAM_CONFIG"; then
    # 直接提取行并检查参数
    line=$(grep "^[^#]*password\s\+requisite\s\+pam_pwquality.so" "$PAM_CONFIG")
    
    # 提取每个参数
    ucredit=$(echo "$line" | grep -o 'ucredit=[-0-9]*' | cut -d'=' -f2)
    lcredit=$(echo "$line" | grep -o 'lcredit=[-0-9]*' | cut -d'=' -f2)
    dcredit=$(echo "$line" | grep -o 'dcredit=[-0-9]*' | cut -d'=' -f2)
    ocredit=$(echo "$line" | grep -o 'ocredit=[-0-9]*' | cut -d'=' -f2)

    # 检查参数值是否均为 -1
    if [[ "$ucredit" == "-1" && "$lcredit" == "-1" && "$dcredit" == "-1" && "$ocredit" == "-1" ]]; then
        pass_checks=$((pass_checks + 1))
    else
        results+=("密码复杂度配置不符合标准: ucredit=$ucredit, lcredit=$lcredit, dcredit=$dcredit, ocredit=$ocredit")
        fail_checks=$((fail_checks + 1))
    fi
else
    results+=("未配置有效的密码复杂度策略")
    not_found_checks=$((not_found_checks + 1))
fi
# 检查是否限制用户su到root
total_checks=$((total_checks + 1))
# 检查 pam_rootok.so
if grep -q '^[^#]*auth\s\+sufficient\s\+pam_rootok.so' /etc/pam.d/su; then
    pass_checks=$((pass_checks + 1))
else
    echo "未找到: auth sufficient pam_rootok.so"
fi

# 检查 pam_wheel.so
if grep -q '^[^#]*auth\s\+required\s\+pam_wheel.so\s\+group=wheel' /etc/pam.d/su; then
    pass_checks=$((pass_checks + 1))
else
    echo "未找到: auth required pam_wheel.so group=wheel"
fi

# 根据找到的情况更新失败检查数
if [ "$pass_checks" -lt 2 ]; then
    results+=("用户su限制不符合标准")
    fail_checks=$((fail_checks + 1))
fi


# 检查是否按用户分配账号
total_checks=$((total_checks + 1))
if grep -qE '^[^:]+:.*' /etc/passwd; then
    pass_checks=$((pass_checks + 1))
else
    results+=("不存在普通用户账号")
    fail_checks=$((fail_checks + 1))
fi

# 检查是否删除工作账号
for user in listen gdm webservd nobody nobody4 noaccess; do
    total_checks=$((total_checks + 1))
    if grep -q "^$user:" /etc/passwd; then
        results+=("账号 $user 存在")
        fail_checks=$((fail_checks + 1))
    else
        pass_checks=$((pass_checks + 1))
    fi
done

# 检查是否设置文件与目录缺省权限
total_checks=$((total_checks + 1))
UMASK=$(grep '^umask' /etc/profile)
if [[ -n $UMASK ]]; then
    if [[ $UMASK == *"027"* ]]; then
        pass_checks=$((pass_checks + 1))
    else
        results+=("umask 设置不符合标准")
        fail_checks=$((fail_checks + 1))
    fi
else
    results+=("umask 未找到")
    not_found_checks=$((not_found_checks + 1))
fi

# 检查命令行界面超时退出
total_checks=$((total_checks + 1))
TMOUT=$(grep '^export TMOUT=' /etc/profile)
if [[ -n $TMOUT ]]; then
    # 提取 TMOUT 的值
    TMOUT_VALUE=$(echo "$TMOUT" | cut -d'=' -f2 | tr -d ' ')
    
    # 检查是否设置为 300
    if [[ "$TMOUT_VALUE" == "300" ]]; then
        pass_checks=$((pass_checks + 1))
    else
        results+=("TMOUT 设置不符合标准,当前值为: $TMOUT_VALUE")
        fail_checks=$((fail_checks + 1))
    fi
else
    results+=("TMOUT 未找到")
    not_found_checks=$((not_found_checks + 1))
fi

# 检查是否启用syslog日志审计
total_checks=$((total_checks + 1))
if systemctl is-active --quiet rsyslog; then
    pass_checks=$((pass_checks + 1))
else
    results+=("syslog 日志审计未启用")
    fail_checks=$((fail_checks + 1))
fi

# 检查日志文件权限
declare -A expected_permissions=(
    ["/var/log/cron"]="775"
    ["/var/log/secure"]="775"
    ["/var/log/messages"]="755"
    ["/var/log/maillog"]="775"
    ["/var/log/boot.log"]="775"
    ["/var/log/mail"]="775"
    ["/var/log/spooler"]="775"
)

# 检查每个日志文件的权限
for file in "${!expected_permissions[@]}"; do
    total_checks=$((total_checks + 1))
    
    if [[ -f $file ]]; then
        perms=$(ls -ld "$file" | awk '{print $1}')
        
        # 检查其他用户权限
        if [[ ${perms:8:1} == "w" ]]; then
            results+=("$file 权限不符合标准")
            fail_checks=$((fail_checks + 1))
        else
            pass_checks=$((pass_checks + 1))
        fi
    else
        # 文件不存在时将其视为符合标准
        pass_checks=$((pass_checks + 1))  # 符合标准
    fi
done


# 检查FTP及SSH相关配置
total_checks=$((total_checks + 1))
if ! grep -q 'ftp' /etc/passwd; then
    pass_checks=$((pass_checks + 1))
else
    results+=("FTP匿名用户未禁用")
    fail_checks=$((fail_checks + 1))
fi

# 检查VSFTP配置
total_checks=$((total_checks + 1))
if [ ! -f /etc/vsftpd.conf ] || grep -q "anonymous_enable=NO" /etc/vsftpd.conf; then
    pass_checks=$((pass_checks + 1))
else
    results+=("VSFTP未禁用匿名登录")
    fail_checks=$((fail_checks + 1))
fi

# 检查root用户FTP登录
total_checks=$((total_checks + 1))
if [ ! -f /etc/ftpusers ] || grep -q 'root' /etc/ftpusers; then
    pass_checks=$((pass_checks + 1))
else
    results+=("root 用户FTP登录未禁用")
    fail_checks=$((fail_checks + 1))
fi

# 检查SSH服务状态
total_checks=$((total_checks + 1))
if systemctl is-active --quiet sshd; then
    pass_checks=$((pass_checks + 1))
else
    results+=("SSH服务未启用")
    fail_checks=$((fail_checks + 1))
fi

# 检查是否删除潜在危险文件
for file in /etc/hosts.equiv /etc/.rhosts /etc/.netrc; do
    total_checks=$((total_checks + 1))
    if [[ -e $file ]]; then
        results+=("$file 存在")
        fail_checks=$((fail_checks + 1))
    else
        pass_checks=$((pass_checks + 1))
    fi
done

# 检查是否安装了 telnet 和 telnet-server
total_checks=$((total_checks + 1))
if rpm -qa | grep -qE "telnet|telnet-server"; then
    # 如果安装了,检查 /etc/xinetd.d/telnet 配置
    total_checks=$((total_checks + 1))
    if [[ -f /etc/xinetd.d/telnet ]]; then
        disable_line=$(grep -E "^disable" /etc/xinetd.d/telnet)
        if [[ $disable_line == "disable = no" ]]; then
            results+=("Telnet服务仍在启用")
            fail_checks=$((fail_checks + 1))
        else
            pass_checks=$((pass_checks + 1))
        fi
    else
        pass_checks=$((pass_checks + 1))
    fi
else
    pass_checks=$((pass_checks + 1))
fi

# 检查是否关闭不必要的服务和端口
total_checks=$((total_checks + 1))
if ps -ef | grep -q '[f]tp'; then
    results+=("FTP服务仍在运行")
    fail_checks=$((fail_checks + 1))
else
    pass_checks=$((pass_checks + 1))
fi

# 检查DNS配置
total_checks=$((total_checks + 1))
DNS_IPS=("114.114.114.114" "233.5.5.5") # 指定的DNS IP地址
DNS_CONFIG=$(grep -E '^nameserver' /etc/resolv.conf | awk '{print $2}')

if [[ -n $DNS_CONFIG ]]; then
    found_ip=false
    for ip in "${DNS_IPS[@]}"; do
        if [[ "$DNS_CONFIG" == *"$ip"* ]]; then
            found_ip=true
            break
        fi
    done
    if [[ $found_ip == false ]]; then
        results+=("DNS配置不符合标准: 未找到指定的DNS IP")
        fail_checks=$((fail_checks + 1))
    else
        pass_checks=$((pass_checks + 1)) # 如果找到了至少一个IP,增加合格计数
    fi
else
    results+=("DNS配置未找到")
    not_found_checks=$((not_found_checks + 1))
fi

# 输出不合格项和检查失败项
if [ ${#results[@]} -ne 0 ]; then
    echo "不合格项和检查失败项:"
    for result in "${results[@]}"; do
        echo "$result"
    done
else
    echo "所有检查项均符合标准。"
fi

# 输出汇总
echo ""
echo "检查汇总:"
echo "总检查项数: $total_checks"
echo "合格数: $pass_checks"
echo "不合格数: $fail_checks"
echo "检查失败数: $not_found_checks"

检查结果示例:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2210620.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

解析 wxPython 和 Pandas 实现的 XLSX 分析器和网页打开器

在本文中,我们将分析一个使用 wxPython 和 Pandas 库编写的 Python 应用程序,名为 “XLSX Analyzer and Web Opener”。该应用程序的核心功能是:从 Excel 文件中读取数据并显示在网格中,此外,还允许用户使用 Google Ch…

力扣面试150 汇总区间 双指针 StringBuilder

Problem: 228. 汇总区间 &#x1f468;‍&#x1f3eb; 参考题解 import java.util.ArrayList; import java.util.List;class Solution {public List<String> summaryRanges(int[] nums) {List<String> ret new ArrayList<String>(); // 存储结果的列表in…

Faster R-CNN模型微调检测航拍图像中的小物体

关于深度实战社区 我们是一个深度学习领域的独立工作室。团队成员有&#xff1a;中科大硕士、纽约大学硕士、浙江大学硕士、华东理工博士等&#xff0c;曾在腾讯、百度、德勤等担任算法工程师/产品经理。全网20多万粉丝&#xff0c;拥有2篇国家级人工智能发明专利。 社区特色…

【排序算法】选择排序的全面剖析(含详细图解)

在之前文章中我们了解到了插入排序&#x1f449;【插入排序】&#xff0c;现在我们来学习排序算法中的直接选择排序。 目录 &#x1f4af;引言 &#x1f4af;选择排序的原理 &#x1f4af;选择排序的实现步骤 ⭐简单选择排序&#xff08;以升序为例&#xff09; ⭐代码实…

Human-M3 多模态姿态估计数据集-初步解读

文章概述(个人总结):该论文重点提出一个用于人体姿态估计的RGB+点云数据集,针对该多模态数据集,作者阐述了数据集的收集、数据标注以及该数据集的特点。并提出了一个简单的多模态3D人体姿态估计算法,对比其他模型,该方法性能较好。最后总结了该数据集和该方法的限制。 …

沪尚茗居装修秘籍:嵌入式蒸烤箱,让厨房生活更精彩

在装修厨房时&#xff0c;选择一款合适的嵌入式蒸烤箱不仅能提升烹饪效率&#xff0c;还能为厨房增添一份现代感。沪尚茗居深知用户对厨房电器的需求&#xff0c;从实际出发&#xff0c;为用户推荐选购嵌入式蒸烤箱的实用技巧&#xff0c;让厨房生活更加美好。    首先&…

【千库网-注册安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…

leetcode二叉树(二)-二叉树的递归遍历

题目 . - 力扣&#xff08;LeetCode&#xff09; . - 力扣&#xff08;LeetCode&#xff09; . - 力扣&#xff08;LeetCode&#xff09; 给你二叉树的根节点 root &#xff0c;返回它节点值的 前序 遍历。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出…

滑块验证码,给图就行

效果如上~ <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>滑块拼图验证码 - 拖动条 Loading 效…

K8s环境下使用sidecar模式对EMQX的exhook.proto 进行流量代理

背景 在使用emqx作为mqtt时需要我们需要拦截client的各种行为&#xff0c;如连接&#xff0c;发送消息&#xff0c;认证等。除了使用emqx自带的插件机制。我们也可以用多语言-钩子扩展来实现这个功能&#xff0c;但是目前emqx仅仅支持单个grpc服务端的设置&#xff0c;所以会有…

视频格式转换

格式转换 1️⃣Convertio &#x1f3c6;优点 速度快、格式多、免费免登录 缺点 超过100m的文件就要登录付费了 点击进入 2️⃣123APPs &#x1f3c6;优点 这个免费的文件上限是10G&#xff0c;完完全全够用功能多、除了转换器格式还有视频、音频、PDF处理工具 缺点 广…

无人机飞手执照培训,三类、四类傻傻分不清楚

无人机飞手执照培训中的三类和四类&#xff0c;主要依据无人机的空机重量进行区分&#xff0c;并对应不同的飞行权限和应用场景。以下是对这两类执照的详细解析&#xff1a; 一、无人机飞手执照的三类与四类定义 1. 三类执照&#xff1a; 定义&#xff1a;三类执照是指允许操…

架构设计笔记-9-软件可靠性

目录 知识要点 综合知识 案例分析 1.可靠性特性&#xff0c;软硬件可靠性对比 论文 1.论软件可靠性设计技术的应用 知识要点 软件架构需求过程主要是获取用户需求&#xff0c;标识系统中所要用到的构件&#xff0c;并进行架构需求评审。其中&#xff0c;标识构件又详细地…

Redis——持久化

文章目录 Redis持久化Redis的两种持久化的策略定期备份&#xff1a;RDB触发机制rdb的触发时机&#xff1a;手动执行save&bgsave保存测试不手动执行bgsave测试bgsave操作流程测试通过配置&#xff0c;自动生成rdb快照RDB的优缺点 实时备份&#xff1a;AOFAOF是否会影响到red…

去耦电容的“滤波半径”

1、简介 去耦电容的滤波半径通常指的是在电路板上&#xff0c;去耦电容能够对其周围电源线路或信号线路产生有效去耦作用的范围。这个范围是以去耦电容为中心&#xff0c;向周围扩展的一个特定距离。 想象你有一个水桶&#xff0c;里面装满了混浊的水&#xff08;含有噪声的信…

基于ESP32的厨房计时器

基于ESP32的厨房计时器 一、项目说明二、项目材料三、OLED显示屏四、外壳设计五、外壳打印六、电路和外壳的集成七、编程八、成品展示 一、项目说明 厨房计时器很有用&#xff0c;但现在没有多少人使用实体厨房计时器了。我个人还是喜欢使用它们&#xff0c;因为拥有一个可以按…

CGAL 带约束的Delaunay三角剖分

CGAL 带约束的Delaunay三角剖分 本文使用CGAL进行简单的2D Delaunay 三角剖分,添加内外边界及点作为约束剖分。 Code #include <CGAL/Exact_predicates_inexact_constructions_kernel.h> #include <CGAL/Constrained_Delaunay_triangulation_2.h> #include <…

问题杂录-NVIDIA Bluefield DPU bfb-build编译报错记录与处理办法?(无数坑)

文章目录 背景bfb-build之后直接退出docker.io无法访问报错 ERROR: failed to solve: processkubernotes 下载失败报错mlnx-fw-updater-signed-24.07-0.6.1.1.aarch64: Cannot download报错 No match for argument: bf-release报错 放弃编译anolis&#xff0c;直接编译老版ubun…

RabbitMQ 入门(二)基本结构和消息模型

一、RabbitMQ的基本结构、角色和消息模型 MQ的基本结构&#xff1a; RabbitMQ中的一些角色&#xff1a; - publisher&#xff1a;生产者 - consumer&#xff1a;消费者 - exchange个&#xff1a;交换机&#xff0c;负责消息路由 - queue&#xff1a;队列&#xff0c;存储消息…

初步认识torch自定义算子

此篇为PyTorch 自定义算子&#xff1a;复现CPU和CUDA版的二维卷积的代码详解 这篇是为了展示setup在构建简单的cpp算子的使用 1.环境配置 整体结构如下图所示 pytorch_cpp_helper.hpp中准备了CPU版卷积需要的头文件 pytorch_cuda_helper.hpp和common_cuda_helper.hpp是cuda…