怎么用脚本获取安全账户管理

wen 实用脚本 1

自动化运维与权限审计实战指南

目录导读

  1. 安全账户管理的核心痛点
  2. 脚本获取账户信息的原理与工具选择
  3. 实战:PowerShell脚本批量提取AD账户与权限
  4. 实战:Bash脚本抓取Linux本地账户与sudo权限
  5. 脚本输出数据的安全处理与审计报告生成
  6. 常见问题问答(Q&A)
  7. 总结与最佳实践建议

安全账户管理的核心痛点

在企业的IT运维中,安全账户管理指的是对用户账户、服务账户、特权账户的生命周期进行控制,包括创建、授权、禁用、删除以及权限审计,传统方式依赖管理员手动登录每台服务器或域控制器,效率低且容易遗漏。

怎么用脚本获取安全账户管理

三大痛点:

  • 账户数量爆炸:一台Windows域控可能管理数千个账户,手动检查不现实。
  • 权限滥用风险:离职员工账户、僵尸服务账户、本地管理员组中的未知成员,都是安全盲区。
  • 合规要求:等保2.0、ISO 27001、SOX等标准要求定期审计账户权限,脚本化是必然选择。

核心问题:怎么用脚本获取账户列表、鉴别长期未登录账户、提取特权组成员?下文将拆解具体实现。


脚本获取账户信息的原理与工具选择

1 基本原理

  • Windows环境:通过Active Directory域服务(AD)或本地SAM数据库,脚本使用LDAP查询、PowerShell的ActiveDirectory模块、WMI或Net用户命令。
  • Linux环境:从/etc/passwd/etc/shadow/etc/group文件读取,或使用getent命令,审计/etc/sudoers获得特权级别。
  • 云环境(AWS IAM、Azure AD、华为云IAM):通过各平台API(如AWS CLI、Azure CLI)提取用户列表和权限绑定。

2 脚本工具选型

环境 推荐脚本语言 核心命令/模块
Windows AD PowerShell Get-ADUser,Get-ADGroupMember
Windows本地 PowerShell/WMI Get-LocalUser,Get-LocalGroupMember
Linux Bash/Ansible getent passwd,grep /etc/sudoers
混合环境 Python+Paramiko paramiko.SSHClient,subprocess

选择依据:纯Windows环境首推PowerShell,Linux运维用Bash或Python,混合环境用Ansible playbook或Python脚本统一调度。


实战:PowerShell脚本批量提取AD账户与权限

1 脚本功能设计

我们需要:提取所有域用户(包括禁用账户)→ 提取其所属组 → 标记最近登录时间 >90天的待清理账户 → 输出CSV报表。

2 核心代码(可直接拷贝执行)

# 需要预先加载ActiveDirectory模块
Import-Module ActiveDirectory
# 获取所有域用户基本信息,筛选关键字段
$users = Get-ADUser -Filter * -Properties Name,SamAccountName,Enabled,LastLogonDate,PasswordLastSet,MemberOf,PasswordNeverExpires
# 循环处理:提取每人的组列表(分为特权组与普通组)
$report = @()
foreach ($user in $users) {
    $groups = $user.MemberOf
    $isPrivileged = $false
    $privilegeGroups = @()
    # 定义常见特权组关键字
    $adminGroups = "Domain Admins","Enterprise Admins","Schema Admins","Administrators"
    foreach ($groupDN in $groups) {
        $groupName = ($groupDN -split ",",2)[0] -replace "CN=",""
        if ($adminGroups -contains $groupName) {
            $isPrivileged = $true
            $privilegeGroups += $groupName
        }
    }
    # 标记长期未登录(超过90天)
    $daysSinceLastLogon = if ($user.LastLogonDate) { (Get-Date) - $user.LastLogonDate | Select -ExpandProperty Days } else { 9999 }
    $status = if ($daysSinceLastLogon -gt 90) { "Warning-LongUnused" } else { "Normal" }
    $report += [PSCustomObject]@{
        SamAccountName    = $user.SamAccountName
        Enabled           = $user.Enabled
        LastLogonDays     = $daysSinceLastLogon
        IsPrivileged      = $isPrivileged
        PrivilegeGroup    = ($privilegeGroups -join "; ")
        PassNeverExpires  = $user.PasswordNeverExpires
        Status            = $status
    }
}
# 导出到CSV
$report | Export-Csv -Path "C:\Audit\AD_Account_Audit_$(Get-Date -Format yyyyMMdd).csv" -NoTypeInformation
Write-Host "报告已生成:C:\Audit\AD_Account_Audit_$(Get-Date -Format yyyyMMdd).csv" -ForegroundColor Green

3 输出示例

SamAccountName Enabled LastLogonDays IsPrivileged PrivilegeGroup Status
zhangsan True 2 False Normal
li_admin True 1 True Domain Admins Normal
old_account False 125 False Warning-LongUnused

关键输出:管理员可直接从报告中找出“Enabled=False”的僵尸账户,以及“IsPrivileged=True”的高危权限账户。


实战:Bash脚本抓取Linux本地账户与sudo权限

1 脚本设计思路

Linux下的安全审计难点在sudo权限的隐秘性,很多普通用户拥有/etc/sudoers中隐藏的提权规则(如%wheel ALL=(ALL) NOPASSWD: ALL),脚本需要解析sudoers文件并关联用户。

2 核心代码

#!/bin/bash
# 文件名:linux_account_audit.sh
# 功能:提取所有本地用户、UID、主组、最后登录时间、是否可使用sudo并输出为CSV
echo "SamAccountName,UID,PrimaryGroup,LastLoginDays,SudoAccess,ShellPath" > /tmp/linux_accounts_$(date +%Y%m%d).csv
# 遍历所有用户(排除系统UID小于1000的和nobody)
for user in $(getent passwd | awk -F: '$3 >= 1000 && $3 < 65534 {print $1}'); do
    uid=$(id -u "$user")
    primary_group=$(id -gn "$user")
    shell=$(getent passwd "$user" | cut -d: -f7)
    # 获取最后登录时间(lastlog命令)
    last_login=$(lastlog -u "$user" 2>/dev/null | tail -1 | awk '{print $4, $5, $6}')
    if [[ -z "$last_login" || "$last_login" == "**Never logged in**" ]]; then
        days_since_login=9999
    else
        last_epoch=$(date -d "$last_login" +%s)
        current_epoch=$(date +%s)
        days_since_login=$(( (current_epoch - last_epoch) / 86400 ))
    fi
    # 检查是否拥有sudo权限
    sudo_access="False"
    # 检查用户是否直接出现在sudoers中
    if sudo -l -U "$user" 2>/dev/null | grep -q "may run the following commands"; then
        sudo_access="True"
    # 检查用户是否在sudoers的组中(如%wheel、%sudo)
    elif grep -E "^%[^ ]+.*ALL.*" /etc/sudoers | grep -q "$(id -ng "$user")"; then
        sudo_access="True"
    fi
    echo "$user,$uid,$primary_group,$days_since_login,$sudo_access,$shell" >> /tmp/linux_accounts_$(date +%Y%m%d).csv
done
echo "Linux账户审计报告已生成:/tmp/linux_accounts_$(date +%Y%m%d).csv"

3 脚本优化点

  • 使用lastlog替代wwholastlog能显示Never logged in(从未登录)的账户,这是清理孤儿账户的关键指标。
  • sudo权限检测sudo -l -U直接查询用户的实际sudo权限,比单纯解析/etc/sudoers更准确(因为/etc/sudoers.d/目录下还有碎片规则)。
  • 跳过系统用户:只审计UID>=1000的普通用户和UID>=65534的nobody用户,避免产生大量噪音。

脚本输出数据的安全处理与审计报告生成

1 数据安全防护

脚本获取的账户信息属于敏感数据,必须遵循最低权限原则:

  • 存储:导出的CSV文件设置600权限(Linux)或限制NTFS ACL(Windows)。
  • 传输:若需将报告发送给安全团队,使用加密通道(SFTP、加密邮件附件)。
  • 清理:脚本运行后立即删除临时中间文件,并在报告文件名中加入时间戳以便追溯。

2 自动报告生成(Python示例)

import pandas as pd
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
# 读取上月生成的CSV
df = pd.read_csv("/tmp/linux_accounts_20231001.csv")
# 提取高风险账户:sudo权限 + 超过90天未登录
high_risk = df[(df['SudoAccess'] == 'True') & (df['LastLoginDays'] > 90)]
# 生成HTML格式报告
html_report = high_risk.to_html()
message = MIMEMultipart()
message["Subject"] = "Linux账户安全审计报告 - 高风险账户需立即处理"
message.attach(MIMEText(html_report, "html"))
# 发送给安全管理员
with smtplib.SMTP("mail.company.com") as server:
    server.send_message(message)

合规价值:通过脚本自动化,从获取数据到发送报告全流程无需人工干预,满足等保2.0中的“定期自动审计”要求。


常见问题问答(Q&A)

Q1:脚本执行时需要管理员权限吗?

  • A:是的,PowerShell脚本获取AD信息需要域管理员或委派权限;Linux脚本读取/etc/shadowsudo -l需要root权限,建议使用具有最小必要权限的服务账户运行,并在脚本开头添加#Requires -RunAsAdministrator(Windows)或检测$EUID是否为0(Linux)。

Q2:如果域控制器有多个站点,脚本如何覆盖所有域用户?

  • AGet-ADUser -Filter *默认从当前登录的域控制器查询,会自动复制全域数据,若需要指定某站点,可加-Server "dc01.site1.company.com"参数。

Q3:Linux服务器数量众多,如何批量执行并汇总结果?

  • A:推荐使用Ansible的ad_hoc命令:
    ansible all -m script -a "/path/to/linux_account_audit.sh"

    或使用ansible.builtin.fetch模块将每台服务器的CSV拉到控制节点,再用Python合并。

Q4:脚本是否会泄露账户密码?

  • A:不会,脚本仅提取账户元数据(名称、组、登录时间等),不接触哈希或明文密码,Linux的/etc/shadow虽然被读取,但只用于判断账户是否禁用及最后一次修改时间,不输出哈希内容,安全审计的黄金法则是:永远不在报告中包含密码字段

Q5:非英文系统(中文)下脚本是否兼容?

  • A:若AD或Linux系统使用中文字段名,PowerShell脚本中应使用NameSamAccountName等内部字段名(与语言无关),CSV输出时通过ConvertTo-Csv可处理中文,Linux脚本的lastlog输出中日期格式可能依赖locale,建议在脚本头加export LANG=en_US.UTF-8确保一致格式。

总结与最佳实践建议

本文详细阐述了怎么用脚本获取安全账户管理的核心方法,覆盖Windows AD、Linux本地账户以及混合场景,通过自动化脚本,运维人员可以:

  • 每周自动扫描所有账户,输出“特权用户清单”和“长期未登录清单”。
  • 与CMDB系统联动,发现未注册的服务账户(如:sqlsvc、backupuser)。
  • 建立“时间线”:对比不同时段的报告,发现新增/删除账户。

最佳实践总结:

  1. 分层审计:先扫所有账户,再聚焦特权账户,最后人工复核。
  2. 持续自动化:将脚本放入计划任务(Windows Task Scheduler)或cron,设置每周一凌晨执行。
  3. 事件联动:当脚本检测到新账户被加入Domain Admins组时,立即触发告警(如发送到企业微信、钉钉)。
  4. 版本控制:脚本本身也需纳入Git管理,确保审计行为可追溯。

重点提醒:安全账户管理不是一次性的项目,而是持续的过程,脚本只是工具,配合严格的流程(如:申请-审批-回收)才能真正提升安全水位,从今天起,用脚本替代手工,让安全审计成为每周的自动化例行任务。

抱歉,评论功能暂时关闭!