怎样用脚本批量删除RADIUS用户?附完整代码与避坑问答
目录导读
- 为什么需要脚本批量删除RADIUS用户?
- 批量删除前的三大必备检查
- 四种主流脚本方案详解(Shell/Python/FreeRADIUS API/Expect)
- 实战代码:基于用户列表文件的批量删除脚本
- 常见问题与解决方案(6个QA)
- 安全与备份:防止误删除的终极策略
为什么需要脚本批量删除RADIUS用户?
在企业网络运维中,RADIUS服务器(如FreeRADIUS、Windows NPS、Cisco ACS)长期运行后,会积累大量离职员工账号、测试账号、过期临时账号,手动逐一删除不仅耗时,且容易遗漏,根据《2024年网维效率调查报告》,批量脚本处理能节省83%的维护时间,并能避免因账号残留引发的安全审计风险。

典型场景:
- 每季度批量清理离职人员账号
- 迁移至新RADIUS服务器前批量导出/删除
- 从LDAP/AD同步的用户垃圾数据清理
批量删除前的三大必备检查
✅ 检查1:确认RADIUS后端数据库类型
不同RADIUS实现存储用户方式不同:
- FreeRADIUS:默认使用MySQL/PostgreSQL(表
radcheck、radusergroup等) - Windows NPS:本地或AD账户,需通过PowerShell操作
- Cisco ACS:支持CLI或REST API
错误源头:若直接用SQL删除FreeRADIUS的
radcheck表,而未清除radusergroup、radacct关联表,会导致计费数据断裂。
✅ 检查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(每行一个用户名) - 需同时删除:
radcheck、radusergroup、radacct中的记录
完整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()
使用步骤
- 将代码保存为
.py文件,用pip install pymysql安装依赖 - 创建
delete_users.txt,每行一个用户名(注意无空白行) - 执行:
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日志中仍有残留?
A:radacct表存储计费记录,建议仅删除待清理用户的计费记录,而非全表,计费日志建议按时间归档后清除,否则影响审计。
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请求方式。