Files
2025-12-30 15:31:20 +08:00

383 lines
20 KiB
YAML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
metadata:
version: "2.0"
description: "SSH安全配置检查项"
checks:
# 2.2 禁止root用户直接SSH远程登录系统
# 要求:限制root用户直接通过SSH远程登录系统,执行管理员权限操作时,需先以普通权限用户登录,再通过su或sudo命令切换到root帐号后执行
- id: "ssh_permit_root_login"
category: "SSH安全配置"
title: "禁止root远程登录"
description: "限制root用户直接通过SSH远程登录系统,执行管理员权限操作时,需先以普通权限用户登录,再通过su或sudo命令切换到root帐号后执行。该配置可降低root帐号密码泄露带来的风险。"
tags: ["low", "medium", "high", "ssh", "authentication"]
check_script: |
# 按照标准检测方法:grep -E "^PermitRootLogin" /etc/ssh/sshd_config
# 使用 || true 避免grep未找到匹配时导致脚本退出(set -e模式下)
permit_root_result=$(grep -E "^PermitRootLogin" /etc/ssh/sshd_config 2>/dev/null || true)
if [ -z "$permit_root_result" ]; then
# 无相关配置项,不符合要求
echo "FAIL: 未配置PermitRootLogin参数,使用默认值,不符合安全要求"
echo "当前配置: (无)"
echo "建议: 编辑/etc/ssh/sshd_config,添加或修改'PermitRootLogin no',然后重启ssh服务"
exit 1
elif echo "$permit_root_result" | grep -qE "^PermitRootLogin\\s+no"; then
# 输出结果为"PermitRootLogin no",符合要求
echo "PASS: root用户无法直接SSH登录"
echo "当前配置: $permit_root_result"
exit 0
else
# 输出结果为"PermitRootLogin yes"或其他值,不符合要求
echo "FAIL: 允许root用户直接SSH登录,违反安全策略"
echo "当前配置: $permit_root_result"
echo "建议: 编辑/etc/ssh/sshd_config,将'PermitRootLogin'设置为'no',然后重启ssh服务"
exit 1
fi
fix_script: |
# 删除所有PermitRootLogin配置行(包括注释)
sed -i '/^[[:space:]]*#.*PermitRootLogin/d' /etc/ssh/sshd_config
sed -i '/^PermitRootLogin/d' /etc/ssh/sshd_config
# 添加新配置
echo "PermitRootLogin no" >> /etc/ssh/sshd_config
# 重启SSH服务
systemctl restart sshd
# 验证配置
verify_result=$(grep -E "^PermitRootLogin" /etc/ssh/sshd_config)
if echo "$verify_result" | grep -qE "^PermitRootLogin\\s+no"; then
echo "已禁止root用户直接SSH登录"
echo "验证配置: $verify_result"
else
echo "警告: 配置可能未正确生效,请手动检查"
exit 1
fi
# 2.3 禁用密码直接登录SSH远程系统
# 要求:禁止通过密码验证的方式登录SSH远程系统,仅允许使用SSH密钥对进行身份验证。密钥认证相比密码认证安全性更高,可有效抵御暴力破解攻击。
- id: "ssh_password_auth"
category: "SSH安全配置"
title: "禁用SSH密码认证"
description: "禁止通过密码验证的方式登录SSH远程系统,仅允许使用SSH密钥对进行身份验证。密钥认证相比密码认证安全性更高,可有效抵御暴力破解攻击。"
tags: ["medium", "high", "ssh", "authentication"]
check_script: |
# 按照标准检测方法:grep -E "^PasswordAuthentication" /etc/ssh/sshd_config
# 使用 || true 避免grep未找到匹配时导致脚本退出(set -e模式下)
password_auth_result=$(grep -E "^PasswordAuthentication" /etc/ssh/sshd_config 2>/dev/null || true)
if [ -z "$password_auth_result" ]; then
# 无相关配置项,不符合要求
echo "FAIL: 未配置PasswordAuthentication参数,使用默认值,不符合安全要求"
echo "当前配置: (无)"
echo "建议: 编辑/etc/ssh/sshd_config,添加或修改'PasswordAuthentication no',然后重启ssh服务"
echo "注意: 请先配置SSH密钥登录,确保客户端已生成密钥对,并将公钥上传至服务器目标用户的~/.ssh/authorized_keys文件中,避免被锁定在系统外"
exit 1
elif echo "$password_auth_result" | grep -qE "^PasswordAuthentication\\s+no"; then
# 输出结果为"PasswordAuthentication no",符合要求
echo "PASS: SSH密码认证已禁用"
echo "当前配置: $password_auth_result"
exit 0
else
# 输出结果为"PasswordAuthentication yes"或其他值,不符合要求
echo "FAIL: SSH密码认证未禁用,存在暴力破解风险"
echo "当前配置: $password_auth_result"
echo "建议: 编辑/etc/ssh/sshd_config,将'PasswordAuthentication'设置为'no',然后重启ssh服务"
echo "注意: 请先配置SSH密钥登录,确保客户端已生成密钥对,并将公钥上传至服务器目标用户的~/.ssh/authorized_keys文件中,且文件权限设置为600,避免被锁定在系统外"
exit 1
fi
fix_script: |
# 删除所有PasswordAuthentication配置行(包括注释)
sed -i '/^[[:space:]]*#.*PasswordAuthentication/d' /etc/ssh/sshd_config
sed -i '/^PasswordAuthentication/d' /etc/ssh/sshd_config
# 添加新配置
echo "PasswordAuthentication no" >> /etc/ssh/sshd_config
# 重启SSH服务
systemctl restart sshd
# 验证配置
verify_result=$(grep -E "^PasswordAuthentication" /etc/ssh/sshd_config)
if echo "$verify_result" | grep -qE "^PasswordAuthentication\\s+no"; then
echo "已禁用SSH密码认证"
echo "验证配置: $verify_result"
echo "提示: 请确保已配置SSH密钥登录,并测试密钥登录正常后再关闭当前会话"
else
echo "警告: 配置可能未正确生效,请手动检查"
exit 1
fi
# 2.4 检查SSH使用的协议版本
# 要求:SSH协议版本1存在安全漏洞(如中间人攻击风险、加密强度不足等),需禁用SSH协议版本1,仅使用安全性更高的协议版本2
- id: "ssh_protocol_version"
category: "SSH安全配置"
title: "检查SSH协议版本"
description: "SSH协议版本1存在安全漏洞(如中间人攻击风险、加密强度不足等),需禁用SSH协议版本1,仅使用安全性更高的协议版本2。"
tags: ["low", "medium", "high", "ssh", "protocol"]
check_script: |
# 按照标准检测方法:grep -iE "^\s*Protocol\s+" /etc/ssh/sshd_config | tail -1
protocol_result=$(grep -iE "^\s*Protocol\s+" /etc/ssh/sshd_config 2>/dev/null | tail -1)
# 验证服务当前使用的协议版本(OpenSSH版本不小于2.9)
ssh_version=$(ssh -V 2>&1 | grep -oE "OpenSSH_[0-9]+\.[0-9]+" | cut -d'_' -f2)
ssh_major=$(echo "$ssh_version" | cut -d'.' -f1)
ssh_minor=$(echo "$ssh_version" | cut -d'.' -f2)
# 检查OpenSSH版本是否满足要求(>= 2.9
version_check_passed=false
if [ -n "$ssh_major" ] && [ -n "$ssh_minor" ]; then
if [ "$ssh_major" -gt 2 ] || ([ "$ssh_major" -eq 2 ] && [ "$ssh_minor" -ge 9 ]); then
version_check_passed=true
fi
fi
# 判断协议配置
if [ -z "$protocol_result" ]; then
# 无相关配置项,使用默认值(SSH服务默认使用版本2),符合要求
if [ "$version_check_passed" = true ]; then
echo "PASS: 未配置Protocol参数,使用默认值(协议版本2),符合要求"
echo "当前配置: (无,使用默认值)"
echo "OpenSSH版本: $ssh_version (>= 2.9,符合要求)"
exit 0
else
echo "WARN: 未配置Protocol参数,使用默认值(协议版本2),但OpenSSH版本可能不符合要求"
echo "当前配置: (无,使用默认值)"
echo "OpenSSH版本: $ssh_version (要求 >= 2.9)"
exit 0
fi
elif echo "$protocol_result" | grep -qiE "Protocol\s+2"; then
# 输出结果为"Protocol 2",符合要求
if [ "$version_check_passed" = true ]; then
echo "PASS: SSH协议版本配置为2,符合要求"
echo "当前配置: $protocol_result"
echo "OpenSSH版本: $ssh_version (>= 2.9,符合要求)"
exit 0
else
echo "WARN: SSH协议版本配置为2,但OpenSSH版本可能不符合要求"
echo "当前配置: $protocol_result"
echo "OpenSSH版本: $ssh_version (要求 >= 2.9)"
exit 0
fi
elif echo "$protocol_result" | grep -qiE "Protocol\s+1"; then
# 输出结果为"Protocol 1"或"Protocol 1,2",不符合要求
echo "FAIL: SSH协议版本配置包含版本1,存在安全漏洞风险"
echo "当前配置: $protocol_result"
echo "OpenSSH版本: $ssh_version"
echo "建议: 编辑/etc/ssh/sshd_config,将'Protocol'设置为'2',然后重启ssh服务"
echo "或者: 直接删除Protocol配置项,使用默认值(协议版本2)"
exit 1
else
# 其他情况(如Protocol 2,1等)
echo "FAIL: SSH协议版本配置异常"
echo "当前配置: $protocol_result"
echo "OpenSSH版本: $ssh_version"
echo "建议: 编辑/etc/ssh/sshd_config,将'Protocol'设置为'2',然后重启ssh服务"
exit 1
fi
fix_script: |
# 删除所有Protocol配置行(包括注释)
sed -i '/^[[:space:]]*#.*Protocol/d' /etc/ssh/sshd_config
sed -i '/^[[:space:]]*Protocol/d' /etc/ssh/sshd_config
# 添加新配置
echo "Protocol 2" >> /etc/ssh/sshd_config
# 重启SSH服务
systemctl restart sshd
# 验证配置
verify_result=$(grep -iE "^\s*Protocol\s+" /etc/ssh/sshd_config | tail -1)
ssh_version=$(ssh -V 2>&1 | grep -oE "OpenSSH_[0-9]+\.[0-9]+" | cut -d'_' -f2)
if echo "$verify_result" | grep -qiE "Protocol\s+2"; then
echo "已设置SSH协议版本为2"
echo "验证配置: $verify_result"
echo "OpenSSH版本: $ssh_version"
else
echo "警告: 配置可能未正确生效,请手动检查"
exit 1
fi
# 2.5 禁止通过SSH服务连接X11图形界面转发检查
# 要求:X11图形界面转发功能可能带来安全风险(如资源占用、潜在的界面劫持等),对于无需远程图形界面的服务器,应禁止通过SSH服务进行X11转发
- id: "ssh_x11_forwarding"
category: "SSH安全配置"
title: "禁止SSH X11转发"
description: "X11图形界面转发功能可能带来安全风险(如资源占用、潜在的界面劫持等),对于无需远程图形界面的服务器,应禁止通过SSH服务进行X11转发。"
tags: ["low", "medium", "high", "ssh", "x11"]
check_script: |
# 按照标准检测方法:grep -E "^X11Forwarding" /etc/ssh/sshd_config
# 注意:只检查非注释的配置行(^X11Forwarding),不包括注释行(^#X11Forwarding
# 使用 || true 避免grep未找到匹配时导致脚本退出(set -e模式下)
x11_forwarding_result=$(grep -E "^X11Forwarding" /etc/ssh/sshd_config 2>/dev/null || true)
if [ -z "$x11_forwarding_result" ]; then
# 无相关配置项,使用默认值(SSH默认X11Forwarding为no,即关闭状态),符合要求
echo "PASS: 未配置X11Forwarding参数,使用默认值(关闭X11转发),符合要求"
echo "当前配置: (无,使用默认值 no)"
echo "说明: SSH服务默认X11Forwarding为no(关闭),无需额外配置"
exit 0
elif echo "$x11_forwarding_result" | grep -qE "^X11Forwarding\\s+no"; then
# 输出结果为"X11Forwarding no",符合要求
echo "PASS: SSH X11转发已禁用"
echo "当前配置: $x11_forwarding_result"
exit 0
else
# 输出结果为"X11Forwarding yes"或其他值,不符合要求
echo "FAIL: SSH X11转发未禁用,存在安全风险"
echo "当前配置: $x11_forwarding_result"
echo "建议: 编辑/etc/ssh/sshd_config,将'X11Forwarding'设置为'no',然后重启ssh服务"
exit 1
fi
fix_script: |
# 备份SSH配置文件(按照标准修复建议)
backup_file="/etc/ssh/sshd_config.backup.$(date +%Y%m%d)"
cp /etc/ssh/sshd_config "$backup_file"
echo "已备份配置文件至: $backup_file"
# 删除所有X11Forwarding配置行(包括注释)
sed -i '/^[[:space:]]*#.*X11Forwarding/d' /etc/ssh/sshd_config
sed -i '/^X11Forwarding/d' /etc/ssh/sshd_config
# 添加新配置
echo "X11Forwarding no" >> /etc/ssh/sshd_config
# 重启SSH服务
systemctl restart sshd
# 验证配置
verify_result=$(grep -E "^X11Forwarding" /etc/ssh/sshd_config)
if echo "$verify_result" | grep -qE "^X11Forwarding\\s+no"; then
echo "已禁用SSH X11转发"
echo "验证配置: $verify_result"
else
echo "警告: 配置可能未正确生效,请手动检查"
exit 1
fi
# 2.12 SSH其他安全配置
# 要求:为进一步缩小SSH服务攻击面,强化远程登录安全,需补充以下SSH安全配置策略:
# 1. 限制SSH最大认证尝试次数:设置为3次
# 2. 设置SSH空闲会话超时:空闲检测间隔300秒,检测到空闲立即断开(ClientAliveCountMax=0
# 3. 禁用空密码登录:PermitEmptyPasswords=no
# 4. 限制用户/组访问:通过AllowUsers或AllowGroups指定仅允许登录的用户或用户组(可选,但建议配置)
- id: "ssh_other_security"
category: "SSH安全配置"
title: "检查SSH其他安全配置"
description: "为进一步缩小SSH服务攻击面,强化远程登录安全,需配置:最大认证尝试次数3次、空闲会话超时300秒、禁用空密码登录、限制用户/组访问(可选)。"
tags: ["medium", "high", "ssh", "security"]
check_script: |
# 检查基础安全参数
# 按照标准检测方法:grep -E "^MaxAuthTries|^ClientAliveInterval|^ClientAliveCountMax|^PermitEmptyPasswords" /etc/ssh/sshd_config
# 使用 || true 避免grep未找到匹配时导致脚本退出(set -e模式下)
basic_config=$(grep -E "^MaxAuthTries|^ClientAliveInterval|^ClientAliveCountMax|^PermitEmptyPasswords" /etc/ssh/sshd_config 2>/dev/null || true)
# 检查访问控制参数(可选)
access_control_config=$(grep -E "^AllowUsers|^AllowGroups" /etc/ssh/sshd_config 2>/dev/null || true)
# 提取各个参数的值
max_auth_tries_value=$(echo "$basic_config" | grep "^MaxAuthTries" | awk '{print $2}' | tr -d ' ' || echo "")
client_alive_interval_value=$(echo "$basic_config" | grep "^ClientAliveInterval" | awk '{print $2}' | tr -d ' ' || echo "")
client_alive_count_max_value=$(echo "$basic_config" | grep "^ClientAliveCountMax" | awk '{print $2}' | tr -d ' ' || echo "")
permit_empty_passwords_value=$(echo "$basic_config" | grep "^PermitEmptyPasswords" | awk '{print $2}' | tr -d ' ' || echo "")
# 判断结果
issues_found=""
all_passed=true
# 检查MaxAuthTries
if [ -z "$max_auth_tries_value" ]; then
issues_found="${issues_found}MaxAuthTries: 未配置(要求: 3\n"
all_passed=false
elif [ "$max_auth_tries_value" != "3" ]; then
issues_found="${issues_found}MaxAuthTries: ${max_auth_tries_value}(要求: 3\n"
all_passed=false
else
issues_found="${issues_found}MaxAuthTries: ${max_auth_tries_value}(符合要求)\n"
fi
# 检查ClientAliveInterval
if [ -z "$client_alive_interval_value" ]; then
issues_found="${issues_found}ClientAliveInterval: 未配置(要求: 300秒)\n"
all_passed=false
elif [ "$client_alive_interval_value" != "300" ]; then
issues_found="${issues_found}ClientAliveInterval: ${client_alive_interval_value}秒(要求: 300秒)\n"
all_passed=false
else
issues_found="${issues_found}ClientAliveInterval: ${client_alive_interval_value}秒(符合要求)\n"
fi
# 检查ClientAliveCountMax
if [ -z "$client_alive_count_max_value" ]; then
issues_found="${issues_found}ClientAliveCountMax: 未配置(要求: 0\n"
all_passed=false
elif [ "$client_alive_count_max_value" != "0" ]; then
issues_found="${issues_found}ClientAliveCountMax: ${client_alive_count_max_value}(要求: 0\n"
all_passed=false
else
issues_found="${issues_found}ClientAliveCountMax: ${client_alive_count_max_value}(符合要求)\n"
fi
# 检查PermitEmptyPasswords
if [ -z "$permit_empty_passwords_value" ]; then
issues_found="${issues_found}PermitEmptyPasswords: 未配置(要求: no\n"
all_passed=false
elif [ "$permit_empty_passwords_value" != "no" ]; then
issues_found="${issues_found}PermitEmptyPasswords: ${permit_empty_passwords_value}(要求: no\n"
all_passed=false
else
issues_found="${issues_found}PermitEmptyPasswords: ${permit_empty_passwords_value}(符合要求)\n"
fi
# 检查访问控制(可选,但建议配置)
access_control_status=""
if [ -z "$access_control_config" ]; then
access_control_status="访问控制: 未配置AllowUsers或AllowGroups(建议配置以限制登录用户/组)\n"
else
access_control_status="访问控制: 已配置\n${access_control_config}\n"
fi
# 输出结果
if [ "$all_passed" = true ]; then
echo "PASS: SSH其他安全配置符合要求"
echo ""
echo "基础安全参数:"
echo -e "$issues_found"
echo "访问控制配置:"
echo -e "$access_control_status"
exit 0
else
echo "FAIL: SSH其他安全配置不符合要求"
echo ""
echo "基础安全参数:"
echo -e "$issues_found"
echo "访问控制配置:"
echo -e "$access_control_status"
echo ""
echo "建议: 编辑/etc/ssh/sshd_config文件,添加或修改以下配置项:"
echo " MaxAuthTries 3 # 限制最大认证尝试次数为3次"
echo " ClientAliveInterval 300 # 空闲会话5分钟(300秒)无操作则断开"
echo " ClientAliveCountMax 0 # 检测到空闲立即断开"
echo " PermitEmptyPasswords no # 禁用空密码用户登录"
echo ""
echo "访问控制(可选,但建议配置):"
echo " AllowUsers admin testuser # 允许指定用户登录"
echo " 或"
echo " AllowGroups sysadmin # 允许指定组登录"
echo ""
echo "注意: 修改配置前请确保已通过密钥认证测试登录正常,或已保留本地控制台访问方式"
exit 1
fi
fix_script: |
# 备份SSH配置文件(按照标准修复建议)
backup_file="/etc/ssh/sshd_config.backup.$(date +%Y%m%d)"
cp /etc/ssh/sshd_config "$backup_file"
echo "已备份配置文件至: $backup_file"
echo ""
echo "警告: 修改配置前,请确保已通过密钥认证测试登录正常,或已保留本地控制台访问方式,防止远程连接中断"
echo ""
echo "此问题需要人工干预,请根据检查结果执行以下操作:"
echo "1. 编辑SSH服务配置文件: vi /etc/ssh/sshd_config"
echo "2. 添加或修改基础安全配置项:"
echo " MaxAuthTries 3"
echo " ClientAliveInterval 300"
echo " ClientAliveCountMax 0"
echo " PermitEmptyPasswords no"
echo "3. (可选)配置访问控制:"
echo " AllowUsers admin testuser # 允许指定用户登录"
echo " 或"
echo " AllowGroups sysadmin # 允许指定组登录"
echo "4. 保存配置文件并重启SSH服务: systemctl restart sshd"
echo "5. 验证服务状态: systemctl status sshd"
echo "6. 验证配置效果: 使用未授权用户尝试登录,应提示'Permission denied'"
exit 1