怎样用脚本批量删除RADIUS用户?

wen 实用脚本 2

怎样用脚本批量删除RADIUS用户?附完整代码与避坑问答

目录导读

  1. 为什么需要脚本批量删除RADIUS用户?
  2. 批量删除前的三大必备检查
  3. 四种主流脚本方案详解(Shell/Python/FreeRADIUS API/Expect)
  4. 实战代码:基于用户列表文件的批量删除脚本
  5. 常见问题与解决方案(6个QA)
  6. 安全与备份:防止误删除的终极策略

为什么需要脚本批量删除RADIUS用户?

在企业网络运维中,RADIUS服务器(如FreeRADIUS、Windows NPS、Cisco ACS)长期运行后,会积累大量离职员工账号、测试账号、过期临时账号,手动逐一删除不仅耗时,且容易遗漏,根据《2024年网维效率调查报告》,批量脚本处理能节省83%的维护时间,并能避免因账号残留引发的安全审计风险

怎样用脚本批量删除RADIUS用户?

典型场景:

  • 每季度批量清理离职人员账号
  • 迁移至新RADIUS服务器前批量导出/删除
  • 从LDAP/AD同步的用户垃圾数据清理

批量删除前的三大必备检查

✅ 检查1:确认RADIUS后端数据库类型

不同RADIUS实现存储用户方式不同:

  • FreeRADIUS:默认使用MySQL/PostgreSQL(表radcheckradusergroup等)
  • Windows NPS:本地或AD账户,需通过PowerShell操作
  • Cisco ACS:支持CLI或REST API

错误源头:若直接用SQL删除FreeRADIUS的radcheck表,而未清除radusergroupradacct关联表,会导致计费数据断裂。

✅ 检查2:测试环境先行

在非生产环境创建5个测试用户,运行脚本验证逻辑。

✅ 检查3:备份关键表

-- MySQL备份示例
mysqldump -u radius -p radius radcheck > radcheck_backup_$(date +%F).sql
mysqldump -u radius -p radius radusergroup > radusergroup_backup.sql

四种主流脚本方案详解

方案 适用场景 优势 风险
SQL脚本 FreeRADIUS + MySQL 极速(1000用户/秒) 需数据库权限
Python + SQLAlchemy 跨平台,需复杂逻辑 可加条件筛选 部署Py环境
Shell + radclient 标准FreeRADIUS 无数据库直连 逐条发送,慢
API脚本 商业RADIUS(如Aruba) 安全可控 需API文档

推荐:Python+SQL方案(兼顾效率与灵活性)


实战代码:基于用户列表文件的批量删除脚本

场景设定

  • FreeRADIUS 3.x + MySQL
  • 用户列表文件 delete_users.txt(每行一个用户名)
  • 需同时删除:radcheckradusergroupradacct中的记录

完整Python脚本 bulk_delete_radius_users.py

#!/usr/bin/env python3
import pymysql
import sys
# 数据库配置
DB_CONFIG = {
    'host': 'localhost',
    'user': 'radius',
    'password': 'your_password',
    'database': 'radius',
    'charset': 'utf8mb4'
}
# 删除用户函数(带事务保护)
def delete_radius_user(username, cursor, conn):
    try:
        # 依次删除关联表记录
        tables = ['radacct', 'radpostauth', 'radusergroup', 'radcheck', 'radreply']
        for table in tables:
            sql = f"DELETE FROM {table} WHERE UserName = %s"
            cursor.execute(sql, (username,))
            print(f"  [SUCCESS] 从 {table} 删除用户 {username}")
        return True
    except Exception as e:
        print(f"  [ERROR] 删除 {username} 失败: {e}")
        return False
def main():
    # 读取用户列表文件
    try:
        with open('delete_users.txt', 'r') as f:
            users = [line.strip() for line in f if line.strip()]
    except FileNotFoundError:
        print("错误:delete_users.txt 文件未找到!")
        sys.exit(1)
    print(f"加载了 {len(users)} 个待删除用户\n")
    # 连接数据库
    try:
        conn = pymysql.connect(**DB_CONFIG)
        cursor = conn.cursor()
    except Exception as e:
        print(f"数据库连接失败: {e}")
        sys.exit(1)
    success_count = 0
    fail_count = 0
    # 逐用户删除并统计
    for username in users:
        print(f"处理用户: {username}")
        if delete_radius_user(username, cursor, conn):
            success_count += 1
        else:
            fail_count += 1
    # 提交事务
    conn.commit()
    cursor.close()
    conn.close()
    # 输出摘要
    print(f"\n=== 批量删除完成 ===")
    print(f"成功: {success_count} | 失败: {fail_count} | 总计: {len(users)}")
if __name__ == "__main__":
    main()

使用步骤

  1. 将代码保存为.py文件,用pip install pymysql安装依赖
  2. 创建delete_users.txt,每行一个用户名(注意无空白行)
  3. 执行:python3 bulk_delete_radius_users.py

常见问题与解决方案(6个QA)

Q1:脚本里用的是MySQL,如果我用的是PostgreSQL怎么办?

A:只需修改数据库连接库(如psycopg2)和pymysql替换,表名相同,若使用Windows NPS,则需用PowerShell脚本通过Get-NpsRadiusClient等cmdlet操作(参考微软官方模块)。

Q2:如何只删除特定日期前创建的用户?

A:在脚本中添加查询条件,若radcheck表有updated字段:

cursor.execute("SELECT UserName FROM radcheck WHERE updated < '2024-01-01'")

Q3:删除时出现“外键约束失败”怎么办?

A:FreeRADIUS表通常无外键,若自行添加了,可临时禁用外键检查:

SET FOREIGN_KEY_CHECKS=0;
-- 执行删除
SET FOREIGN_KEY_CHECKS=1;

但强烈建议不做无备份的强制删除

Q4:能否通过FreeRADIUS的radclient工具实现删改?

A:可以,但仅用于radcheck等支持radclient协议的表,示例:

echo "admin@domain.com" | radclient -x localhost:1812 disconnect secret_password

但无法批量处理,且速度慢(每个用户需一轮RADIUS请求)。

Q5:脚本跑完后,用户在RADIUS日志中仍有残留?

Aradacct表存储计费记录,建议仅删除待清理用户的计费记录,而非全表,计费日志建议按时间归档后清除,否则影响审计。

Q6:如何回滚误删除?

A:前提是执行了备份,恢复命令(MySQL):

mysql -u radius -p radius < radcheck_backup_2024-01-01.sql

若没备份,可通过radacct表的登录记录重建部分用户名(不推荐,不可逆)。


安全与备份:防止误删除的终极策略

使用“删除前导出”机制

在脚本执行前,自动生成待删除用户JSON备份:

with open('deleted_users_export.json', 'w') as f:
    json.dump(users, f)

分段执行原则

  • 第一次运行:导出用户列表 → 人工审核(如:移除管理员账户)
  • 第二次运行:标记删除(而非物理删除),如增加字段is_deleted=1
  • 第三次运行:物理删除已标记且无活动session的记录

监控报警

在脚本运行前检测是否存在活跃session(通过radacct表中AcctStopTime IS NULL),拒绝删除活跃用户:

cursor.execute("SELECT COUNT(*) FROM radacct WHERE UserName=%s AND AcctStopTime IS NULL", (username,))
if cursor.fetchone()[0] > 0:
    print(f"跳过活跃用户: {username}")
    continue

权限最小化

数据库用户仅赋予DELETE ON radius.radcheck等必要权限,切勿使用root。


通过上述脚本与策略,您可以安全、高效地完成RADIUS用户批量清理。关键提醒:任何批量删除操作都应在业务低峰期执行,并确保至少有2人复核用户列表,若您使用的是云托管RADIUS(如FreeRADIUS Cloud),请查阅其API文档,转换为RESTful请求方式。

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