基于golang开发的基线检查脚本(附源码)

前言

看市面上似乎没有公开这种可自动生成结果文件的脚本,故用go编写了一个检测脚本,主要实现了一键根据基线检查结果生成xlsx
( 检查项 级别 检查项说明 检查方法 标准值 检查语句 修复方案)
ssh版本已发布:ssh版本链接
建议使用ssh版本,代码逻辑都做了优化,更加准确一些,检查效率也更高。

兼容性:

目前对于/usr/bin/zsh的兼容性可能还是有点问题,不过其他的版本(龙溪、欧拉、银河等)都测试过没问题。

我的编写环境

windows11、go1.23.0、goland2024.1;

脚本检测时间

平均在3秒到20秒不等一台主机

主要检查项

  • 检查是否设置除root之外UID为0的用户
  • 检查是否设置系统管理员、安全保密管理员或用户管理员、安全审计员或审计操作员账户
  • 检查设备密码复杂度策略
  • 检查 /etc/login.defs 中的口令策略
  • 检查是否存在空口令账户
  • 检查密码重复使用次数限制
  • 检查账户认证失败次数限制
  • 检查umask命令输出
  • 检查 /root/.bashrc 中的 umask
  • 检查 /etc/bashrc 中的 umask
  • 检查 /etc/profile 中的 umask
  • 检查 /etc/login.defs 中的 umask
  • 检查是否设置SSH登录前警告Banner
  • 检查安全事件日志配置
  • 检查日志文件权限设置
  • 检查是否配置远程日志功能
  • 检查是否启用审计服务
  • 检查重要目录或文件权限设置
  • 检查FTP用户上传的文件所具有的权限
  • 检查是否禁用Telnet协议
  • 检查是否使用PAM认证模块禁止wheel组之外的用户su为root
  • 检查是否修改SNMP默认团体字
  • 检查是否禁止root用户远程登录
  • 检查系统openssh安全配置
  • 检查是否禁止匿名用户登录
  • 检查是否删除了潜在危险文件
  • 检查是否设置命令行界面超时退出
  • 检查root用户的path环境变量
  • 检查历史命令设置
  • 检查系统是否禁用Ctrl+Alt+Delete组合键
  • 检查是否使用NTP保持时间同步
  • 检查是否限制访问IP

升级版本

稍后看需要的人多的话我会推出ssh版本,一键批量检测,目前还在测试,没问题后我会推出来,目前测试是平均一个目标稳定在1.2秒以内,900个也就1000秒左右。都是在发起主机上本地上生成结果的

脚本启动方式

chmod +x script-name
./script-name

源码使用方式

set CGO_ENABLED=0
set GOOS=linux
set GOARCH=amd64
go build -tags=linux -o linux-script

我也是个刚学go不久的小白,脚本有问题可以直接跟我说哈~欢迎指导!

不想自己编译的可以直接下载下面这个链接,效果和使用方式一模一样

linux基线检查脚本百度网盘提取码
链接:百度网盘基线检查脚本
提取码:cvcv

源码

package main

import (
	"bufio"
	"encoding/json"
	"fmt"
	"github.com/xuri/excelize/v2"
	"io/ioutil"
	"net"
	"os"
	"os/exec"
	"os/user"
	"path/filepath"
	"reflect"
	"regexp"
	"strconv"
	"strings"
	"time"
)

// 定义列表
var debianLike = []string{"debian", "ubuntu", "Linux Mint", "elementary OS",
	"Debian GNU/Linux", "Ubuntu", "Kali GNU/Linux", "Kylin"}

var redhatLike = []string{"CentOS Linux", "Red Hat Enterprise Linux", "Red Hat Enterprise Linux Server",
	"Fedora", "Anolis OS", "openEuler", "Oracle Linux Server", "Kylin Linux Advanced Server",
	"Alibaba Cloud Linux", "Alibaba Cloud Linux (Aliyun Linux)"}

var archLike = []string{"Arch Linux"}

var suseLike = []string{"openSUSE Leap", "SUSE Linux Enterprise Server"}

var xlsxData = [][]string{}

// 初始化数据
var countAll int
var countSuccess int
var countFail int
var count_manual int

// 用户身份
var userId bool

// 根据操作系统类型执行相应的操作
var bashrc, authSetPath, accountSetPath, passwordComplexity string

// ############################################### 以下是主方法中包装的小函数 ###################################################################

// 获取系统
func Get_Os() string {

	// 获取本地 os-release 中的 name

	localSys := getLocalSys()
	fmt.Println("local_sys =", localSys)

	// 初始化操作系统类型变量
	osLike := "unknown"
	userId = getId()

	// 判断发行版属于哪个列表
	if contains(debianLike, localSys) {
		osLike = "debian_like"
	} else if contains(redhatLike, localSys) {
		osLike = "redhat_like"
	} else if contains(archLike, localSys) {
		osLike = "arch_like"
	} else if contains(suseLike, localSys) {
		osLike = "suse_like"
	}

	switch osLike {
	case "debian_like":
		bashrc = "/etc/bash.bashrc"
		authSetPath = "/etc/pam.d/common-auth"
		accountSetPath = "/etc/pam.d/common-account"
		passwordComplexity = "/etc/pam.d/common-password"
	case "redhat_like", "arch_like":
		bashrc = "/etc/bashrc"
		authSetPath = "/etc/pam.d/system-auth"
		accountSetPath = "/etc/pam.d/system-auth"
		passwordComplexity = "/etc/pam.d/system-auth"
	case "suse_like":
		// 在此处执行 SUSE 系操作
		bashrc = "/etc/bash.bashrc"
		authSetPath = "/etc/pam.d/common-auth"
		accountSetPath = "/etc/pam.d/common-account"
		passwordComplexity = "/etc/pam.d/common-password"
	default:
		// 如果未匹配到任何操作系统类型,可以在此添加默认操作
		fmt.Println("操作系统未识别")
	}
	return osLike
}

// 部分异常处理
func errPrint(describe string, err error) {
	if err != nil {
		fmt.Printf("%s  :  %s", describe, err)
	}
}

// 最后保存检测结果
func saveExcel(filePath string, data [][]string, additionalData [][]interface{}) (int, error) {
	saveErr := 0
	fmt.Println("开始写入xlsx表格数据...")
	// 创建一个新的 Excel 文件
	f := excelize.NewFile()

	// 创建一个新的工作表或选择一个现有的工作表
	index, _ := f.NewSheet("Sheet1")
	SheetName := f.GetSheetName(index)
	if err := f.SetSheetName(SheetName, "基线检查"); err != nil {
		fmt.Println("创建工作表失败:", err)
	}
	NewSheetName := f.GetSheetName(index)
	// 将数据写入工作表
	for rowsIndex, rows := range data {

		for rowindex, row := range rows {
			cellAddress, _ := excelize.CoordinatesToCellName(rowindex+1, rowsIndex+1)
			if cellAddress == "" {
				continue
			}
			if err := f.SetCellValue(NewSheetName, cellAddress, row); err != nil {
				fmt.Printf("xlsx表格数据写入失败: %v\n", err)
				saveErr++
			}
		}
	}

	// 设置冻结窗格
	panesJSON := `{"freeze":true,"split":false,"x_split":0,"y_split":1,"top_left_cell":"A2","active_pane":"bottomLeft"}`
	var panes struct {
		Freeze      bool   `json:"freeze"`
		Split       bool   `json:"split"`
		XSplit      int    `json:"x_split"`
		YSplit      int    `json:"y_split"`
		TopLeftCell string `json:"top_left_cell"`
		ActivePane  string `json:"active_pane"`
	}
	err := json.Unmarshal([]byte(panesJSON), &panes)
	if err != nil {
		fmt.Printf("冻结窗格出现错误: %v\n", err)
		saveErr++
	}

	err = f.SetPanes(NewSheetName, &excelize.Panes{
		Freeze:      panes.Freeze,
		Split:       panes.Split,
		XSplit:      panes.XSplit,
		YSplit:      panes.YSplit,
		TopLeftCell: panes.TopLeftCell,
		ActivePane:  panes.ActivePane,
	})
	if err != nil {
		fmt.Printf("初始化xlsx错误: %v\n", err)
		saveErr++
	}

	// 设置列宽
	columnWidths := map[string]float64{
		"A": 6.55, "B": 15.7, "C": 4.64, "D": 41, "E": 22.73,
		"F": 21.45, "G": 21.18, "H": 22.55, "I": 22.55, "J": 8.64,
	}
	for col, width := range columnWidths {
		if err = f.SetColWidth(NewSheetName, col, col, width); err != nil {
			fmt.Printf("xlsx设置列宽错误: %v\n", err)
		}
	}

	// 设置单元格对齐方式
	style, err := f.NewStyle(&excelize.Style{
		Alignment: &excelize.Alignment{
			WrapText: true,
			Vertical: "top",
		},
	})
	if err != nil {
		fmt.Printf("设置单元格对齐方式错误: %v\n", err)
		saveErr++
	}
	if err = f.SetCellStyle(NewSheetName, "A1", "J"+strconv.Itoa(len(data)+1), style); err != nil {
		fmt.Printf("设置单元格对齐方式错误: %v\n", err)
		saveErr++
	}

	// 创建第二个工作表并写入额外数据
	sheetIndex, err := f.NewSheet("主机信息")
	if err != nil {
		fmt.Printf("创建第二个工作表出现错误: %v\n", err)
		saveErr++
	}
	sheetName2 := f.GetSheetName(sheetIndex)
	for rowsIndex, rows := range additionalData {
		for rowIndex, row := range rows {
			cellAddress, _ := excelize.CoordinatesToCellName(rowIndex+1, rowsIndex+1) // 获取坐标
			if err = f.SetCellValue(sheetName2, cellAddress, row); err != nil {
				fmt.Printf("xlsx表格数据写入错误: %v\n", err)
				saveErr++
			}
		}
	}

	// 保存 Excel 文件
	if err = f.SaveAs(filePath); err != nil {
		fmt.Println("保存xlsx文件失败: ", err)
		return saveErr, err
	}

	fmt.Printf("%s已保存\n", filePath)
	return saveErr, nil
}

func getLocalSys() string {
	file, err := os.Open("/etc/os-release")
	if err != nil {
		return "CentOS Linux"
	}
	defer func() {
		err = file.Close()
		if err != nil {
			fmt.Println(err)
		}
	}()

	var localSys string
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		line := scanner.Text()
		if strings.HasPrefix(line, "NAME=") {
			localSys = strings.Trim(strings.TrimPrefix(line, "NAME="), `"`)
			break
		}
	}

	return localSys
}

func readUser(path string, result7_6Data []string, HISTFILESIZE *int, HISTSIZE *int) (bool, string) {
	// 获取当前用户的信息
	currentUser, err := user.Current()
	if err != nil {
		fmt.Println("Error getting current user:", err)
		//return []byte{}
	}

	// 构建 ~/.bashrc 的完整路径
	bashrcPath := currentUser.HomeDir + "/" + path

	// 打开文件
	file, err := os.Open(bashrcPath)
	if err == nil {
		return checkHistoryFile(file, result7_6Data, HISTFILESIZE, HISTSIZE), bashrcPath
	}
	return false, bashrcPath
}

// 匹配内容
func scantxt(line string, result7_6Data []string, HISTFILESIZE *int, HISTSIZE *int) {
	if !strings.HasPrefix(line, "#") && strings.Contains(line, "HISTFILESIZE") {
		if strings.Contains(line, "=") {
			result7_6Data = append(result7_6Data, line)
			value, err1 := strconv.Atoi(strings.Split(line, "=")[1])
			if err1 == nil {
				*HISTFILESIZE = value
			}
		}
	}
	if !strings.HasPrefix(line, "#") && strings.Contains(line, "HISTSIZE") {
		if strings.Contains(line, "=") {
			result7_6Data = append(result7_6Data, line)
			value, err1 := strconv.Atoi(strings.Split(line, "=")[1])
			if err1 == nil {
				*HISTSIZE = value
			}
		}
	}
}

func checkHistoryFile(filedata *os.File, result7_6Data []string, HISTFILESIZE *int, HISTSIZE *int) bool {
	defer filedata.Close()

	scanner := bufio.NewScanner(filedata)
	for scanner.Scan() {
		line := scanner.Text()
		line = strings.TrimSpace(line)
		//fmt.Println(line)
		scantxt(line, result7_6Data, HISTFILESIZE, HISTSIZE)
	}

	if *HISTFILESIZE != 0 || *HISTSIZE != 0 {
		return true
	}
	return false
}

func getLocalIP() string {
	// 创建套接字并连接到外部服务(例如Google的DNS服务器)
	conn, err := net.Dial("udp", "8.8.8.8:80")
	if err != nil {
		return "127.0.0.1" // 如果无法连接外部服务,使用回环地址作为备选方案
	}
	defer func() {
		err = conn.Close()
		if err != nil {
			fmt.Println(err)
		}
	}()

	localAddr := conn.LocalAddr().(*net.UDPAddr)
	return localAddr.IP.String()
}

func getOSName() string {
	file, err := os.Open("/etc/os-release")
	if err != nil {
		return "未找到os-release"
	}
	defer func() {
		err = file.Close()
		if err != nil {
			fmt.Println(err)
		}
	}()

	var osName string
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		line := scanner.Text()
		if strings.Contains(line, "PRETTY_NAME") {
			osName = strings.Trim(strings.TrimPrefix(line, "PRETTY_NAME="), `"`)
			break
		}
	}

	return osName
}

func checkUID0() []string {
	var userUID0 []string
	file, err := os.Open("/etc/passwd")
	if err != nil {
		fmt.Println(err)
		return userUID0
	}
	defer func() {
		err = file.Close()
		if err != nil {
			fmt.Println(err)
		}
	}()

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		line := scanner.Text()
		fields := strings.Split(line, ":")
		uid := fields[2]
		if uid == "0" {
			userUID0 = append(userUID0, fields[0])
		}
	}

	return userUID0
}

func getUsers(username string) error {
	_, err := user.Lookup(username)
	return err
}

func checkUsers() (bool, bool, bool) {
	user1, user2, user3 := false, false, false

	if err := getUsers("sysadmin"); err == nil {
		user1 = true
	}
	if err := getUsers("useradmin"); err == nil {
		user2 = true
	}
	if err := getUsers("auditor"); err == nil {
		user3 = true
	}

	return user1, user2, user3
}

func checkCommand(command string) bool {
	cmd := exec.Command("service", "status", command)
	output, err := cmd.CombinedOutput()
	if err != nil {
		return false
	}
	outputStr := string(output)
	return strings.Contains(outputStr, "Active: active (running)") || strings.Contains(outputStr, "is running")
}

func checkNtpTime(command string) bool {
	cmd := exec.Command("systemctl", "status", command)
	output, err := cmd.CombinedOutput()
	if err != nil {
		return false
	}
	outputStr := string(output)
	return strings.Contains(outputStr, "Active: active (running)") || strings.Contains(outputStr, "is running")
}

func runCommand(command string) (string, error) {
	cmd := exec.Command("sh", "-c", command)
	output, err := cmd.CombinedOutput()
	//fmt.Println("output,", output)
	return string(output), err
}

func getKey(data_map map[string]string, str string) string {
	var keys []string
	for key := range data_map {
		keys = append(keys, key)
	}
	// 使用 strings.Join 连接这些键
	joinedKeys := strings.Join(keys, str)

	return joinedKeys
}

// 保存状态判断
func save_status(saveErr int) {
	if saveErr != 0 {
		fmt.Printf("写入失败结果次数为:%d\n", saveErr)
	} else {
		fmt.Println("本次写入很成功哟~")
	}
}

// 初始化
func start_scan() (string, [][]interface{}) {

	// 获取操作系统的数据类型
	osLike := Get_Os()
	hostInfo := make([][]interface{}, 2)
	osName := getOSName()
	ipAddress := getLocalIP()

	// 将数据添加到 hostInfo 中
	hostInfo[0] = []interface{}{"IP地址", ipAddress}
	hostInfo[1] = []interface{}{"操作系统", osName}

	// 调用函数获取本机IP地址
	fmt.Println("本机操作系统为", osName, ",IP地址为", ipAddress)
	fmt.Println(osLike)
	fmt.Println(bashrc)
	fmt.Println(authSetPath)
	fmt.Println(accountSetPath)
	fmt.Println(passwordComplexity)

	// 设置title
	xlsxTitle := []string{
		"编号", "检查项", "级别", "检查项说明", "检查方法", "标准值", "检查语句", "修复方案",
		"检查情况", "符合性", "调整情况", "原因",
	}

	xlsxData = append(xlsxData, xlsxTitle)
	return ipAddress, hostInfo

}

// 循环确认value是否存在于tmp中
func contains(tmp []string, value string) bool {
	b := false
	for _, v := range tmp {
		if v == value {
			b = true
		}
	}
	return b
}

// 使用 "umask" 命令获取 umask 值
func getUmask() (string, error) {
	cmd := exec.Command("sh", "-c", "umask")
	output, err := cmd.Output()
	if err != nil {
		return "/", err
	}
	// 去掉输出中的换行符
	return strings.TrimSpace(string(output)), nil
}

func getId() bool {
	cmd := exec.Command("sh", "-c", "id")
	output, err := cmd.Output()
	if err != nil {
		return false
	}
	rootId := []string{"gid=0", "uid=0", "groups=0"}
	if contains(rootId, strings.TrimSpace(string(output))) {
		// 去掉输出中的换行符
		return true
	}
	return false
}

//############################################### 以下是主调用方法 ###################################################################

// 1:帐号管理
func account_admin() {

	// 1.1:检查是否设置除root之外UID为0的用户
	countAll++
	var result1_1 string
	userUID0 := checkUID0()
	if len(userUID0) > 1 {
		result1_1 = "不合规"
		countFail++
		fmt.Println("1.1:检查是否设置除root之外UID为0的用户\t", result1_1, "\t", userUID0)
	} else {
		result1_1 = "合规"
		countSuccess++
		fmt.Println("1.1:检查是否设置除root之外UID为0的用户\t", result1_1, "\t", userUID0)
	}
	recommendation1_1 := `1、执行备份
		cp –p /etc/passwd /etc/passwd.bak
		cp –p /etc/shadow /etc/shadow.bak
		cp –p /etc/group /etc/group.bak
		2、删除除root外其他UID为0的用户(删除之前应确保用户未被其他业务使用)或修改账号UID
		userdel {用户名}
		usermod -u {UID} {用户名}
`
	data1_1 := []string{
		"1.1",
		"检查是否设置除root之外UID为0的用户",
		"中危",
		"任何UID为0的帐户都具有系统上的超级用户特权,只有root账号的uid才能为0",
		"检查/etc/passwd,以\":\"分隔,第一项为用户名,第三项为UID",
		"不允许存在除root外UID为0的用户",
		"cat /etc/passwd | awk -F: '$3 == 0 {print $1}'",
		recommendation1_1,
		"当前具备UID权限为0的用户有:" + strings.Join(userUID0, " ; "),
		result1_1,
		"/",
		"/",
	}

	xlsxData = append(xlsxData, data1_1)

	// 1.2:检查是否设置系统管理员、安全保密管理员或用户管理员、安全审计员或审计操作员账户
	countAll++
	var result1_2 string
	user1, user2, user3 := checkUsers()
	if user1 && user2 && user3 {
		countSuccess++
		result1_2 = "合规"
		fmt.Println("1.2:检查是否设置系统管理员、安全保密管理员或用户管理员、安全审计员或审计操作员账户\t", result1_2)
	} else {
		countFail++
		result1_2 = "不合规"
		fmt.Println("1.2:检查是否设置系统管理员、安全保密管理员或用户管理员、安全审计员或审计操作员账户\t", result1_2)
	}
	var result1_2_data []string
	resList := []bool{user1, user2, user3}
	userList := []string{"sysadmin", "useradmin", "auditor"}
	for resIndex, row := range resList {
		if !row {
			result1_2_data = append(result1_2_data, userList[resIndex])
		}
	}
	data1_2 := []string{
		"1.2",
		"检查是否设置系统管理员、安全保密管理员或用户管理员、安全审计员或审计操作员账户",
		"中危",
		"应分别设置系统管理员、安全保密管理员或用户管理员、安全审计员或审计操作员账户",
		"检查 /etc/passwd 是否包含sysadmin、useradmin、auditor用户",
		"同时存在sysadmin、useradmin、auditor用户",
		"grep -e sysadmin -e useradmin -e auditor /etc/passwd",
		"1、按要求创建账户\nuseradd {用户名}\n2、为用户创建密码\n passwd {用户名}",
		"当前缺少的用户账户:" + strings.Join(result1_2_data, " ; "),
		result1_2,
		"/",
		"/",
	}
	xlsxData = append(xlsxData, data1_2)
}

// 2 密码复杂度检查
func checkpPassword() {
	var flag1, flag2, flag3, flag4 bool
	// 2.1:检查设备密码复杂度策略
	countAll++
	parsePWQualityConfig := func(content string, dcredit *string, ucredit *string, ocredit *string, lcredit *string, minclass *string, minlen *string) {
		for _, line := range strings.Split(content, "\n") {
			if strings.Contains(line, "password") && strings.Contains(line, "requisite") && (strings.Contains(line, "pam_pwquality.so") || strings.Contains(line, "pam_cracklib.so")) {
				for _, part := range strings.Fields(line) {
					switch {
					case strings.HasPrefix(part, "dcredit="):
						*dcredit = part[len("dcredit="):]
					case strings.HasPrefix(part, "ucredit="):
						*ucredit = part[len("ucredit="):]
					case strings.HasPrefix(part, "ocredit="):
						*ocredit = part[len("ocredit="):]
					case strings.HasPrefix(part, "lcredit="):
						*lcredit = part[len("lcredit="):]
					case strings.HasPrefix(part, "minclass="):
						*minclass = part[len("minclass="):]
					case strings.HasPrefix(part, "minlen="):
						*minlen = part[len("minlen="):]
					}
				}
			}
		}
	}

	dcredit, ucredit, ocredit, lcredit, minclass, minlen := "配置不存在", "配置不存在", "配置不存在", "配置不存在", "配置不存在", "配置不存在"

	passwordContent, err := os.ReadFile(passwordComplexity)
	fmt.Println(passwordComplexity)
	if err != nil {
		passwordComplexity = "/etc/security/pwquality.conf"
		passwordContent, err = os.ReadFile(passwordComplexity)
		if err != nil {
			fmt.Println("2:读取文件/etc/security/pwquality.conf以及/etc/pam.d/system-auth失败:", err)
			return
		}
	}

	parsePWQualityConfig(string(passwordContent), &dcredit, &ucredit, &ocredit, &lcredit, &minclass, &minlen)

	flag1 = true
	if !(ucredit != "0" && lcredit != "0" && dcredit != "0" && ocredit != "0") || minclass != "4" {
		flag1 = false
	}

	flag2 = true
	num, _ := strconv.Atoi(minlen)
	if num < 8 {
		flag2 = false
	}

	result2_1 := "部分合规"
	if flag1 && flag2 {
		result2_1 = "合规"
		countSuccess++
	} else if !flag1 && !flag2 {
		result2_1 = "不合规"
		countFail++
	} else {
		countFail++
	}

	data2_1 := []string{
		"2.1", "检查设备密码复杂度策略", "高危", "密码复杂度过低会增加密码被爆破风险。",
		fmt.Sprintf("检查%s或/etc/security/pwquality.conf中ucredit/lcredit/dcredit/ocredit/minlen/minclass的值是否符合标准值", passwordComplexity),
		"按照企业密码管理要求与等级保护标准,密码至少8位,复杂度应包含特殊字符、大小写字母和数字。",
		fmt.Sprintf("cat %s | grep -v '#' | grep password\ncat /etc/security/pwquality.conf", passwordComplexity),
		fmt.Sprintf("在%s中修改或追加ucredit/lcredit/dcredit/ocredit=-1", passwordComplexity),
		fmt.Sprintf("dcredit %s\nucredit %s\nocredit %s\nlcredit %s\nminclass %s\nminlen %s", dcredit, ucredit, ocredit, lcredit, minclass, minlen),
		result2_1, "/", "/",
	}
	xlsxData = append(xlsxData, data2_1)

	fmt.Printf("2.1:检查设备密码复杂度策略\t%s\n", result2_1)

	//================================================
	// 2.2:检查 /etc/login.defs 中的口令策略
	countAll++
	PASS_MIN_DAYS := "/"
	PASS_WARN_AGE := "/"
	PASS_MAX_DAYS := "/"
	PASS_MIN_LEN := "/"
	var result2_2 string
	loginDefsContent, err := ioutil.ReadFile("/etc/login.defs")
	if err != nil {
		fmt.Println("读取文件失败:", err)
		return
	}
	for _, line := range strings.Split(string(loginDefsContent), "\n") {
		line = strings.TrimSpace(line)
		if !strings.HasPrefix(line, "#") && strings.Contains(line, "PASS_MIN_DAYS") {
			PASS_MIN_DAYS = strings.Fields(line)[len(strings.Fields(line))-1]
		} else if !strings.HasPrefix(line, "#") && strings.Contains(line, "PASS_WARN_AGE") {
			PASS_WARN_AGE = strings.Fields(line)[len(strings.Fields(line))-1]
		} else if !strings.HasPrefix(line, "#") && strings.Contains(line, "PASS_MAX_DAYS") {
			PASS_MAX_DAYS = strings.Fields(line)[len(strings.Fields(line))-1]
		} else if !strings.HasPrefix(line, "#") && strings.Contains(line, "PASS_MIN_LEN") {
			PASS_MIN_LEN = strings.Fields(line)[len(strings.Fields(line))-1]
		}
	}

	recommendation2_2 := make([]string, 0)
	num, _ = strconv.Atoi(PASS_MIN_LEN)
	if PASS_MIN_DAYS != "/" && num >= 7 {
		flag1 = true
	} else {
		recommendation2_2 = append(recommendation2_2, "修改 PASS_MIN_DAYS >= 7")
	}
	num, _ = strconv.Atoi(PASS_MIN_LEN)
	if PASS_WARN_AGE != "/" && num >= 7 {
		flag2 = true
	} else {
		recommendation2_2 = append(recommendation2_2, "修改 PASS_WARN_AGE >= 7")
	}
	num, _ = strconv.Atoi(PASS_MIN_LEN)
	if PASS_MAX_DAYS != "/" && num <= 90 {
		flag3 = true
	} else {
		recommendation2_2 = append(recommendation2_2, "修改 PASS_MAX_DAYS <= 90")
	}
	num, _ = strconv.Atoi(PASS_MIN_LEN)
	if PASS_MIN_LEN != "/" && num >= 8 {
		flag4 = true
	} else {
		recommendation2_2 = append(recommendation2_2, "修改 PASS_MIN_LEN >= 8")
	}
	if len(recommendation2_2) > 0 {
		recommendation2_2 = append([]string{"编辑配置文件\nvim /etc/login.defs\n"}, recommendation2_2...)
	}
	if flag1 && flag2 && flag3 && flag4 {
		result2_2 = "合规"
		countSuccess++
	} else if !flag1 && !flag2 && !flag3 && !flag4 {
		result2_2 = "不合规"
		countFail++
	} else {
		result2_2 = "部分合规"
		countFail++
	}
	info2_2 := "通过限制密码更改的频率,管理员可以防止用户重复更改密码,从而避免密码重用控制。\n提供一个预先警告,密码将会到期给用户时间来考虑一个安全的密码。不知情的用户可能会选择一个简单的密码,或者把它写在可能被发现的地方。\n攻击者利用网络暴力攻击的机会,通过网络暴力攻击的机会窗口,受到密码生存周期的限制。因此,减少密码的生命周期也会减少攻击者的机会窗口。\n增加密码长度可有效增加攻击者爆破难度。"
	standard2_2 := "建议将PASS_MIN_DAYS参数设置为不小于7天。\n建议将PASS_WARN_AGE参数设置为7天。\n建议将PASS_MAX_DAYS参数设置为小于或等于90天。\n建议将PASS_MIN_LEN参数设置为大于或等于8位。"
	data2_2 := []string{
		"2.2", "检查 /etc/login.defs 中的口令策略", "高危", info2_2, "检查 /etc/login.def 中的配置是否符合标准值。",
		standard2_2, "cat /etc/login.defs | grep -v '#' | awk '/PASS_MIN_DAYS/ || /PASS_WARN_AGE/ || /PASS_MAX_DAYS/ || /PASS_MIN_LEN/'",
		strings.Join(recommendation2_2, "\n"), fmt.Sprintf("PASS_MIN_DAYS %s\nPASS_WARN_AGE %s\nPASS_MAX_DAYS %s\nPASS_MIN_LEN %s", PASS_MIN_DAYS, PASS_WARN_AGE, PASS_MAX_DAYS, PASS_MIN_LEN),
		result2_2}
	xlsxData = append(xlsxData, data2_2)
	fmt.Printf("2.2:检查 /etc/login.defs 中的口令策略\t%s\n", result2_2)


	// 2.3:检查是否存在空口令账号
	countAll++
	var result2_3 string
	var result2_3_data string
	userNoPassword := make([]string, 0)
	shadowContent, err := ioutil.ReadFile("/etc/shadow")
	if err != nil {
		fmt.Println("读取文件失败/etc/shadow:", err)
		count_manual++
		return
	} else {
		for _, line := range strings.Split(string(shadowContent), "\n") {
			if line == "" {
				break
			}
			fields := strings.Split(line, ":")

			username := fields[0]
			passwordHash := fields[1]

			// 检查密码字段是否为空字符串或为*
			if passwordHash == "/" {
				fmt.Printf("空口令账户发现: %s\n", username)
				userNoPassword = append(userNoPassword, username)
			}
		}
		if len(userNoPassword) > 0 {
			result2_3_data = "以下账户口令为空:\n" + strings.Join(userNoPassword, "\n")
		} else {
			result2_3_data = "不存在空口令账户"
		}
		if len(userNoPassword) > 0 {
			result2_3 = "不合规"
			countFail++
		} else {
			result2_3 = "合规"
			countSuccess++
		}
		data2_3 := []string{
			"2.3", "检查是否存在空口令账户", "高危", "由于空口令会让攻击者不需要口令进入系统,存在较大风险。",
			"查看/etc/passwd,以“:”分隔,第二项若为空,则表示空口令", "不存在空口令账户",
			`"awk -F: \'($2 == '") {print $1}' /etc/shadow"`, "使用passwd命令重设空口令用户密码", result2_3_data, result2_3, "/", "/",
		}
		xlsxData = append(xlsxData, data2_3)
		if result2_3 == "合规" {
			fmt.Printf("2.3:检查是否存在空口令账号\t%s\t%s\n", result2_3, userNoPassword)
		} else {
			fmt.Printf("2.3:检查是否存在空口令账号\t%s\t%s\n", result2_3, userNoPassword)

		}
	}

	// 2.4:检查密码重复使用次数限制
	countAll++
	var result2_4 string
	recommendation2_4 := make([]string, 0)
	result2_4_data := make([]string, 0)
	setPamUnix := false
	setPamPwhistory := false
	var rememberSet int
	passwordComplexityContent, err := ioutil.ReadFile(passwordComplexity)
	if err != nil {
		fmt.Println("读取文件失败:", err)
		return
	}
	for _, line := range strings.Split(string(passwordComplexityContent), "\n") {
		line = strings.TrimSpace(line)
		if !strings.HasPrefix(line, "#") && strings.Contains(line, "password") && strings.Contains(line, "pam_unix.so") {
			result2_4_data = append(result2_4_data, fmt.Sprintf("pam_unix.so检查记录 [ %s ]", line))
			setPamUnix = true
			for _, item := range strings.Fields(line) {
				if strings.Contains(item, "remember") {
					strLists := strings.Split(item, "=")
					num := strLists[len(strLists)-1]
					rememberSet, _ = strconv.Atoi(num)
				}
			}
		}
		if !strings.HasPrefix(line, "#") && strings.Contains(line, "password") && strings.Contains(line, "pam_pwhistory.so") {
			result2_4_data = append(result2_4_data, fmt.Sprintf("pam_pwhistory.so检查记录 [ %s ]", line))
			setPamPwhistory = true
			for _, item := range strings.Fields(line) {
				if strings.Contains(item, "remember") {
					strLists := strings.Split(item, "=")
					num := strLists[len(strLists)-1]
					rememberSet, _ = strconv.Atoi(num)
				}
			}
		}
	}
	res := rememberSet <= 5
	if res {
		result2_4_data = append(result2_4_data, fmt.Sprintf("口令次数限制为 %d 次 合规", rememberSet))
	} else {
		if setPamUnix {
			recommendation2_4 = append(recommendation2_4, fmt.Sprintf("在 %s中password sufficient pam_unix.so 后添加 remember=5", passwordComplexity))
		} else if setPamPwhistory {
			recommendation2_4 = append(recommendation2_4, fmt.Sprintf("在 %s中password sufficient pam_pwhistory.so 后添加 remember=5", passwordComplexity))
		} else {
			recommendation2_4 = append(recommendation2_4, fmt.Sprintf("在 %s中password sufficient pam_unix.so 后添加 remember=5", passwordComplexity))
		}
		result2_4_data = append(result2_4_data, fmt.Sprintf("未正确设置口令重复使用次数限制,当前设置为 %d", rememberSet))
		recommendation2_4 = append(recommendation2_4, fmt.Sprintf("在 %s中找到类似行password sufficient pam_unix.so,在行末尾增加remember=5,中间以空格隔开。", passwordComplexity))
	}
	existOpasswd := false
	var opasswdStat os.FileMode
	opasswdStatGood := false
	if fileInfo, err := os.Stat("/etc/security/opasswd"); err == nil {
		existOpasswd = true
		// 获取文件的实际权限
		opasswdStat = fileInfo.Mode()

		// 检查权限是否符合安全要求
		if opasswdStat.Perm()&0777 == 0600 {
			opasswdStatGood = true
		} else {
			opasswdStatGood = false
		}
	} else {
		existOpasswd = false
		result2_4_data = append(result2_4_data, "/etc/security/opasswd 文件不存在")
		recommendation2_4 = append(recommendation2_4, "创建文件/etc/security/opasswd用于存储旧密码,并设置权限。\ntouch /etc/security/opasswd\nchown root:root /etc/security/opasswd\nchmod 600 /etc/security/opasswd")
	}
	if !opasswdStatGood {
		result2_4_data = append(result2_4_data, fmt.Sprintf("/etc/security/opasswd 文件权限不合规,当前权限为:%o", opasswdStat))
		recommendation2_4 = append(recommendation2_4, "修改 /etc/security/opasswd 文件权限\nchown root:root /etc/security/opasswd\nchmod 600 /etc/security/opasswd")
	}
	recommendation2_4 = append([]string{"配置文件备份\ncp -p /etc/pam.d/system-auth /etc/pam.d/system-auth.bak"}, recommendation2_4...)
	if res && setPamUnix && existOpasswd && opasswdStatGood {
		result2_4 = "合规"
		countSuccess++
	} else if res || setPamUnix || existOpasswd || opasswdStatGood {
		fmt.Printf("res:%t , setPamUnix:%t , setPamPwhistory:%t , existOpasswd:%t , opasswdStatGood:%t \n", res, setPamUnix, setPamPwhistory, existOpasswd, opasswdStatGood)
		result2_4 = "部分合规"
		countFail++
	} else {
		result2_4 = "不合规"
		countFail++
	}
	data2_4 := []string{
		"2.4", "检查密码重复使用次数限制", "中危",
		"对于采用静态口令认证技术的设备,应配置设备,使用户不能重复使用最近5次(含5次)内已使用的口令。",
		"1、查看文件/etc/pam.d/system-auth,是否有配置口令重复使用次数限制\n2、检查 /etc/security/opasswd 文件权限是否小于等于600",
		"用户不能重复使用最近5次(含5次)内已使用的口令",
		"cat /etc/pam.d/system-auth |sed '/^\\s*#/d'|sed '/^\\s*$/d'|grep -i 'password' | grep pam_unix.so\nstat -c %a /etc/security/opasswd",
		strings.Join(recommendation2_4, "\n"), strings.Join(result2_4_data, "\n"), result2_4, "/", "/"}
	xlsxData = append(xlsxData, data2_4)
	if result2_4 == "合规" {
		fmt.Printf("2.4: 检查密码重复使用次数限制 %s\n", result2_4)
	} else {
		fmt.Printf("2.4: 检查密码重复使用次数限制\t%s\n", result2_4)
	}

	// 2.5:检查账户认证失败次数限制
	countAll++
	result2_5_data := []string{}
	recommendation2_5 := "string"
	//pam_lock := []string{}
	var flag5, flag6 bool
	auth_file, err := os.Open(authSetPath)
	if err != nil {
		fmt.Println("Error opening auth file:", err)
		return
	}
	defer func() {
		err = auth_file.Close()
		if err != nil {
			fmt.Println(err)
		}
	}()
	scanner := bufio.NewScanner(auth_file)
	for scanner.Scan() {
		line := scanner.Text()
		line = strings.TrimSpace(line)
		if !strings.HasPrefix(line, "#") && strings.Contains(line, "auth") && strings.Contains(line, "pam_faillock.so") {
			result2_5_data = append(result2_5_data, line)
			if strings.Contains(line, "preauth") {
				flag1 = true
			}
			if strings.Contains(line, "deny=5") {
				flag2 = true
			}
			if strings.Contains(line, "unlock_time=180") {
				flag3 = true
			}
		}
		if !strings.HasPrefix(line, "#") && strings.Contains(line, "auth") && (strings.Contains(line, "pam_tally2.so") || strings.Contains(line, "pam_tally.so")) {
			result2_5_data = append(result2_5_data, line)
			if strings.Contains(line, "deny=5") {
				flag4 = true
			}
			if strings.Contains(line, "unlock_time=180") {
				flag5 = true
			}
		}
	}
	if flag4 || flag5 {
		account_file, err1 := os.Open(accountSetPath)
		if err1 != nil {
			fmt.Println("Error opening account file:", err1)
			return
		}
		defer func() {
			err = account_file.Close()
			if err != nil {
				fmt.Println(err)
			}
		}()
		scanner = bufio.NewScanner(account_file)
		for scanner.Scan() {
			line := scanner.Text()
			line = strings.TrimSpace(line)
			if strings.Contains(line, "account") && strings.Contains(line, "required") && strings.Contains(line, "pam_tally2.so") {
				result2_5_data = append(result2_5_data, line)
				flag6 = true
			}
		}
	}
	result2_5 := "不合规"
	if flag1 && flag2 && flag3 {
		result2_5 = "合规"
		countSuccess++
	}
	if flag4 && flag5 && flag6 {
		result2_5 = "合规"
		countSuccess++
	}
	if result2_5 == "不合规" {
		countFail++
		recommendation2_5 = fmt.Sprintf(`
    查找可用于配置账户认证失败次数限制的动态链接库
	使用包管理器安装mlocate
	updatedb
	locate pam_faillock.so
	locate pam_tally2.so
	locate pam_tally.so
	auth配置文件:%s
	account配置文件:%s
	备份上述配置文件
	cp -p {{配置文件}} {{配置文件}}.bak
	选项1:pam_tally2.so或pam_tally.so
	在相应的文件中编辑或增加如下内容:
	auth required pam_tally2.so deny=5 onerr=fail no_magic_root unlock_time=180
	account required pam_tally2.so
	#(redhat5.1以上版本支持 pam_tally2.so,其他版本使用pam_tally.so)
	选项2:pam_faillock.so
	在相应的文件中编辑或增加如下内容:
	auth required pam_faillock.so preauth silent audit deny=6 unlock_time=180
	auth [success=1 default=ignore] pam_unix.so
	auth required pam_faillock.so authfail audit deny=6 unlock_time=180`, authSetPath, accountSetPath)
	}
	if len(result2_5_data) > 0 {
		result2_5_data = append(result2_5_data, strings.Join(result2_5_data, "\n"))
	} else {
		result2_5_data = append(result2_5_data, "未找到相关配置")
	}
	data2_5 := []string{
		"2.5", "检查账户认证失败次数限制", "中危",
		"对于采用静态口令认证技术的设备,应配置当用户连续认证失败次数超过6次(不含6次),锁定该用户使用的账号。",
		fmt.Sprintf("检查配置文件 %s 是否引用了pam_faillock.so 或 pam_tally.so 或 pam_tally2.so,并配置deny=5、unlock_time=180", authSetPath),
		"用户连续认证失败次数不超过6次,超出后锁定180秒", "cat /etc/pam.d/system-auth | grep -e pam_tally -e pam_faillock.so", recommendation2_5, strings.Join(result2_5_data, "\n"), result2_5, "/", "/",
	}
	xlsxData = append(xlsxData, data2_5)

	fmt.Printf("2.5:检查账户认证失败次数限制\t%s\n", result2_5)

}

// 3
func userAuth() {

	// 3:认证授权
	// 3.1:检查umask设置
	countAll++
	// 获取 umask
	umask, err := getUmask()
	if err != nil {
		fmt.Println("Error:", err)
		return
	}

	// 将 umask 转换为四位的八进制字符串
	umask1 := fmt.Sprintf("%04o", umask)

	// 正则匹配出数字
	re := regexp.MustCompile(`\d+`)
	match := re.FindString(umask1)
	var result3_1 string
	tmp := []string{"0027", "0077"}
	res := contains(tmp, match)
	if res {
		result3_1 = "合规"
		countSuccess++
	} else {
		result3_1 = "不合规"
		countFail++
	}
	data3_1 := []string{
		"3.1", "检查umask命令输出", "中危", "用户umask设置由多个文件控制,请参考子项。",
		"参考子项", "0077或0027", "umask",
		"参考子项", match, result3_1, "/", "/",
	}
	xlsxData = append(xlsxData, data3_1)
	if result3_1 == "合规" {
		fmt.Printf("3.1:检查umask命令输出\t%s\t%s\n", result3_1, match)
	} else {
		fmt.Printf("3.1:检查umask命令输出\t%s\t%s\n", result3_1, match)
	}
	usr, err := user.Current()
	homeDir := usr.HomeDir
	bashrcPath := filepath.Join(homeDir, ".bashrc")
	login_path := "/etc/login.defs"
	profile_path := "/etc/profile"
	if !res {
		// 3.1.1:检查~/.bashrc
		countAll++
		errPrint("获取用户信息错误", err)
		//bashrc_path := os.path.expanduser("~/.bashrc")
		umask_values := []string{}
		result3_1_1_data := "string"
		result3_1_1 := "string"
		bashrc_file, err := os.Open(bashrcPath)
		defer func() {
			if err = bashrc_file.Close(); err != nil {
				fmt.Println(err)
			}
		}()
		if err != nil {
			fmt.Println("Error opening bashrc file:", err)
			count_manual++
			data3_1_1 := []string{
				"3.1.1", fmt.Sprintf("检查 %s 中的 umask", bashrcPath), "中危",
				fmt.Sprintf("当用户以交互方式登录时,或者启动新的交互式 Bash shell 时,系统会尝试加载 %s 文件,以读取umask", bashrcPath),
				fmt.Sprintf("检查 %s 中的 umask 是否符合标准值。", bashrcPath), "077或027",
				fmt.Sprintf("cat ~/.bashrc | grep -v '#' | grep umask | /bin/awk  '{print $2}'"), fmt.Sprintf("修改 %s 中的 umask 为标准值。", bashrcPath),
				"无法打开文件", "人工检测", "/", "/",
			}

			xlsxData = append(xlsxData, data3_1_1)
			return
		} else {
			scanner := bufio.NewScanner(bashrc_file)
			for scanner.Scan() {
				line := scanner.Text()
				line = strings.TrimSpace(line)
				if !strings.HasPrefix(line, "#") && strings.Contains(line, "umask") {
					umask_value := strings.TrimSpace(strings.Split(line, " ")[len(strings.Split(line, " "))-1])
					umask_values = append(umask_values, umask_value)
				}
			}
			if len(umask_values) == 0 {
				result3_1_1_data = fmt.Sprintf("%s 中不存在umask", bashrcPath)
				result3_1_1 = "合规"
				countSuccess++
			} else if len(umask_values) == 1 {
				for _, umask = range umask_values {
					tmpnum := []string{"027", "077"}
					if contains(tmpnum, umask) {
						result3_1_1 = "合规"
						countSuccess++
						result3_1_1_data = fmt.Sprintf("%s中的umask值:%s", bashrcPath, umask)
					} else {
						result3_1_1 = "不合规"
						result3_1_1_data = fmt.Sprintf("%s中的umask值:%s", bashrcPath, umask)
						countFail++
					}
				}
			} else {
				result3_1_1 = "人工判断"
				count_manual++
				result3_1_1_data = fmt.Sprintf("%s中的umask值:\n%s", bashrcPath, strings.Join(umask_values, "\n"))
			}

			data3_1_1 := []string{
				"3.1.1", fmt.Sprintf("检查 %s 中的 umask", bashrcPath), "中危",
				fmt.Sprintf("当用户以交互方式登录时,或者启动新的交互式 Bash shell 时,系统会尝试加载 %s 文件,以读取umask", bashrcPath),
				fmt.Sprintf("检查 %s 中的 umask 是否符合标准值。", bashrcPath), "077或027",
				fmt.Sprintf("cat ~/.bashrc | grep -v '#' | grep umask | /bin/awk  '{print $2}'"),
				fmt.Sprintf("修改 %s 中的 umask 为标准值。", bashrcPath),
				result3_1_1_data, result3_1_1, "/", "/",
			}

			xlsxData = append(xlsxData, data3_1_1)
			if result3_1_1 == "合规" {
				fmt.Printf("3.1.1:检查 %s 中的 umask\t%s\t%s\n", bashrcPath, result3_1_1, umask_values)
			} else {
				fmt.Printf("3.1.1:检查 %s 中的 umask\t%s\t%s\n", bashrcPath, result3_1_1, umask_values)
			}
		}
		// 3.1.2:检查bashrc
		result3_1_2_data := "string"
		result3_1_2 := "string"
		countAll++
		umask_values_bashrc := []string{}
		_, err = os.Stat(bashrc)
		if !os.IsNotExist(err) {
			bashrc_file1, err := os.Open(bashrc)
			if err != nil {
				fmt.Println("Error opening bashrc file:", err)
				return
			}
			defer func() {
				if err = bashrc_file1.Close(); err != nil {
					fmt.Println(err)
				}
			}()
			scanner := bufio.NewScanner(bashrc_file)
			for scanner.Scan() {
				line := scanner.Text()
				line = strings.TrimSpace(line)
				if !strings.HasPrefix(line, "#") && strings.Contains(line, "umask") {
					umask_value := strings.TrimSpace(strings.Split(line, " ")[len(strings.Split(line, " "))-1])
					umask_values_bashrc = append(umask_values_bashrc, umask_value)
				}
			}
			if len(umask_values_bashrc) == 0 {
				result3_1_2_data = fmt.Sprintf("%s 中不存在umask", bashrc)
				result3_1_2 = "合规"
				countSuccess++
			} else if len(umask_values_bashrc) == 1 {
				for _, umask = range umask_values_bashrc {
					tmp = []string{"027", "077"}
					if contains(tmp, umask) {
						result3_1_2 = "合规"
						countSuccess++
						result3_1_2_data = fmt.Sprintf("%s中的umask值:%s", bashrc, umask)
					} else {
						result3_1_2 = "不合规"
						result3_1_2_data = fmt.Sprintf("%s中的umask值:%s", bashrc, umask)
						countFail++
					}
				}
			} else {
				result3_1_2 = "人工判断"
				count_manual++
				result3_1_2_data = fmt.Sprintf("%s中的umask值:\n%s", bashrc, strings.Join(umask_values_bashrc, "\n"))
			}
		}
		data3_1_2 := []string{
			"3.1.2", fmt.Sprintf("检查 %s 中的 umask", bashrc), "中危",
			fmt.Sprintf("当用户以交互方式登录时,或者启动新的交互式 Bash shell 时,系统会尝试加载 %s 文件,以读取umask", bashrc),
			fmt.Sprintf("检查 %s 中的 umask 是否符合标准值。", bashrc), "077或027",
			fmt.Sprintf("cat %s | grep -v '#' | grep umask | /bin/awk  '{{print $2}}'", bashrc),
			fmt.Sprintf("修改 %s 中的 umask 为标准值。", bashrc),
			result3_1_2_data, result3_1_2, "/", "/",
		}
		xlsxData = append(xlsxData, data3_1_2)
		if result3_1_2 == "合规" {
			fmt.Printf("3.1.2:检查 %s 中的 umask\t%s\t%s\n", bashrc, result3_1_2, umask_values_bashrc)
		} else {
			fmt.Printf("3.1.2:检查 %s 中的 umask\t%s\t%s\n", bashrc, result3_1_2, umask_values_bashrc)
		}
		// 3.1.3:检查/etc/profile
		countAll++
		umask_values_profile := []string{}
		result3_1_3_data := "string"
		result3_1_3 := "string"
		_, err = os.Stat(profile_path)
		if !os.IsNotExist(err) {
			profile_file, err1 := os.Open(profile_path)
			if err1 != nil {
				result3_1_3 = "合规"
				countSuccess++
				result3_1_3_data = fmt.Sprintf("%s ", profile_path)
			}
			defer func() {
				if err = profile_file.Close(); err != nil {
					fmt.Println(err)
				}
			}()
			scanner := bufio.NewScanner(profile_file)
			for scanner.Scan() {
				line := scanner.Text()
				line = strings.TrimSpace(line)
				if !strings.HasPrefix(line, "#") && !strings.HasPrefix(line, "  ") && strings.Contains(line, "umask") {
					umask_value := strings.TrimSpace(strings.Split(line, " ")[len(strings.Split(line, " "))-1])
					umask_values_profile = append(umask_values_profile, umask_value)
				}
			}
			if len(umask_values_profile) == 0 {
				scanner = bufio.NewScanner(profile_file)
				for scanner.Scan() {
					line := scanner.Text()
					line = strings.TrimSpace(line)
					if !strings.HasPrefix(line, "#") && strings.Contains(line, "umask") {
						umask_value := strings.TrimSpace(strings.Split(line, " ")[len(strings.Split(line, " "))-1])
						umask_values_profile = append(umask_values_profile, umask_value)
					}
				}
			}
			if len(umask_values_profile) == 0 {
				result3_1_3_data = fmt.Sprintf("%s 中不存在umask", profile_path)
				result3_1_3 = "合规"
				countSuccess++
			} else if len(umask_values_profile) == 1 {
				for _, umask = range umask_values_profile {
					tmp = []string{"027", "077"}
					if contains(tmp, umask) {
						result3_1_3 = "合规"
						countSuccess++
						result3_1_3_data = fmt.Sprintf("%s中的umask值:%s", profile_path, umask)
					} else {
						result3_1_3 = "不合规"
						countFail++
						result3_1_3_data = fmt.Sprintf("%s中的umask值:%s", profile_path, umask)
					}
				}
			} else {
				num := 0
				for _, umask = range umask_values_profile {
					tmp = []string{"027", "077"}
					if contains(tmp, umask) {
						num++
					}
				}
				if num == len(umask_values_profile) {
					result3_1_3 = "合规"
					countSuccess++
					result3_1_3_data = fmt.Sprintf("%s中的umask值:%s", profile_path, umask)
				} else {
					result3_1_3 = "不合规"
					countFail++
					result3_1_3_data = fmt.Sprintf("%s中的umask值:%s", profile_path, umask)
				}
			}
		}

		data3_1_3 := []string{
			"3.1.3", fmt.Sprintf("检查 %s 中的 umask", profile_path), "中危",
			fmt.Sprintf("当用户登录时,系统会尝试加载 %s 文件,以读取umask", profile_path),
			fmt.Sprintf("检查 %s 中的 umask 是否符合标准值。", profile_path), "077或027",
			"cat /etc/profile | grep -v '#' | grep umask | /bin/awk  '{print $2}'",
			fmt.Sprintf("修改 %s 中的 umask 为标准值。", profile_path), result3_1_3_data, result3_1_3, "/", "/",
		}
		xlsxData = append(xlsxData, data3_1_3)
		if result3_1_3 == "合规" {
			fmt.Printf("3.1.3:检查 %s 中的 umask\t%s\t%s\n", profile_path, result3_1_3, umask_values_profile)
		} else {
			fmt.Printf("3.1.3:检查 %s 中的 umask\t%s\t%s\n", profile_path, result3_1_3, umask_values_profile)
		}

		// 3.1.4:检查/etc/login.defs
		countAll++
		umask_values_login := []string{}
		result3_1_4 := "string"
		result3_1_4_data := "string"
		login_file, err := os.Open(login_path)
		defer func() {
			if err = login_file.Close(); err != nil {
				fmt.Println(err)
			}
		}()
		if err != nil {
			fmt.Println("3.1.4:打开/etc/login.defs失败,无法执行接下来的检查,错误信息:\n", err)
		} else {

			scanner := bufio.NewScanner(login_file)
			for scanner.Scan() {
				line := scanner.Text()
				line = strings.TrimSpace(line)
				if !strings.HasPrefix(line, "#") && strings.Contains(line, "UMASK") {
					umask_value := strings.TrimSpace(strings.Split(line, " ")[len(strings.Split(line, " "))-1])
					re = regexp.MustCompile(`\d+`)
					umask_new_value := re.FindString(umask_value)
					umask_values_login = append(umask_values_login, umask_new_value)
				}
			}
			if len(umask_values_login) == 0 {
				result3_1_4_data = fmt.Sprintf("%s 中不存在umask", login_path)
				result3_1_4 = "合规"
				countSuccess++
			} else if len(umask_values_login) == 1 {
				for _, umask = range umask_values_login {
					tmp = []string{"027", "077"}
					if contains(tmp, umask) {
						result3_1_4 = "合规"
						countSuccess++
						result3_1_4_data = fmt.Sprintf("%s中的umask值:%s", login_path, umask)
					} else {
						result3_1_4 = "不合规"
						result3_1_4_data = fmt.Sprintf("%s中的umask值:%s", login_path, umask)
						countFail++
					}
				}
			} else {
				result3_1_4 = "人工判断"
				count_manual++
				result3_1_4_data = fmt.Sprintf("%s中的umask值:\n%s", login_path, strings.Join(umask_values_login, "\n"))
			}
			data3_1_4 := []string{
				"3.1.4", fmt.Sprintf("检查 %s 中的 umask", login_path), "中危",
				fmt.Sprintf("当用户登录时,系统会尝试加载 %s 文件,以读取umask", login_path),
				fmt.Sprintf("检查 %s 中的 umask 是否符合标准值。", login_path), "077或027",
				"cat /etc/login.defs | grep -v '#' | grep umask | /bin/awk  '{print $2}'",
				fmt.Sprintf("修改 %s 中的 umask 为标准值。", login_path), result3_1_4_data, result3_1_4, "/", "/",
			}
			xlsxData = append(xlsxData, data3_1_4)
			if result3_1_4 == "合规" {
				fmt.Printf("3.1.4:检查 %s 中的 umask\t%s\t%s\n", login_path, result3_1_4, umask_values_login)
			} else {
				fmt.Printf("3.1.4:检查 %s 中的 umask\t%s\t%s\n", login_path, result3_1_4, umask_values_login)
			}
		}
	} else {
		countAll++
		countSuccess++
		data3_1_1 := []string{
			"3.1.1", fmt.Sprintf("检查 %s 中的 umask", bashrcPath), "中危",
			fmt.Sprintf("当用户以交互方式登录时,或者启动新的交互式 Bash shell 时,系统会尝试加载 %s 文件,以读取umask", bashrcPath),
			fmt.Sprintf("检查 %s 中的 umask 是否符合标准值。", bashrcPath), "077或027",
			fmt.Sprintf("cat ~/.bashrc | grep -v '#' | grep umask | /bin/awk  '{print $2}'"),
			"首项合规",
			"首项合规", "合规", "/", "/",
		}
		xlsxData = append(xlsxData, data3_1_1)
		countAll++
		countSuccess++
		data3_1_2 := []string{
			"3.1.2", fmt.Sprintf("检查 %s 中的 umask", bashrc), "中危",
			fmt.Sprintf("当用户以交互方式登录时,或者启动新的交互式 Bash shell 时,系统会尝试加载 %s 文件,以读取umask", bashrc),
			fmt.Sprintf("检查 %s 中的 umask 是否符合标准值。", bashrc), "077或027",
			fmt.Sprintf("cat %s | grep -v '#' | grep umask | /bin/awk  '{{print $2}}'", bashrc),
			"首项合规",
			"首项合规", "合规", "/", "/",
		}
		xlsxData = append(xlsxData, data3_1_2)
		countAll++
		countSuccess++
		data3_1_3 := []string{
			"3.1.3", fmt.Sprintf("检查 %s 中的 umask", profile_path), "中危",
			fmt.Sprintf("当用户登录时,系统会尝试加载 %s 文件,以读取umask", profile_path),
			fmt.Sprintf("检查 %s 中的 umask 是否符合标准值。", profile_path), "077或027",
			"cat /etc/profile | grep -v '#' | grep umask | /bin/awk  '{print $2}'",
			"首项合规",
			"首项合规", "合规", "/", "/",
		}
		xlsxData = append(xlsxData, data3_1_3)
		countAll++
		countSuccess++
		data3_1_4 := []string{
			"3.1.4", fmt.Sprintf("检查 %s 中的 umask", login_path), "中危",
			fmt.Sprintf("当用户登录时,系统会尝试加载 %s 文件,以读取umask", login_path),
			fmt.Sprintf("检查 %s 中的 umask 是否符合标准值。", login_path), "077或027",
			"cat /etc/login.defs | grep -v '#' | grep umask | /bin/awk  '{print $2}'",
			"首项合规",
			"首项合规", "合规", "/", "/",
		}
		xlsxData = append(xlsxData, data3_1_4)
	}

	// 3.2:检查是否设置SSH登录前警告Banner
	countAll++
	bannerPath := "/"
	result3_2Data := "未设置 Banner"
	result3_2 := "string"
	sshConfig, err := ioutil.ReadFile("/etc/ssh/sshd_config")
	if err != nil {
		fmt.Println("无法读取 /etc/ssh/sshd_config 文件")
		return
	}
	for _, line := range strings.Split(string(sshConfig), "\n") {
		line = strings.TrimSpace(line)
		if !strings.HasPrefix(line, "#") && strings.Contains(line, "Banner") {
			parts := strings.Split(line, " ")
			if len(parts) == 2 {
				bannerPath = parts[1]
			} else {
				result3_2 = "不合规"
				countFail++
				result3_2Data = fmt.Sprintf("Banner 设置异常\n %s", line)
			}
		}
	}
	if bannerPath != "/" {
		bannerContent, err1 := ioutil.ReadFile(bannerPath)
		if err1 != nil {
			fmt.Println("无法读取 Banner 文件")
			return
		}
		if len(bannerContent) > 0 {
			result3_2 = "合规"
			countSuccess++
			result3_2Data = strings.TrimSpace(string(bannerContent))
		} else {
			result3_2 = "不合规"
			countFail++
			result3_2Data = fmt.Sprintf("Banner指向的文件 %s 为空", bannerPath)
		}
	} else {
		result3_2 = "不合规"
		countFail++
		result3_2Data = "未设置 Banner"
	}
	recommendation3_2 := `
	1、编辑文件/etc/ssh/sshd_config文件,修改Banner参数的值如下(如不存在则新增):
	Banner /etc/ssh_banner
	2、执行如下命令创建SSH banner警示信息文件:
	touch /etc/ssh_banner
	chmod 644 /etc/ssh_banner
	echo "Authorized only. All activity will be monitored and reported" > /etc/ssh_banner
	可根据实际需要修改该文件的内容。
	3、重启sshd服务:
	/etc/init.d/sshd restart`
	data3_2 := []string{
		"3.2", "检查是否设置SSH登录前警告Banner", "中危", "ssh登陆前的警告Banner信息用于警示登陆系统的人员",
		"检查SSH配置文件: /etc/ssh/sshd_config 是否启用banner并合理设置banner的内容", "启用banner并合理设置banner的内容",
		"cat /etc/ssh/sshd_config | grep -v '#' | grep Banner\ncat {Banner设置指向的文件}", recommendation3_2,
		result3_2Data, result3_2, "/", "/",
	}
	xlsxData = append(xlsxData, data3_2)

	fmt.Printf("3.2:检查是否设置SSH登录前警告Banner\t%s\t%s\n", result3_2, result3_2Data)
}

// 4
func SshLog() {

	// 4:日志审计
	// 4.1:检查安全事件日志配置
	countAll++
	syslogConf := map[string][]string{
		"/var/log/messages": {"*.info", "mail.none", "authpriv.none", "cron.none"},
		"/var/log/secure":   {"authpriv.*"},
		"/var/log/cron":     {"cron.*"},
	}
	logsNoSet := make(map[string][]string)
	standardList := make([]string, 0)
	var result4_1_data []string
	for path, logs := range syslogConf {
		logNoSet := make([]string, 0)
		standardList = append(standardList, strings.Join(logs, ";")+"    "+path)
		for _, log := range logs {
			isSetLog := false
			rsyslog, err1 := ioutil.ReadFile("/etc/rsyslog.conf")
			if err1 != nil {
				rsyslog, err1 = ioutil.ReadFile("/etc/systemd/journald.conf")
				if err1 != nil {
					result4_1_data = append(result4_1_data, "/etc/systemd/journald.conf以及/etc/rsyslog.conf打开失败")
					break
				}
			}
			for _, line := range strings.Split(string(rsyslog), "\n") {
				line = strings.TrimSpace(line)
				if !strings.HasPrefix(line, "#") && strings.Contains(line, log) && strings.Contains(line, path) {
					isSetLog = true
					result4_1_data = append(result4_1_data, line)
				}
			}
			if !isSetLog {
				logNoSet = append(logNoSet, log)
			}
		}
		if len(logNoSet) > 0 {
			logsNoSet[path] = logNoSet
		}
	}
	standard := strings.Join(standardList, "\n")
	result4_1_data_str := strings.Join(result4_1_data, "\n")
	recommendation4_1 := "string"
	result4_1 := "string"

	if len(logsNoSet) > 0 {
		result4_1 = "不合规"
		countFail++
		recommendation4_1 = "在 /etc/rsyslog.conf 中写入: \n"
		if _, ok := logsNoSet["0"]; ok {
			result4_1_data_str = result4_1_data_str + "\t" + "未安装rsyslog日志记录服务"
		} else {
			for path, logs := range logsNoSet {
				log := strings.Join(logs, ";")
				result4_1_data_str = result4_1_data_str + fmt.Sprintf("未将 %s 指向 %s", log, path)
				recommendation4_1 += fmt.Sprintf("%s {{多个制表符}} %s\n", log, path)
			}
			result4_1_data_str = strings.TrimSpace(result4_1_data_str)
			recommendation4_1 = strings.TrimSpace(recommendation4_1)
		}

	} else {
		result4_1 = "合规"
		countSuccess++
		recommendation4_1 = "/"
	}
	data4_1 := []string{
		"4.1", "检查安全事件日志配置", "高危", "应对安全事件日志文件进行配置",
		"检查 /etc/rsyslog.conf 中是否按标准值配置了日志保存路径", standard, "cat /etc/rsyslog.conf | grep -v '#' | grep -v '^$'", recommendation4_1,
		result4_1_data_str, result4_1, "/", "/",
	}
	xlsxData = append(xlsxData, data4_1)
	if result4_1 == "合规" {
		fmt.Printf("4.1:检查安全事件日志配置\t%s\n", result4_1)
	} else {
		fmt.Printf("4.1:检查安全事件日志配置\t%s\n", result4_1)
	}

	// 4.2:检查日志文件权限设置
	countAll++
	permissionDict := map[string]int{
		"/var/log/messages": 600,
		//"/var/log/secure":   600,
		"/var/log/auth.log": 600,
		//"/var/log/maillog":  600,
		"/var/log/mail.log": 600,
		//"/var/log/cron":     600,
		"/var/log/syslog": 600,
		"/var/log/dmesg":  644,
		"/var/log/wtmp":   644,
	}

	permissionRecommendation := make([]string, 0)
	result4_2Data := make([]string, 0)
	recommendation4_2 := make([]string, 0)
	flag4_2 := true
	result := "string"
	var recommendation4_2_str string

	for file, permissionSet := range permissionDict {
		permissionRecommendation = append(permissionRecommendation, fmt.Sprintf("%s\t%d", file, permissionSet))
		if _, err := os.Stat(file); err == nil {
			fileStat, _ := os.Stat(file)
			strFileStat := fmt.Sprintf("%o", fileStat.Mode().Perm())
			intFileStat, _ := strconv.Atoi(strFileStat)
			if intFileStat <= permissionSet {
				result = "合规"

			} else {
				result = "不合规"
				flag4_2 = false
				recommendation := fmt.Sprintf("修改%s文件权限\nchmod %d %s", file, permissionSet, file)
				recommendation4_2 = append(recommendation4_2, recommendation)
			}
			result4_2Data = append(result4_2Data, fmt.Sprintf("%s 权限\t%d\t%s", file, intFileStat, result))
		} else {
			flag4_2 = false
			result4_2Data = append(result4_2Data, fmt.Sprintf("%s 文件不存在\t", file))
			//result4_2Data = append(result4_2Data, fmt.Sprintf("%s 文件不存在\t不合规", file))
			recommendation := fmt.Sprintf("创建%s,并设置权限\ntouch %s\nchmod %d %s", file, file, permissionSet, file)
			recommendation4_2 = append(recommendation4_2, recommendation)
		}
	}

	if len(recommendation4_2) > 0 {
		recommendation4_2 = append(recommendation4_2, "重启syslog服务\n/etc/init.d/rsyslog restart")
		recommendation4_2_str = strings.Join(recommendation4_2, "\n")
	}

	var result4_2 string
	var result4_2Data_str string
	var permissionRecommendation_str string
	result4_2Data_str = strings.Join(result4_2Data, "\n")
	permissionRecommendation_str = strings.Join(permissionRecommendation, "\n")

	if flag4_2 {
		result4_2 = "合规"
		countSuccess++
		fmt.Printf("4.2:检查日志文件权限设置\t%s\n", result4_2)
	} else {
		result4_2 = "不合规"
		countFail++
		fmt.Printf("4.2:检查日志文件权限设置\t%s\n", result4_2)
	}

	data4_2 := []string{
		"4.2", "检查日志文件权限设置", "中危",
		"设备应配置权限,控制对日志文件读取、修改和删除等操作\n/var/log/messages\t系统日志\n/var/log/maillog\t邮件系统日志\n/var/log/secure\t安全信息,系统登录与网络连接的信息\n/var/log/dmesg\t核心启动日志\n/var/log/wtmp\t登录记录\n/var/log/cron\tcron(定制任务日志)日志",
		"检查日志文件权限是否小于等于标准值", permissionRecommendation_str, "ls -l {目标文件} 或 stat -c %a {目标文件}",
		recommendation4_2_str, result4_2Data_str, result4_2, "/", "/",
	}
	xlsxData = append(xlsxData, data4_2)

	// 4.3:检查是否配置远程日志功能
	countAll++
	statusCmd := exec.Command("service", "rsyslog", "status")
	statusOutput, _ := statusCmd.Output()
	var result4_3 string
	result4_3Data := make([]string, 0)
	recommendation4_3 := make([]string, 0)
	//recommendation4_3Command := make([]string, 0)
	var flag4_3_1, flag4_3_2, flag4_3_3 bool
	if strings.Contains(string(statusOutput), "Active") {
		if strings.Contains(string(statusOutput), "Active: active (running)") {
			result4_3Data = append(result4_3Data, "rsyslog 服务正在运行")
			flag4_3_1 = true
		} else {
			result4_3Data = append(result4_3Data, "rsyslog 服务未运行")
			flag4_3_1 = false
			recommendation4_3 = append(recommendation4_3, "运行 rsyslog 服务")
			//recommendation4_3Command = append(recommendation4_3Command, "service rsyslog start")
		}
		for _, line := range strings.Split(string(statusOutput), "\n") {
			if strings.HasPrefix(line, "Loaded") {
				if !strings.Contains(line, "disabled;") {
					result4_3Data = append(result4_3Data, "rsyslog 服务已启用")
					flag4_3_2 = true
				} else {
					result4_3Data = append(result4_3Data, "rsyslog 服务未启用")
					recommendation4_3 = append(recommendation4_3, "启用 rsyslog 服务")
					//recommendation4_3Command = append(recommendation4_3Command, "systemctl enable rsyslog")
					flag4_3_2 = false
				}
			}
		}
	} else if strings.Contains(string(statusOutput), "is running...") || strings.Contains(string(statusOutput), "is stopped") {
		if strings.Contains(string(statusOutput), "is running...") {
			result4_3Data = append(result4_3Data, "rsyslog 服务正在运行")
			flag4_3_1 = true
		} else {
			result4_3Data = append(result4_3Data, "rsyslog 服务未运行")
			flag4_3_1 = false
			recommendation4_3 = append(recommendation4_3, "运行 rsyslog 服务")
			//recommendation4_3Command = append(recommendation4_3Command, "service rsyslog start")
		}
		chkconfigCmd := exec.Command("chkconfig", "--list", "|", "grep", "rsyslog")
		chkconfigOutput, err1 := chkconfigCmd.Output()
		if err1 != nil {
			fmt.Println("无法执行 chkconfig 命令")
			return
		}
		if strings.Contains(string(chkconfigOutput), "on") {
			result4_3Data = append(result4_3Data, "rsyslog 服务已启用")
			flag4_3_2 = true
		} else {
			result4_3Data = append(result4_3Data, "rsyslog 服务未启用")
			recommendation4_3 = append(recommendation4_3, "启用 rsyslog 服务")
			//recommendation4_3Command = append(recommendation4_3Command, "systemctl enable rsyslog")
			flag4_3_2 = false
		}
	}
	if _, err := os.Stat("/etc/rsyslog.conf"); err == nil {
		mark := "/"
		rsyslog, err1 := ioutil.ReadFile("/etc/rsyslog.conf")
		if err1 != nil {
			fmt.Println("无法读取 /etc/rsyslog.conf 文件")
			return
		}
		for _, line := range strings.Split(string(rsyslog), "\n") {
			line = strings.TrimSpace(line)
			if !strings.HasPrefix(line, "#") && strings.Contains(line, "@") {
				mark = line
				result4_3Data = append(result4_3Data, line)
				flag4_3_3 = true
			}
		}
		if mark == "/" {
			recommendation4_3 = append(recommendation4_3, fmt.Sprintf("根据需求在 /etc/rsyslog.conf 中添加或修改,{日志类型}.{日志级别}{制表符}@{日志服务器IP}:{端口},详情参考 /etc/rsyslog.conf 中的注释\n重启 syslog 服务\n service rsyslog restart"))
			//recommendation4_3Command = append(recommendation4_3Command, "请根据需求修改 /etc/rsyslog.conf")
			result4_3Data = append(result4_3Data, "rsyslog.conf 未正确配置")
		}
	} else {
		result4_3Data = append(result4_3Data, "/etc/rsyslog.conf 文件不存在")
	}
	if (flag4_3_1 || flag4_3_2) && flag4_3_3 {
		result4_3 = "合规"
		countSuccess++
	} else if flag4_3_1 || flag4_3_2 || flag4_3_3 {
		result4_3 = "部分合规"
		countFail++
	} else {
		result4_3 = "不合规"
		countFail++
	}
	recommendation4_3Message := strings.Join(recommendation4_3, "\n")
	//recommendation4_3CommandMessage := strings.Join(recommendation4_3Command, "\n")
	result4_3DataMessage := strings.Join(result4_3Data, "\n")
	data4_3 := []string{
		"4.3", "检查是否配置远程日志功能", "中危", "日志应统一管理",
		"检查 rsyslog 服务启动并启用,检查 /etc/rsyslog.conf 是否正确配置日志转发。", "按需将日志转发至远程服务器",
		"service rsyslog status\n cat /etc/rsyslog.conf | grep -v '#' | grep '@'", recommendation4_3Message,
		result4_3DataMessage, result4_3, "/", "/",
	}
	xlsxData = append(xlsxData, data4_3)

	fmt.Printf("4.3:检查是否配置远程日志功能\t%s\n", result4_3)

	// 4.4:检查是否启用审计服务
	countAll++
	var result4_4Data string
	var result4_4 string
	auditCheckCommand := exec.Command("ps", "-ef", "|", "grep", "auditd", "|", "grep", "-v", "grep", "|", "grep", "-v", "kauditd")
	auditOutput, _ := auditCheckCommand.Output()
	recommendation4_4 := `使用包管理器安装auditd,启用并启动auditd 服务`
	if len(auditOutput) == 0 {
		result4_4Data = "auditd 未启动"
		countFail++
		result4_4 = "不合规"
		fmt.Println("4.4:检查是否启用审计服务\t不合规")
	} else {
		result4_4Data = "auditd 已启动"
		countSuccess++
		result4_4 = "合规"
		fmt.Println("4.4:检查是否启用审计服务\t合规")
		recommendation4_4 = "/"
	}
	data4_4 := []string{
		"4.4", "检查是否启用审计服务", "中危",
		"应启用auditd,auditd 是 Linux 操作系统上用于审计的守护进程。它是 Linux 内核审计框架的用户空间组件,负责收集、处理和记录与系统安全相关的事件。审计日志记录的信息包括用户登录、文件访问、进程创建和终止、系统调用等。",
		"auditd 已启动", "/", "ps -ef | grep auditd | grep -v grep | grep -v kauditd", recommendation4_4, result4_4Data,
		result4_4, "/", "/",
	}
	xlsxData = append(xlsxData, data4_4)
}

// 5
func Ftp_Telnet_Snmp() {
	countAll++
	flag5_1 := true
	var result string
	var result5_1 string
	result5_1Data := []string{}
	permissionRecommendation := []string{}
	recommendation5_1 := []string{}
	permissionDict := map[string]string{
		"/etc/shadow":   "400",
		"/etc/passwd":   "644",
		"/etc/group":    "644",
		"/etc":          "755",
		"/etc/security": "755",
		"/etc/services": "644",
		//"/etc/grub.conf":      600,
		"/etc/grub/grub.conf": "600",
		"/boot/grub/grub.cfg": "600",
		"/etc/default/grub":   "600",
		//"/etc/lilo.conf":      600,
		"/etc/systemd/system": "600",
		"/tmp":                "750",
		//"/etc/rc.d/init.d":    755,
		"/lib/systemd/system/": "755",
		"/etc/xinetd.conf":     "600",
		"/etc/inetd.conf":      "600",
	}
	permissionCheckFalse := []string{}
	for path, permissionSet := range permissionDict {
		permissionRecommendation = append(permissionRecommendation, fmt.Sprintf("%s\t%s", path, permissionSet))
		if _, err := os.Stat(path); err == nil {
			info, _ := os.Stat(path)
			strFileStat := fmt.Sprintf("%o", info.Mode().Perm())
			intpermissionSet, _ := strconv.Atoi(permissionSet)
			intFileStat, _ := strconv.Atoi(strFileStat)
			if intFileStat <= intpermissionSet {
				result = "合规"
			} else {
				result = "不合规"
				flag5_1 = false
				recommendation := fmt.Sprintf("# 修改%s文件权限\nchmod %s %s", path, permissionSet, path)
				recommendation5_1 = append(recommendation5_1, recommendation)
				permissionCheckFalse = append(permissionCheckFalse, path)
			}
			result5_1Data = append(result5_1Data, fmt.Sprintf("%s 权限\t%d\t%s", path, intFileStat, result))
		} else {
			result5_1Data = append(result5_1Data, fmt.Sprintf("%s 文件不存在\t合规", path))
		}
	}
	if flag5_1 {
		result5_1 = "合规"
		countSuccess++
		fmt.Printf("5.1:检查重要目录或文件权限设置\t%s\n", result5_1)
	} else {
		result5_1 = "不合规"
		countFail++
		fmt.Printf("5.1:检查重要目录或文件权限设置\t%s\n", result5_1)
		recommendation5_1 = append(recommendation5_1, fmt.Sprintf("# 重新检查权限\nstat -c %%a %s", permissionCheckFalse))
	}
	newPermissionRecommendation := strings.Join(permissionRecommendation, "\n")
	newRecommendation5_1 := strings.Join(recommendation5_1, "\n")
	newResult5_1Data := strings.Join(result5_1Data, "\n")
	data5_1 := []string{
		"5.1", "检查重要目录或文件权限设置", "中危", "在设备权限配置能力内,根据用户的业务需要,配置其所需的最小权限。",
		"检查目标权限是否小于等于标准值", newPermissionRecommendation, "ls -l {目标} 或 stat -c %a {目标}", newRecommendation5_1,
		newResult5_1Data, result5_1, "/", "/",
	}
	xlsxData = append(xlsxData, data5_1)

	var result5_2 string

	countAll++
	result5_2Data := []string{}
	recommendation5_2 := []string{}

	// Check FTP process
	ftpCheckCommand := exec.Command("sh", "-c", "ps -ef | grep ftpd | grep -v grep | wc -l")
	ftpOutput, err := ftpCheckCommand.Output()
	if err != nil {
		fmt.Println("Error executing FTP check command:", err)
		return
	}
	ftpStat := strings.TrimSpace(string(ftpOutput))
	if ftpStat == "0" {
		result5_2Data = append(result5_2Data, "FTP进程不存在")
		result5_2 = "合规"
		countSuccess++
		fmt.Println("5.2:检查FTP用户上传的文件所具有的权限\t合规")
		return
	}

	// 检查 local_umask
	localUmaskCheckCommand := exec.Command("sh", "-c", "cat /etc/vsftpd/vsftpd.conf | grep -v '^[[:space:]]*#' | grep local_umask")
	localUmaskOutput, err := localUmaskCheckCommand.Output()
	if err != nil {
		fmt.Println("Error executing local umask check command:", err)
		return
	}
	localUmask := strings.TrimSpace(string(localUmaskOutput))
	localUmaskFlag := false
	if localUmask != "/" {
		localUmaskNum, err := strconv.Atoi(strings.Split(localUmask, "=")[1])
		if err != nil {
			fmt.Println("Error converting local umask:", err)
			return
		}
		if localUmaskNum == 22 {
			localUmaskFlag = true
			result5_2Data = append(result5_2Data, fmt.Sprintf("%s\t合规", localUmask))
		} else {
			result5_2Data = append(result5_2Data, fmt.Sprintf("%s\t不合规", localUmask))
			recommendation5_2 = append(recommendation5_2, "在 /etc/vsftpd/vsftpd.conf 中修改 local_umask=022")
		}
	} else {
		result5_2Data = append(result5_2Data, "local_umask 未设置")
		recommendation5_2 = append(recommendation5_2, "在 /etc/vsftpd/vsftpd.conf 中添加 local_umask=022")
	}

	// 检查 anon_umask
	anonUmaskCheckCommand := exec.Command("sh", "-c", "cat /etc/vsftpd/vsftpd.conf | grep -v '^[[:space:]]*#' | grep anon_umask")
	anonUmaskOutput, err := anonUmaskCheckCommand.Output()
	if err != nil {
		fmt.Println("Error executing anon umask check command:", err)
		return
	}
	anonUmaskFlag := false
	anonUmask := strings.TrimSpace(string(anonUmaskOutput))
	if anonUmask != "/" {
		anonUmaskNum, err := strconv.Atoi(strings.Split(anonUmask, "=")[1])
		if err != nil {
			fmt.Println("Error converting anon umask:", err)
			return
		}
		if anonUmaskNum == 22 {
			anonUmaskFlag = true
			result5_2Data = append(result5_2Data, fmt.Sprintf("%s\t合规", anonUmask))
		} else {
			result5_2Data = append(result5_2Data, fmt.Sprintf("%s\t不合规", anonUmask))
			recommendation5_2 = append(recommendation5_2, "在 /etc/vsftpd/vsftpd.conf 中修改 anon_umask=022")
		}
	} else {
		result5_2Data = append(result5_2Data, "anon_umask 未设置")
		recommendation5_2 = append(recommendation5_2, "在 /etc/vsftpd/vsftpd.conf 中添加 anon_umask=022")
	}

	// Final result
	if localUmaskFlag && anonUmaskFlag {
		result5_2 = "合规"
		countSuccess++
		fmt.Println("5.2:检查FTP用户上传的文件所具有的权限\t合规")
	} else {
		result5_2 = "不合规"
		countFail++
		fmt.Println("5.2:检查FTP用户上传的文件所具有的权限\t不合规")
	}

	result5_2DataStr := strings.Join(result5_2Data, "\n")
	recommendation5_2Str := strings.Join(recommendation5_2, "\n")
	data5_2 := []string{
		"5.2", "检查FTP用户上传的文件所具有的权限", "中危", "设置FTP用户登录后对文件目录的存取权限。",
		"检查FTP进程,若不存在,则合规;否则检查 /etc/vsftpd/vsftpd.conf 中 local_umask、anon_umask 配置是否符合标准",
		"FTP进程不存在或local_umask、anon_umask=022",
		"ps -ef|grep ftpd|grep -v grep\ncat /etc/vsftpd/vsftpd.conf|grep -v \"^[[:space:]]*#\"|grep \"local_umask\"\ncat /etc/vsftpd/vsftpd.conf|grep -v \"^[[:space:]]*#\"|grep \"anon_umask\"/",
		recommendation5_2Str, result5_2DataStr, result5_2, "/", "/",
	}
	xlsxData = append(xlsxData, data5_2)
}

// 6
func Openssh_Root() {

	// 6:网络通信
	// 6.1:检查是否禁用Telnet协议
	countAll++
	telnetCheckCommand := exec.Command("ps", "-ef", "|", "grep", "inetd", "|", "grep", "-v", "grep")
	telnetOutput, err := telnetCheckCommand.Output()
	if err != nil {
		if err.Error() != "exit status 1" {
			fmt.Println("6.1:执行 Telnet 命令失败:", err)
			recommendation6_1 := "/"
			result6_1Data := "/"
			result6_1 := "执行失败"
			data6_1 := []string{
				"6.1", "检查是否禁用Telnet协议", "高危", "不应使用不安全的Telnet进行远程管理。",
				"检查Telnet服务是否启动", "Telnet 已禁用", "ps -ef | grep inetd | grep -v grep\nps -ef | grep xinetd | grep -v grep", recommendation6_1, result6_1Data, result6_1, "/", "/",
			}
			xlsxData = append(xlsxData, data6_1)
		} else {
			//fmt.Println("6.1:检查是否禁用Telnet协议命令输出:|", reflect.TypeOf(telnetOutput), "|", telnetOutput, "|")
			var telnetOutput1 []byte
			if string(telnetOutput) == "" {
				telnetCheckCommand = exec.Command("ps", "-ef", "|", "grep", "xinetd", "|", "grep", "-v", "grep")
				telnetOutput1, _ = telnetCheckCommand.Output()
			}
			var recommendation6_1 string
			var result6_1 string
			var result6_1Data string
			//res := make([]uint8, 1)
			if len(telnetOutput1) > 0 {
				result6_1 = "不合规"
				countFail++
				fmt.Println("6.1:检查是否禁用Telnet协议\t不合规")
				result6_1Data = strings.TrimSpace(string(telnetOutput))
				recommendation6_1 = `
关闭Telnet服务xinetd或inetd:
以下以xinetd为例
备份
cp -p /etc/xinetd.d/telnet /etc/xinetd.d/telnet_bak
编辑文件/etc/xinetd.d/telnet,把disable项改为yes.
执行以下命令重启xinetd服务。
service xinetd restart`
			} else {
				result6_1 = "合规"
				fmt.Println("6.1:检查是否禁用Telnet协议\t合规")
				countSuccess++
				result6_1Data = "Telnet 已禁用"
				data6_1 := []string{
					"6.1", "检查是否禁用Telnet协议", "高危", "不应使用不安全的Telnet进行远程管理。",
					"检查Telnet服务是否启动", "Telnet 已禁用", "ps -ef | grep inetd | grep -v grep\nps -ef | grep xinetd | grep -v grep", recommendation6_1, result6_1Data, result6_1, "/", "/",
				}
				xlsxData = append(xlsxData, data6_1)
			}
			//}
			// 6.2:检查是否使用PAM认证模块禁止wheel组之外的用户su为root
			countAll++
			suFilePath := "/etc/pam.d/su"
			result6_2Data := "未使用PAM认证模块禁止wheel组之外的用户su为root"
			result6_2 := "不合规"
			recommendation6_2 := `
编辑文件/etc/pam.d/su
在文件开头加入如下两行(有则修改,没有则添加):
auth sufficient pam_rootok.so
auth required pam_wheel.so use_uid
#注意auth与sufficient之间由两个tab建隔开,sufficient与动态库路径之间使用一个tab建隔开
说明:(这表明只有wheel组中的用户可以使用su命令成为root用户。你可以把用户添加到wheel组,以使它可以使用su命令成为root用户。)
添加方法:
#usermod -G wheel username #username为需要添加至wheel组的账户名称。`
			if _, err = os.Stat(suFilePath); err == nil {
				file, err1 := os.Open(suFilePath)
				if err1 != nil {
					fmt.Println("6.2 Error opening su file:", err)
					return
				}
				defer func() {
					if err = file.Close(); err != nil {
						fmt.Println(err)
					}
				}()
				scanner := bufio.NewScanner(file)
				for scanner.Scan() {
					line := scanner.Text()
					if !strings.HasPrefix(line, "#") && strings.Contains(line, "pam_wheel.so") {
						result6_2Data = line
						result6_2 = "合规"
						break
					}
				}
				if err1 = scanner.Err(); err1 != nil {
					fmt.Println("6.2 Error reading su file:", err1)
					return
				}
			} else if os.IsNotExist(err) {
				result6_2Data = fmt.Sprintf("%s 不存在", suFilePath)
			}
			if result6_2 == "合规" {
				fmt.Println("6.2:检查是否使用PAM认证模块禁止wheel组之外的用户su为root\t 合规")
			} else {
				fmt.Println("6.2:检查是否使用PAM认证模块禁止wheel组之外的用户su为root\t 不合规")
			}
			data6_2 := []string{
				"6.2", "检查是否使用PAM认证模块禁止wheel组之外的用户su为root", "高危",
				"应使用PAM认证模块禁止wheel组之外的用户su为root",
				fmt.Sprintf("检查%s 是否使用PAM认证模块禁止wheel组之外的用户su为root", suFilePath), "使用PAM认证模块禁止wheel组之外的用户su为root", "cat /etc/pam.d/su | grep -v '#' | grep auth | grep pam_wheel.so", recommendation6_2, result6_2Data,
				result6_2, "/", "/",
			}
			xlsxData = append(xlsxData, data6_2)
		}
	}

	// 6.3:是否修改SNMP默认团体字
	countAll++
	result6_3Data := []string{}
	recommendation6_3 := []string{}
	result6_3 := "不合规"
	snmpdConf := "/etc/snmp/snmpd.conf"
	snmpCheckCommand := exec.Command("ps", "-ef", "|", "grep", "snmpd", "|", "egrep", "-v", "grep", "|", "wc", "-l")
	snmpOutput, err := snmpCheckCommand.Output()
	if err != nil {
		if err.Error() != "exit status 1" {
			fmt.Println("6.3 执行 SNMP 命令错误:", err)
			recommendation6_3Str := "/"
			result6_3DataStr := "/"
			result6_3 = err.Error()
			data6_3 := []string{
				"6.3", "检查是否修改SNMP默认团体字", "中危",
				"如果没有必要,需要停止SNMP服务,如果确实需要使用SNMP服务,需要修改SNMP Community。",
				"检查snmpd服务是否已启动,若已启动,则检查是否修改团体名,否则合规。", "未启动snmp服务,或已修改团体名",
				"ps -ef|grep snmpd|egrep -v \"grep\"|wc -l\nvim /etc/snmp/snmpd.conf", recommendation6_3Str, result6_3DataStr, result6_3, "/", "/",
			}
			count_manual++
			xlsxData = append(xlsxData, data6_3)
		} else {
			snmpOutputStr := strings.TrimSpace(string(snmpOutput))
			snmpPubilc := false
			if snmpOutputStr == "0" || snmpOutputStr == "" || reflect.TypeOf(snmpOutputStr) == reflect.TypeOf(int(0)) {
				result6_3 = "合规"
				result6_3Data = append(result6_3Data, "snmp服务未启动")
			} else {
				result6_3Data = append(result6_3Data, "snmp服务已启动")
				if _, err = os.Stat(snmpdConf); err == nil {
					file, err1 := os.Open(snmpdConf)
					if err1 != nil {
						fmt.Println("6.3 Error opening snmpd.conf file:", err1)
						recommendation6_3Str := "/"
						result6_3DataStr := "/"
						result6_3 = err1.Error()
						data6_3 := []string{
							"6.3", "检查是否修改SNMP默认团体字", "中危",
							"如果没有必要,需要停止SNMP服务,如果确实需要使用SNMP服务,需要修改SNMP Community。",
							"检查snmpd服务是否已启动,若已启动,则检查是否修改团体名,否则合规。", "未启动snmp服务,或已修改团体名",
							"ps -ef|grep snmpd|egrep -v \"grep\"\nvim /etc/snmp/snmpd.conf", recommendation6_3Str, result6_3DataStr, result6_3, "/", "/",
						}
						count_manual++
						xlsxData = append(xlsxData, data6_3)
					}
					defer func() {
						if err = file.Close(); err != nil {
							fmt.Println(err)
						}
					}()
					scanner := bufio.NewScanner(file)
					for scanner.Scan() {
						line := scanner.Text()
						if strings.HasPrefix(line, "rocommunity") {
							if strings.Contains(line, "public") {
								result6_3Data = append(result6_3Data, fmt.Sprintf("%s\t不合规", line))
								snmpPubilc = true
							} else {
								result6_3Data = append(result6_3Data, fmt.Sprintf("%s\t合规", line))
							}
						}
					}
					if err = scanner.Err(); err != nil {
						fmt.Println("6.3 Error reading snmpd.conf file:", err)
						return
					}
					if snmpPubilc {
						result6_3 = "不合规"
						recommendation6_3 = append(recommendation6_3, fmt.Sprintf("修改snmp配置文件/etc/snmp/snmpd.conf找到类似如下配置,修改默认团体名public为其他用户自己可识别的字符串\nrocommunity  public default -V systemonly\n重启snmp服务\nservice snmpd restart"))
					} else {
						result6_3 = "合规"
					}
				} else if os.IsNotExist(err) {
					result6_3Data = append(result6_3Data, fmt.Sprintf("%s 不存在", snmpdConf))
				}
			}
			recommendation6_3Str := strings.Join(recommendation6_3, "\n")
			result6_3DataStr := strings.Join(result6_3Data, "\n")
			if result6_3 == "合规" {
				countSuccess++
				fmt.Println("6.3:检查是否修改SNMP默认团体字\t 合规")
			} else {
				countFail++
				fmt.Println("6.3:检查是否修改SNMP默认团体字\t 不合规")
			}
			data6_3 := []string{
				"6.3", "检查是否修改SNMP默认团体字", "中危",
				"如果没有必要,需要停止SNMP服务,如果确实需要使用SNMP服务,需要修改SNMP Community。",
				"检查snmpd服务是否已启动,若已启动,则检查是否修改团体名,否则合规。", "未启动snmp服务,或已修改团体名",
				"ps -ef|grep snmpd|egrep -v \"grep\"\nvim /etc/snmp/snmpd.conf", recommendation6_3Str, result6_3DataStr, result6_3, "/", "/",
			}
			xlsxData = append(xlsxData, data6_3)
			//}
			// 6.4:检查是否禁止root用户远程登录
			countAll++
			sshdConfigPath := "/etc/ssh/sshd_config"
			result6_4Data := make([]string, 0)
			recommendation6_4 := "/"
			result6_4 := "不合规"
			if _, err = os.Stat(sshdConfigPath); err == nil {
				recommendation6_4 = `
执行备份:
cp -p /etc/ssh/sshd_config /etc/ssh/sshd_config_bak
2、新建一个普通用户并设置高强度密码(防止设备上只存在root用户可用时,无法远程访问):
useradd {username}
passwd {username}
3、禁止root用户远程登录系统
编辑文件/etc/ssh/sshd_config,修改PermitRootLogin值为no并去掉注释。
PermitRootLogin no
4、重启SSH服务
/etc/init.d/sshd restart`
				contents, err1 := ioutil.ReadFile(sshdConfigPath)
				if err1 != nil {
					fmt.Println("6.4读取文件失败:", err)
					return
				}
				for _, line := range strings.Split(string(contents), "\n") {
					line = strings.TrimSpace(line)
					if !strings.HasPrefix(line, "#") && strings.Contains(line, "PermitRootLogin") {
						result6_4Data = append(result6_4Data, line)
						rootLoginSetting := strings.Split(line, " ")[1]
						if rootLoginSetting == "no" || rootLoginSetting == "NO" {
							result6_4 = "合规"
							recommendation6_4 = "/"
						} else {
							result6_4 = "不合规"
						}
					}
				}
			} else {
				result6_4 = "不合规"
				result6_4Data = append(result6_4Data, fmt.Sprintf("%s 不存在", sshdConfigPath))
				recommendation6_4 = fmt.Sprintf("%s 不存在,请检查ssh配置文件", sshdConfigPath)
			}
			if result6_4 == "合规" {
				fmt.Println("6.4:检查是否禁止root用户远程登录\t合规")
				countSuccess++
			} else {
				fmt.Println("6.4:检查是否禁止root用户远程登录\t不合规")
				countFail++
			}
			var result6_4Data_srt string
			if len(result6_4Data) > 0 {
				result6_4Data_srt = strings.Join(result6_4Data, "\n")
			} else {
				result6_4Data_srt = "未在 /etc/ssh/sshd_config 中找到 PermitRootLogin 配置"
			}
			data6_4 := []string{
				"6.4", "检查是否禁止root用户远程登录", "高危",
				"在SSH上不允许root登录,需要服务器管理员使用自己的帐户进行身份验证,然后通过sudo或su升级到根,这反过来限制了不可抵赖的机会,并在发生安全事件时提供了清晰的审计线索",
				"查看文件/etc/ssh/sshd_config,是否存在拒绝root用户通过SSH协议远程登录的配置", "PermitRootLogin no",
				"cat /etc/ssh/sshd_config | grep -v '#' | grep PermitRootLogin", recommendation6_4, result6_4Data_srt, result6_4, "/", "/",
			}
			xlsxData = append(xlsxData, data6_4)
		}
	}
}

// 7
func His_Ntp_Cad() {

	// 7:其他配置
	// 7.1:检查系统openssh安全配置
	countAll++
	sshdConfigPath := "/etc/ssh/sshd_config"
	result7_1 := "合规"
	result7_1Data := make([]string, 0)
	recommendation7_1 := make([]string, 0)
	if _, err := os.Stat(sshdConfigPath); err == nil {
		contents, err1 := ioutil.ReadFile(sshdConfigPath)
		if err1 != nil {
			fmt.Println("7.1 读取文件失败:", err1)
			return
		}
		flag7_1 := false
		for _, line := range strings.Split(string(contents), "\n") {
			line = strings.TrimSpace(line)
			if !strings.HasPrefix(line, "#") && strings.Contains(line, "X11Forwarding") {
				flag7_1 = true
				result7_1Data = append(result7_1Data, line)
				setting := strings.Split(line, " ")[1]
				if setting != "no" && setting != "NO" {
					result7_1 = "不合规"
					recommendation7_1 = append(recommendation7_1, "X11Forwarding no")
					break
				}
			}
		}
		if !flag7_1 {
			result7_1Data = append(result7_1Data, "X11Forwarding 被注释")
			recommendation7_1 = append(recommendation7_1, "X11Forwarding no")
		}
		flag7_1 = false
		for _, line := range strings.Split(string(contents), "\n") {
			line = strings.TrimSpace(line)
			if !strings.HasPrefix(line, "#") && strings.Contains(line, "MaxAuthTries") {
				flag7_1 = true
				result7_1Data = append(result7_1Data, line)
				if setting, err2 := strconv.Atoi(strings.Split(line, " ")[1]); err2 == nil {
					if setting > 5 {
						result7_1 = "不合规"
						recommendation7_1 = append(recommendation7_1, "MaxAuthTries 4")
						break
					}
				} else {
					result7_1 = "不合规"
					recommendation7_1 = append(recommendation7_1, "MaxAuthTries 4")
				}
			}
		}
		if !flag7_1 {
			result7_1Data = append(result7_1Data, "MaxAuthTries 被注释")
			recommendation7_1 = append(recommendation7_1, "MaxAuthTries 4")
		}
		flag7_1 = false
		for _, line := range strings.Split(string(contents), "\n") {
			line = strings.TrimSpace(line)
			if !strings.HasPrefix(line, "#") && strings.Contains(line, "IgnoreRhosts") {
				flag7_1 = true
				result7_1Data = append(result7_1Data, line)
				setting := strings.Split(line, " ")[1]
				if setting != "yes" && setting != "YES" {
					result7_1 = "不合规"
					recommendation7_1 = append(recommendation7_1, "IgnoreRhosts yes")
					break
				}
			}
		}
		if !flag7_1 {
			result7_1Data = append(result7_1Data, "IgnoreRhosts 被注释")
			recommendation7_1 = append(recommendation7_1, "IgnoreRhosts yes")
		}
		flag7_1 = false
		for _, line := range strings.Split(string(contents), "\n") {
			line = strings.TrimSpace(line)
			if !strings.HasPrefix(line, "#") && strings.Contains(line, "HostbasedAuthentication") {
				flag7_1 = true
				result7_1Data = append(result7_1Data, line)
				setting := strings.Split(line, " ")[1]
				if setting != "no" && setting != "NO" {
					result7_1 = "不合规"
					recommendation7_1 = append(recommendation7_1, "HostbasedAuthentication no")
					break
				}
			}
		}
		if !flag7_1 {
			result7_1Data = append(result7_1Data, "HostbasedAuthentication 被注释")
			recommendation7_1 = append(recommendation7_1, "HostbasedAuthentication no")
		}
		flag7_1 = false
		for _, line := range strings.Split(string(contents), "\n") {
			line = strings.TrimSpace(line)
			if !strings.HasPrefix(line, "#") && strings.Contains(line, "PermitEmptyPasswords") {
				flag7_1 = true
				result7_1Data = append(result7_1Data, line)
				setting := strings.Split(line, " ")[1]
				if setting != "no" && setting != "NO" {
					result7_1 = "不合规"
					recommendation7_1 = append(recommendation7_1, "PermitEmptyPasswords no")
					break
				}
			}
		}
		if !flag7_1 {
			result7_1Data = append(result7_1Data, "PermitEmptyPasswords 被注释")
			recommendation7_1 = append(recommendation7_1, "PermitEmptyPasswords no")
		}
		if result7_1 != "合规" {
			recommendation7_1 = []string{"编辑配置文件/etc/ssh/sshd_config,修改下面几个参数的值:\n" + strings.Join(recommendation7_1, "\n") + "\n重启ssh服务\n/etc/init.d/sshd restart"}
		} else {
			recommendation7_1 = []string{"/"}
		}
	} else {
		result7_1 = "不合规"
		result7_1Data = append(result7_1Data, fmt.Sprintf("%s 不存在", sshdConfigPath))
		recommendation7_1 = []string{fmt.Sprintf("%s 不存在,请检查ssh配置文件", sshdConfigPath)}
	}
	var result7_1Data_str string
	result7_1Data_str = strings.Join(result7_1Data, "\n")
	data7_1 := []string{
		"7.1", "检查系统openssh安全配置", "高危",
		"强烈建议系统放弃旧的明文登录协议,使用SSH防止会话劫持和嗅探网络上的敏感数据",
		"查看配置文件/etc/ssh/sshd_config,检查以下几个参数的配置值是否满足安全要求:\nX11Forwarding\tx11转发功能,如果没有需要使用此功能的应用应该关闭该功能\nMaxAuthTries\t指定每个连接允许的身份验证尝试的最大数量。建议配置为4次或者更少\nIgnoreRhosts\t此参数将强制用户在使用SSH进行身份验证时输入密码,建议开启开功能\nHostbasedAuthentication\t开启主机认证,建议关闭该功能\nPermitEmptyPasswords\t允许空密码登录,建议关闭该功能",
		"X11Forwarding no\nMaxAuthTries 4\nIgnoreRhosts yes\nHostbasedAuthentication no\nPermitEmptyPasswords no",
		"grep -v '#' /etc/ssh/sshd_config | grep -e X11Forwarding -e MaxAuthTries -e IgnoreRhosts -e HostbasedAuthentication -e PermitEmptyPasswords",
		strings.Join(recommendation7_1, "\n"), result7_1Data_str, result7_1, "/", "/",
	}
	xlsxData = append(xlsxData, data7_1)
	if result7_1 == "合规" {
		fmt.Println("7.1:检查系统openssh安全配置\t合规")
		countSuccess++
	} else {
		fmt.Println("7.1:检查系统openssh安全配置\t不合规")
		countFail++
	}

	// 7.2:检查是否禁止匿名用户登录FTP
	countAll++
	var result7_2 string
	result7_2Data := make([]string, 0)
	recommendation7_2 := make([]string, 0)
	anonymousEnable := false
	ftpCheckCommand := "ps -ef | grep ftpd | grep -v grep | wc -l"
	checkProcess := exec.Command("bash", "-c", ftpCheckCommand)
	ftpOutput, err := checkProcess.Output()
	if err != nil {
		fmt.Println("执行命令失败:", err)
	} else {

		ftpStat := strings.TrimSpace(string(ftpOutput))
		ftpConfig := "/"
		if ftpStat == "0" {
			result7_2Data = append(result7_2Data, "FTP进程不存在")
			result7_2 = "合规"
			countSuccess++
		} else {
			result7_2Data = append(result7_2Data, "FTP进程已启动")
			if _, err = os.Stat("/etc/vsftpd.conf"); err == nil {
				ftpConfig = "/etc/vsftpd.conf"
			} else if _, err = os.Stat("/etc/vsftpd/vsftpd.conf"); err == nil {
				ftpConfig = "/etc/vsftpd/vsftpd.conf"
			} else {
				result7_2Data = append(result7_2Data, "FTP 配置文件未找到")
				recommendation7_2 = append(recommendation7_2, "FTP 配置文件未找到,人工检查")
			}
			if ftpConfig != "/" {
				contents, err1 := ioutil.ReadFile(ftpConfig)
				if err1 != nil {
					fmt.Println("读取文件失败:", err1)
					return
				}
				for _, line := range strings.Split(string(contents), "\n") {
					line = strings.TrimSpace(line)
					if strings.Contains(line, "anonymous_enable=") {
						result7_2Data = append(result7_2Data, line)
						if strings.Split(line, "=")[1] == "yes" || strings.Split(line, "=")[1] == "YES" {
							anonymousEnable = true
							recommendation7_2 = append(recommendation7_2, fmt.Sprintf("编辑文件%s,修改参数anonymous_enable的值为NO:\nanonymous_enable=NO\n重启FTP服务", ftpConfig))
						}
					}
				}
			}

			if anonymousEnable {
				result7_2 = "合规"
			} else {
				result7_2 = "不合规"
			}
		}
		if result7_2 == "合规" {
			countSuccess++
			recommendation7_2 = append(recommendation7_2, "/")
			fmt.Println("7.2:检查是否禁止匿名用户登录FTP\t合规")
		} else {
			countFail++
			fmt.Println("7.2:检查是否禁止匿名用户登录FTP\t不合规")
		}
		data7_2 := []string{
			"7.2",
			"检查是否禁止匿名用户登录",
			"高危",
			"禁止匿名用户登录FTP服务器。",
			"/",
			"未启用FTP服务或禁止匿名用户登录FTP服务",
			fmt.Sprintf("ps -ef | grep ftpd | grep -v grep\n cat {%s} | grep anonymous_enable", ftpConfig),
			strings.Join(recommendation7_2, "\n"),
			strings.Join(result7_2Data, "\n"),
			result7_2,
			"/",
			"/",
		}
		xlsxData = append(xlsxData, data7_2)
	}

	//fileList := []string{".rhost", ".netrc", "hosts.equiv"}
	countAll++
	result7_3Data := []string{}
	recommendation7_3 := []string{}
	existFileList := []string{}
	var result7_3 string
	fileResults, err := runCommand("find / -name .rhost && find / -name .netrc && find / -name hosts.equiv")
	if err == nil && fileResults != "/" {
		for _, line := range strings.Split(fileResults, "\n") {
			if line != "/" && line != "" && !strings.Contains(line, "No such file or directory") {
				existFileList = append(existFileList, strings.TrimSpace(line))
			}
		}
	}

	if len(existFileList) == 0 {
		result7_3 = "合规"
		countSuccess++
		existFileList = append(existFileList, "/")
		recommendation7_3 = append(recommendation7_3, "/")
		fmt.Println("7.3:检查是否删除了潜在危险文件\t合规")
	} else {
		result7_3 = "不合规"
		countFail++
		fmt.Println("7.3:检查是否删除了潜在危险文件\t不合规")
		result7_3Data = existFileList
		recommendation7_3 = []string{"使用rm命令删除以下文件:\n" + strings.Join(existFileList, "\n")}
	}

	data7_3 := []string{
		"7.3",
		"检查是否删除了潜在危险文件",
		"高危",
		".rhosts,.netrc,hosts.equiv等文件都具有潜在的危险,如果没有应用,应该删除",
		"使用find 或 locate命令查看系统是否存在如下文件:\".rhost .netrc hosts.equiv\"",
		"不存在如下文件:\".rhost .netrc hosts.equiv\"",
		"find / -name .rhost&&find / -name .netrc&&find / -name hosts.equiv\nupdatedb\nlocate hosts.equiv|grep -i \"hosts.equiv$\"\nlocate .netrc|grep -i \".netrc$\"\nlocate .rhost|grep -i \".rhost$\"/",
		strings.Join(recommendation7_3, "\n"),
		strings.Join(result7_3Data, "\n"),
		result7_3,
		"/",
		"/",
	}
	xlsxData = append(xlsxData, data7_3)

	countAll++
	data7_4Date := []string{}
	profilePath := "/etc/profile"
	recommendation7_4 := []string{}
	profile, err := os.Open(profilePath)
	if err == nil {
		defer func() {
			if err = profile.Close(); err != nil {
				fmt.Println(err)
			}
		}()
		scanner := bufio.NewScanner(profile)
		for scanner.Scan() {
			line := scanner.Text()
			line = strings.TrimSpace(line)
			if !strings.HasPrefix(line, "#") && strings.Contains(line, "TMOUT") {
				data7_4Date = append(data7_4Date, line)
			}
		}
	}

	flag7_4_1 := false
	flag7_4_2 := false
	var result7_4 string
	if len(data7_4Date) > 0 {
		for _, line := range data7_4Date {
			if strings.Contains(line, "=") {
				value, err1 := strconv.Atoi(strings.Split(line, "=")[1])
				if err1 == nil && value <= 300 {
					flag7_4_1 = true
				}
			}
			if strings.Contains(line, "export") {
				flag7_4_2 = true
			}
		}
		data7_4Date = []string{strings.Join(data7_4Date, "\n")}

		if flag7_4_1 && flag7_4_2 {
			result7_4 = "合规"
			recommendation7_4 = []string{"/"}
		} else if flag7_4_1 && !flag7_4_2 {
			result7_4 = "不合规"
			recommendation7_4 = []string{"export TMOUT"}
		} else if !flag7_4_1 && flag7_4_2 {
			result7_4 = "不合规"
			recommendation7_4 = []string{"TMOUT=300"}
		} else {
			result7_4 = "不合规"
			recommendation7_4 = []string{"TMOUT=300", "export TMOUT"}
		}
	} else {
		line := "未配置"
		data7_4Date = []string{}
		data7_4Date = append(data7_4Date, line)
		result7_4 = "不合规"
		recommendation7_4 = []string{"TMOUT=300", "export TMOUT"}
	}

	if len(recommendation7_4) > 0 {
		recommendation7_4 = []string{strings.Join(recommendation7_4, "\n")}
		recommendation7_4 = []string{"执行备份\ncp -p /etc/profile /etc/profile_bak\n在/etc/profile文件中增加如下行(存在则修改,不存在则添加):\n" + strings.Join(recommendation7_4, "\n\n") + "\n执行以下命令使TMOUT参数立即生效\nsource /etc/profile"}
	}

	if result7_4 == "合规" {
		countSuccess++
		fmt.Println("7.4:检查是否设置命令行界面超时退出\t合规")
	} else {
		countFail++
		fmt.Println("7.4:检查是否设置命令行界面超时退出\t不合规")
	}

	data7_4 := []string{
		"7.4", "检查是否设置命令行界面超时退出", "高危", "对于具备字符交互界面的设备,应配置定时帐户自动登出,避免管理员忘记注销登录,减少安全隐患。", "查看/etc/profile文件中是否配置超时设置", "设置命令行界面登录后300s内无任何操作自动登出\nTMOUT=300\nexport TMOUT",
		"cat /etc/profile |grep -i TMOUT", strings.Join(recommendation7_4, "\n"), strings.Join(data7_4Date, "\n"), result7_4, "/", "/",
	}
	xlsxData = append(xlsxData, data7_4)

	countAll++
	var result7_5 string
	var profilePath7_5 []string
	result7_5Data := []string{}
	recommendation7_5 := "/"
	if _, err = os.Stat("/root/.bash_profile"); err == nil {
		profilePath7_5 = append(profilePath7_5, "/root/.bash_profile")
	}
	if _, err = os.Stat("/etc/profile"); err == nil {
		profilePath7_5 = append(profilePath7_5, "/etc/profile")
	}
	paths, err := runCommand("echo $PATH")
	if err == nil {
		for _, path := range strings.Split(paths, ":") {
			if path == "." || path == "./" || path == ".." || path == "../" {
				result7_5Data = append(result7_5Data, path)
			}
		}
	}

	if len(result7_5Data) == 0 {
		result7_5Data = []string{"/"}
		result7_5 = "合规"
		countSuccess++
		fmt.Println("7.5:检查root用户的path环境变量\t合规")
	} else {
		result7_5Data = []string{strings.Join(result7_5Data, "\n")}
		result7_5 = "不合规"
		countFail++
		fmt.Println("7.5:检查root用户的path环境变量\t不合规")
		if len(profilePath7_5) > 0 {
			recommendation7_5 = "修改文件 " + strings.Join(profilePath7_5, " 或 ") + " 中的环境变量$PATH,删除环境变量值包含的(.和..)的路径"
		} else {
			recommendation7_5 = "配置文件未找到,请人工检查环境变量$PATH,删除环境变量值包含的(.和..)的路径"
		}
	}

	data7_5 := []string{
		"7.5", "检查root用户的path环境变量", "中危", "root用户环境变量的安全性", "使用命令echo $PATH查看PATH环境变量的值,确认PATH环境变量中是否存在.或者..的路径", "$PATH环境变量中不存在.或者..的路径则合规,否则不合规", "echo $PATH",
		recommendation7_5, strings.Join(result7_5Data, "\n"), result7_5, "/", "/",
	}
	xlsxData = append(xlsxData, data7_5)

	countAll++
	result7_6Data := []string{}
	profilePathList := []string{"/etc/profile", "~/.bashrc", "~/.bash_history", "/etc/bashrc", "/etc/profile.d/", "~/.inputrc", "~/.bash_login", "/etc/bash.bashrc", "~/.profile"}
	result7_6 := "不合规"
	recommendation7_6 := []string{}
	HISTFILESIZE_flag := false
	HISTSIZE_flag := false
	HISTFILESIZE := new(int)
	HISTSIZE := new(int)
	*HISTFILESIZE = 0
	*HISTSIZE = 0
	filePath := ""

	boolValue := false
	for _, profilePath = range profilePathList {
		if !boolValue {
			if strings.HasPrefix(profilePath, "~") {
				boolValue, filePath = readUser(strings.Split(profilePath, "/")[1], result7_6Data, HISTFILESIZE, HISTSIZE)
			} else {
				profile, err = os.Open(profilePath)
				if err == nil {
					boolValue = checkHistoryFile(profile, result7_6Data, HISTFILESIZE, HISTSIZE)
					if boolValue {
						filePath = profilePath
					}
				}
			}
		}
	}
	// 虽然读取不出来,但是放着,万一有时候突然有效呢?
	if *HISTSIZE == 0 {
		hists := os.Getenv("HISTSIZE")
		num, _ := strconv.Atoi(strings.TrimSpace(hists))
		*HISTSIZE = num
	}
	if *HISTFILESIZE == 0 {
		histf := os.Getenv("HISTFILESIZE")
		num, _ := strconv.Atoi(strings.TrimSpace(histf))
		*HISTFILESIZE = num
	}

	if *HISTFILESIZE <= 5 {
		HISTFILESIZE_flag = true
	} else {
		recommendation7_6 = append(recommendation7_6, "HISTFILESIZE=5")
	}
	if *HISTSIZE <= 5 {
		HISTSIZE_flag = true
	} else {
		recommendation7_6 = append(recommendation7_6, "HISTSIZE=5")
	}

	if HISTFILESIZE_flag && HISTSIZE_flag {
		result7_6 = "合规"
		countSuccess++
		resultData := fmt.Sprintf("HISTFILESIZE 为:%s  \n HISTSIZE 为:%s \n 所在文件位置为:%s", strconv.Itoa(*HISTFILESIZE), strconv.Itoa(*HISTSIZE), filePath)
		result7_6Data = []string{resultData}
		fmt.Println("7.6:检查历史命令设置\t合规")
	} else {
		result7_6 = "不合规"
		countFail++
		fmt.Println("7.6:检查历史命令设置\t不合规")
		recommendation7_6 = []string{"编辑文件/etc/profile,在文件中加入如下两行(存在则修改):\n" + strings.Join(recommendation7_6, "\n")}
		resultData := fmt.Sprintf("HISTFILESIZE 为:%s  \n HISTSIZE 为:%s \n 所在文件位置为:%s", strconv.Itoa(*HISTFILESIZE), strconv.Itoa(*HISTSIZE), filePath)
		result7_6Data = []string{resultData}
		recommendation7_6 = []string{"编辑文件/etc/profile,在文件中加入如下两行(存在则修改):\n" + strings.Join(recommendation7_6, "\n")}
	}

	if len(result7_6Data) == 0 {
		result7_6Data = []string{strings.Join(result7_6Data, "\n")}
	} else {
		result7_6Data = []string{strings.Join(result7_6Data, "\n")}
	}

	data7_6 := []string{
		"7.6", "检查历史命令设置", "中危", "保证bash shell保存少量的(或不保存)命令,保存较少的命令条数,减少安全隐患。", "编辑文件/etc/profile查看是否存在如下内容:\nHISTFILESIZE=5\nHISTSIZE=5", "HISTFILESIZE和HISTSIZE的值小于等于5则合规,否则不合规。", "cat /etc/profile | grep -v '#' | awk '/HISTFILESIZE/ || /HISTSIZE/'",
		strings.Join(recommendation7_6, "\n"), strings.Join(result7_6Data, "\n"), result7_6, "/", "/",
	}
	xlsxData = append(xlsxData, data7_6)

	countAll++
	result7_7Data := "/"
	recommendation7_7 := "/"
	var result7_7 string
	ctrlAltDelPath := "/usr/lib/systemd/system/ctrl-alt-del.target"
	if _, err = os.Stat(ctrlAltDelPath); os.IsNotExist(err) {
		recommendation7_7 = "未定位到ctrl-alt-del.target,人工检查"
	} else {
		profile3, err := os.Open(ctrlAltDelPath)
		if err == nil {
			defer func() {
				if err = profile3.Close(); err != nil {
					fmt.Println(err)
				}
			}()
			scanner := bufio.NewScanner(profile3)
			for scanner.Scan() {
				line := scanner.Text()
				line = strings.TrimSpace(line)
				if !strings.HasPrefix(line, "#") && strings.Contains(line, "Alias") && strings.Contains(line, "ctrl-alt-del.target") {
					result7_7Data = line
					recommendation7_7 = "编辑文件/usr/lib/systemd/system/ctrl-alt-del.target,将如下行删除或注释:\nAlias=ctrl-alt-del.target"
				}
			}
		}
	}

	if result7_7Data == "/" {
		result7_7 = "合规"
		countSuccess++
		fmt.Println("7.7:检查系统是否禁用Ctrl+Alt+Delete组合键\t合规")
	} else {
		result7_7 = "不合规"
		countFail++
		fmt.Println("7.7:检查系统是否禁用Ctrl+Alt+Delete组合键\t不合规")
	}

	data7_7 := []string{
		"7.7", "检查系统是否禁用Ctrl+Alt+Delete组合键", "中危", "禁止Ctrl+Alt+Delete,防止非法重新启动服务器。", "查看文件/usr/lib/systemd/system/ctrl-alt-del.target,是否存在使用组合键Ctrl+Alt+Delete控制系统重启的配置。\nAlias=ctrl-alt-del.target", "禁用了使用组合键Ctrl+Alt+Delete重启系统则合规,否则不合规。", "cat /usr/lib/systemd/system/ctrl-alt-del.target | grep Alias | grep -v '#'", recommendation7_7, result7_7Data, result7_7, "/", "/",
	}
	xlsxData = append(xlsxData, data7_7)

	countAll++
	result7_8Data := []string{}
	ntpRunning := false
	var result7_8 string
	ntpCheckCommand := []string{}
	ntpServices := map[string]string{
		"systemd-timesyncd.service": "/etc/systemd/timesyncd.conf",
		"systemd-timesyncd":         "/etc/systemd/timesyncd.conf",
		"chronyd":                   "/etc/chrony.conf",
		"ntpd":                      "/etc/ntp.conf",
		"ntp":                       "/etc/ntp.conf",
	}
	for ntpService, configFile := range ntpServices {
		ntpCheckCommand = append(ntpCheckCommand, fmt.Sprintf("service status %s", ntpService)+"\n"+fmt.Sprintf("systemctl status %s", ntpService))
		if checkCommand(ntpService) || checkNtpTime(ntpService) {
			ntpRunning = true
			result7_8Data = append(result7_8Data, fmt.Sprintf("%s 已启动", ntpService))
			if configFile == "/etc/systemd/timesyncd.conf" {
				if _, err = os.Stat(configFile); err == nil {
					result7_8Data = append(result7_8Data, "时间同步服务器设置为:")
					ntpServer := "/"
					profile4, err := os.Open(configFile)
					if err == nil {
						defer func() {
							if err = profile4.Close(); err != nil {
								fmt.Println(err)
							}
						}()
						scanner := bufio.NewScanner(profile4)
						for scanner.Scan() {
							line := scanner.Text()
							line = strings.TrimSpace(line)
							if !strings.HasPrefix(line, "#") && strings.Contains(line, "NTP") {
								ntpServer = strings.Split(line, "=")[1]
								result7_8Data = append(result7_8Data, ntpServer)
							}
						}
					}
					if ntpServer == "/" {
						result7_8Data = append(result7_8Data, "未找到时间同步服务器")
					}
				} else {
					result7_8Data = append(result7_8Data, fmt.Sprintf("配置文件 %s 未找到", configFile))
				}
			} else {
				if _, err = os.Stat(configFile); err == nil {
					result7_8Data = append(result7_8Data, "时间同步服务器设置为:")
					ntpServer := "/"
					profile5, err := os.Open(configFile)
					if err == nil {
						defer func() {
							if err = profile5.Close(); err != nil {
								fmt.Println(err)
							}
						}()
						scanner := bufio.NewScanner(profile5)
						for scanner.Scan() {
							line := scanner.Text()
							line = strings.TrimSpace(line)
							if !strings.HasPrefix(line, "#") && strings.Contains(line, "NTP") {
								ntpServer = strings.Split(strings.TrimSpace(line), "=")[1]
								result7_8Data = append(result7_8Data, ntpServer)
							}
						}
					}
					if ntpServer == "/" {
						result7_8Data = append(result7_8Data, "未找到时间同步服务器")
					}
				} else {
					result7_8Data = append(result7_8Data, fmt.Sprintf("配置文件 %s 未找到", configFile))
				}
			}
		}
	}

	if ntpRunning {
		result7_8 = "人工判断"
		count_manual++
		fmt.Println("7.8:检查是否使用NTP保持时间同步\t合规")
	} else {
		result7_8 = "不合规"
		countFail++
		fmt.Println("7.8:检查是否使用NTP保持时间同步\t不合规")
	}

	ntpCheckCommand = []string{strings.Join(ntpCheckCommand, "\n")}
	if len(result7_8Data) > 0 {
		result7_8Data = []string{strings.Join(result7_8Data, "\n")}
	} else {
		result7_8Data = []string{}
	}

	data7_8 := []string{
		"7.8", "检查是否使用NTP保持时间同步", "低危", "建议将缺乏直接访问物理主机时钟的物理系统和虚拟客户机配置为NTP客户机来同步它们的时钟(特别是支持像Kerberos这样的时间敏感安全机制)。这也确保日志文件在整个企业中都有一致的时间记录,这有助于问题排查。",
		fmt.Sprintf("检查%s服务是否启动", getKey(ntpServices, " 或 ")), "NTP服务处于开启状态", strings.Join(ntpCheckCommand, "\n"), "开启NTP服务,并查看是否配置NTP服务器", strings.Join(result7_8Data, "\n"), result7_8, "/", "/",
	}
	xlsxData = append(xlsxData, data7_8)

	var result7_9 string
	var result7_9_data string
	hostsAllowPath := "/etc/hosts.allow"
	hostsDenyPath := "/etc/hosts.deny"
	hostsAllow := []string{}
	hostsDeny := []string{}
	countAll++
	if _, err = os.Stat(hostsAllowPath); err == nil {
		file, err1 := os.Open(hostsAllowPath)
		if err1 != nil {
			fmt.Println(err1)
			return
		}
		defer func() {
			if err = file.Close(); err != nil {
				fmt.Println(err)
			}
		}()

		scanner := bufio.NewScanner(file)
		for scanner.Scan() {
			line := strings.TrimSpace(scanner.Text())
			if line != "/" && !strings.HasPrefix(line, "#") {
				hostsAllow = append(hostsAllow, line)
			}
		}

	}
	if len(hostsAllow) == 0 {
		hostsAllow = []string{"/"}
	}
	if _, err = os.Stat(hostsDenyPath); err == nil {
		file, err1 := os.Open(hostsDenyPath)
		if err1 != nil {
			fmt.Println(err1)
			return
		}
		defer func() {
			if err = file.Close(); err != nil {
				fmt.Println(err)
			}
		}()

		scanner := bufio.NewScanner(file)
		for scanner.Scan() {
			line := strings.TrimSpace(scanner.Text())
			if line != "/" && !strings.HasPrefix(line, "#") {
				hostsDeny = append(hostsDeny, line)
			}
		}

	}
	if len(hostsDeny) == 0 {
		hostsDeny = []string{"/"}
	}
	if len(hostsAllow) == 0 && len(hostsDeny) == 0 {
		result7_9 = "不合规"
		result7_9_data = "未限制访问IP"
		countFail++
	} else if len(hostsAllow) > 0 && len(hostsDeny) == 0 {
		result7_9 = "人工判断"
		result7_9_data = "允许:" + strings.Join(hostsAllow, "\n")
		count_manual++
	} else if len(hostsDeny) > 0 && len(hostsAllow) == 0 {
		result7_9 = "人工判断"
		result7_9_data = "不允许:" + strings.Join(hostsDeny, "\n")
		count_manual++
	} else {
		result7_9 = "人工判断"
		result7_9_data = "允许:" + strings.Join(hostsAllow, "\n") + "\n不允许:" + strings.Join(hostsDeny, "\n")
		count_manual++
	}

	data7_9 := []string{
		"7.9", "检查是否限制访问IP", "低危", "应限制访问主机的IP", "检查允许的IP\n/etc/hosts.allow\n检查不允许的IP\n/etc/hosts.deny", "根据企业要求", "cat /etc/hosts.allow | grep -v '#' | grep allow\ncat /etc/hosts.deny | grep -v '#'", "根据企业要求修改文件", result7_9_data, result7_9, "/", "/",
	}
	xlsxData = append(xlsxData, data7_9)

	fmt.Printf("7.9:检查是否限制访问IP\t%s\n", result7_9)
}

// ############################################### 入口 ###################################################################
func main() {
	// 记录开始时间
	startTime := time.Now()

	// 初始化
	ipAddress, hostInfo := start_scan()

	// 检查项:1
	account_admin()

	// 检查项:2
	checkpPassword()

	// 检查项:3
	userAuth()

	// 检查项:4
	SshLog()

	// 检查项:5
	Ftp_Telnet_Snmp()

	// 检查项:6
	Openssh_Root()

	// 检查项:7
	His_Ntp_Cad()

	// 最后保存Excel
	saveErr, err := saveExcel(ipAddress+".xlsx", xlsxData, hostInfo)
	errPrint("保存xlsx文件错误", err)

	// 输出检查结果
	complianceRate := float64(countSuccess) / float64(countAll) * 100
	fmt.Printf("成功检查项共计 %d 项,合规 %d 项,不合规 %d 项,人工判断 %d 项,合规率 %d% \n", countAll, countSuccess, countFail, count_manual, int(complianceRate))

	// 保存状态判断
	save_status(saveErr)
	endTime := time.Now()
	elapsedTime := endTime.Sub(startTime)
	fmt.Printf("程序执行时间: %v\n", elapsedTime)

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安全小白音

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值