本文目录导读:

- 📚 目录导读
- 为什么需要批量修改WiFi密码?——从运维痛点谈起
- 脚本批量修改的核心原理
- 实战代码:用Python批量修改WiFi密码
- 进阶方案:Shell + Expect(适合Linux运维者)
- 常见问题与排错指南
- 安全与合规建议
- Q&A问答专区
📚 目录导读
- 为什么需要批量修改WiFi密码?(场景与痛点分析)
- 脚本批量修改的核心原理(SSH/API与设备交互机制)
- 主流方案实战代码(Python + Paramiko / Shell + Expect)
- 常见问题与排错(设备不兼容、密码同步失败等)
- 安全与合规建议(密码策略、日志审计)
- Q&A问答专区(高频问题解答)
为什么需要批量修改WiFi密码?——从运维痛点谈起
在 企业网络管理、酒店/学校/园区无线覆盖 场景中,手动逐个登录设备修改WiFi密码是 效率黑洞:
- 假设有50台AP(接入点),手动登录每台设备→找到无线配置→修改密码→保存→重启服务,每台耗时5分钟,总计4小时以上。
- 更糟糕的:若存在异构设备(如不同厂商AP),流程不统一,极易遗漏或配置错误。
- 安全事件后应急响应(如员工离职需重置密码)要求 分钟内 完成全量修改,手工操作无法达标。
脚本批量修改 是运维必备技能,核心解决 “一次编写,多次执行” 的重复劳动问题。
脚本批量修改的核心原理
1 交互方式选择
| 交互方式 | 适用设备 | 优点 | 缺点 |
|---|---|---|---|
| SSH命令 | 主流企业AP(Cisco/Aruba/Ruckus/OpenWrt) | 标准协议,安全性高 | 需启用SSH服务 |
| Telnet | 老旧设备 | 简单 | 明文传输,不推荐 |
| HTTP/HTTPS API | 云管理AP(如Ubiquiti/TP-Link Omada) | 批量调用方便 | 需要API密钥,且平台差异大 |
| SNMP | 部分企业级AP | 无侵入 | 配置复杂,部分功能受限 |
2 核心流程设计
准备设备IP列表+SSH凭据(建议使用CSV或YAML文件)
2. 循环遍历每台设备
3. 通过SSH登录
4. 执行厂商特定命令(如修改无线配置)
5. 保存配置(部分设备需write memory)
6. 验证新密码是否生效(可选)
7. 记录日志
实战代码:用Python批量修改WiFi密码
场景假设:管理50台运行OpenWrt的路由器/AP,需同时修改SSID为“Office”的密码
1 前期准备
- 安装Python库:
pip install paramiko pandas - 准备设备列表文件
devices.csv:ip,username,password,ssh_port 192.168.1.10,root,old_password,22 192.168.1.11,root,old_password,22 ...
2 完整脚本
import paramiko
import pandas as pd
import logging
from time import sleep
# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
def ssh_execute(host, username, password, command, port=22):
"""SSH执行单条命令并返回输出"""
try:
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(host, port=port, username=username, password=password, timeout=10)
stdin, stdout, stderr = client.exec_command(command)
output = stdout.read().decode('utf-8')
error = stderr.read().decode('utf-8')
client.close()
return output, error
except Exception as e:
logging.error(f"设备 {host} 连接失败: {str(e)}")
return None, str(e)
def change_wifi_password(host, creds, new_password, ssid="Office"):
"""修改指定SSID的密码(OpenWrt /etc/config/wireless为例)"""
# 步骤1: 读取当前无线配置(可选,用于确认SSID存在)
cmd_check = f"uci show wireless | grep {ssid}"
output, error = ssh_execute(host, creds['user'], creds['pass'], cmd_check)
if not output:
logging.warning(f"设备 {host} 未找到SSID: {ssid},跳过")
return False
# 步骤2: 执行密码修改命令(需根据实际无线接口名调整,此处为示例)
# 真实场景建议先通过uci show wireless获取无线接口名
cmd_change = f"""
uci set wireless.@wifi-iface[0].key='{new_password}'
uci commit wireless
wifi reload
"""
output, error = ssh_execute(host, creds['user'], creds['pass'], cmd_change)
if error:
logging.error(f"设备 {host} 修改失败: {error}")
return False
# 步骤3: 保存配置(部分固件需要)
ssh_execute(host, creds['user'], creds['pass'], "uci commit")
logging.info(f"设备 {host} 密码修改成功")
return True
def main():
# 读取设备列表
df = pd.read_csv('devices.csv')
new_pass = "NewSecurePass123!" # 新密码,建议从环境变量读取
success_count = 0
for index, row in df.iterrows():
host = row['ip']
creds = {
'user': row['username'],
'pass': row['password']
}
logging.info(f"正在处理设备 {host}")
result = change_wifi_password(host, creds, new_pass)
if result:
success_count += 1
sleep(1) # 避免设备端SSH连接过多
logging.info(f"处理完成,成功{success_count}/{len(df)}台")
if __name__ == "__main__":
main()
3 重要注意事项
- 命令适配:不同厂商的无线配置命令差异极大,需要先手动在一台设备上验证命令,例如Cisco的
config t → interface dot11radio 0 → ssid Office → authentication open → key 12345678。 - 并发控制:若设备数超100,建议用
concurrent.futures.ThreadPoolExecutor控制并发数(推荐10-20线程)。 - 密码安全:密码建议从环境变量或加密配置读取,不硬编码在脚本中。
- 双因子验证:部分设备SSH可能需密钥认证,可改用
paramiko.RSAKey加载私钥。
进阶方案:Shell + Expect(适合Linux运维者)
如果设备不支持Python环境,纯Shell脚本配合 expect(自动交互工具)更轻量:
#!/bin/bash
# wifi_batch_change.sh
# 用法: ./wifi_batch_change.sh <new_password>
NEW_PASS=$1
if [ -z "$NEW_PASS" ]; then
echo "Usage: $0 <new_password>"
exit 1
fi
# 读取IP列表文件(每行一个IP)
for HOST in $(cat device_ip.txt); do
echo "Processing $HOST..."
# 使用expect自动交互SSH登录并执行命令(此处以OpenWrt为例)
/usr/bin/expect <<-EOF
set timeout 10
spawn ssh root@$HOST
expect "password:" { send "old_default_pass\r" }
expect "#" { send "uci set wireless.@wifi-iface[0].key='$NEW_PASS'\r" }
expect "#" { send "uci commit wireless\r" }
expect "#" { send "wifi reload\r" }
expect "#" { send "exit\r" }
expect eof
EOF
done
注意:expect 方式安全性较低(密码明文出现在脚本),仅建议用于临时或内部测试网络。
常见问题与排错指南
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| SSH连接超时 | 设备未开启SSH,或IP不可达 | 先 ping 测试,在设备Web界面检查服务 |
| 命令执行无报错但密码未变 | 无线接口索引错误(如@wifi-iface[0]与实际不符) |
先登录设备执行 uci show wireless 确认索引号 |
| 部分设备修改成功部分失败 | 固件版本差异导致的命令语法变化 | 按厂商版本分支处理,或用设备API代替SSH |
| 新密码立即被回退 | 部分设备内存写保护未执行写入 | 增加 uci commit 或 save 命令 |
| 密码包含特殊字符导致shell错误 | 单引号/反斜杠未转义 | 在脚本中使用双引号包裹,并使用 sed 替换特殊字符 |
安全与合规建议
- 审计日志:脚本应记录每台设备的操作结果(成功/失败、时间戳、操作IP),便于事后追踪。
- 凭证保护:建议使用 Ansible Vault 或 HashiCorp Vault 管理设备密码,脚本不存储明文。
- 灰度发布:先对5%的设备执行,验证无误后再全量推送。
- 网络隔离:若设备在不同VLAN,脚本机需有网络权限,并设置防火墙限制SSH来源IP。
- 定期轮换:配合自动化任务(如cron)设置周期性密码修改(如90天一次)。
Q&A问答专区
Q1: 不同品牌的AP(如Cisco + Aruba)能用同一个脚本吗?
A:不能直接复用命令,建议按品牌分组,每组调用对应模块,脚本中可加 if-elif 判断设备型号(通过SNMP或SSH执行的 show version 输出)。
Q2: 机房有200台AP,脚本运行多久?
A:串行处理每台约10-15秒(含SSH握手和命令执行),200台约30-50分钟,若用10线程并发,可缩短至5-8分钟,注意设备端SSH连接数限制(通常每台最多5个并发)。
Q3: 支持通过云管理平台(如Meraki/Cisco DNA)批量改吗?
A:支持,这类平台通常有 REST API,只需写HTTP请求(如Python的 requests 库)发送新密码参数,无需SSH,效率更高,但需申请API Token并了解文档。
Q4: 如何验证密码是否真的修改成功?
A:可在脚本末尾用 curl 或手机测试连接,对OpenWrt设备,可执行 iwinfo wlan0 assoclist 验证新客户端能否连接(需提前断开旧连接),生产环境建议用自动化测试工具(如WPA2连接测试库)。
Q5: 密码修改后,已连接的客户端会自动断开?
A:取决于设备实现。wifi reload 会重启无线服务,已连接的客户端会断开并需输入新密码重连,建议在业务低峰期执行,或分批操作(如每5分钟修改10台)。
批量修改WiFi密码的核心在于 自动化交互 + 命令适配 + 异常处理,使用Python+Paramiko是多数运维团队的首选,而Shell+Expect适合轻量快速场景,无论哪种方案,务必先做测试,并建立回滚机制(如备份旧配置),掌握此技能,你再也不用逐个登录设备改密码了。