☰
南墙WAF后台锁死自救:密码重置与FreeOTP令牌恢复实战
2026/10/21 5:57:26 网站建设 项目流程

手里一台南墙WAF管理后台进不去了:密码忘了,手机上的FreeOTP又被误删了,两个认证因素同时失效。这个场景光是听着就让人手心冒汗,但先别急着找厂商,更别急着重装系统。这类“自锁门外”的问题,绝大多数都能在不丢规则、不丢证书、不重做业务的前提下恢复。

这篇文章我把完整排查路径写下来:从搞清楚密码和动态口令到底存在哪里,到命令行重置口令,再到把误删的FreeOTP令牌从数据库里重新捞回来扫码,最后附上我在实际处理中踩过的坑。适用于在一体机或云服务器里部署了南墙WAF,又恰好把管理后台锁死的运维同学。只要你还能登录操作系统,WAF的安装目录和数据文件还在,事情就还有得救。

1. 先搞懂:密码和动态口令到底存在哪里

很多人一慌就想着重装系统,其实是被“账号密码”这个思维带偏了。要恢复访问,先得知道南墙WAF把认证信息放在哪、用什么形式存放。这两件事想清楚了,恢复动作就顺理成章。

1.1 密码不是“明文”而是“哈希”

南墙WAF的管理员账号和口令,和大多数Web系统一样,存在安装目录下的数据库里。数据文件可能是SQLite单文件,也可能是MySQL/MariaDB中的一张表。口令本身不会以明文存放,而是经过不可逆的哈希算法处理后的字符串,常见的是bcrypt这种带随机盐的哈希。

哈希这个东西可以这么理解:数据库里存的不是“钥匙”,而是“这把钥匙的指纹”。你没法从指纹反推出钥匙原来的样子,也就是所谓的“找回密码”在技术上不成立。但你可以直接把“指纹”换成另一把新钥匙的,也就是重置密码。这比“找回旧密码”简单得多。

所以第一步不是找旧密码,而是确认数据库文件在哪、认证表是哪张、口令字段叫什么。后面我会给出一套通用定位方法,不同版本的南墙安装路径会有差异,但思路一致。

1.2 FreeOTP里的令牌只是一份“种子副本”

FreeOTP这类TOTP动态口令工具,很多人以为它像密码一样“验证的是手机上的一个码”。实际上,它验证的是算法结果。TOTP的完整校验逻辑是:服务器保存一串密钥种子(seed),手机上的FreeOTP也保存同一串seed,双方各自用“当前时间”计算出一个6位验证码,比对是否一致。

也就是说,FreeOTP里那个看似独立的动态口令条目,本质上是服务器那份seed的副本。你在手机上删除了这个条目,不等于服务器上的seed也消失了。只要数据库里的seed字段还在,令牌就能重新生成、重新导入新手机。

这是整个恢复方案的支点:密码哈希可以重置,动态口令种子可以从数据库里取回来。两个因素都能在服务器本地重新配置,唯一的前提是你对服务器还有操作系统的访问权限。

2. 动手前先做三件事:评估、备份、定路线

拿到服务器权限之后,别急着改数据库,先花十分钟做评估。我见过不少同事因为跳过这一步,把本来能救的局面搞得更复杂。

2.1 三条恢复路径的利弊对比

根据当前状态,可以走的路大致有三条:重置密码并保留双因子、重置密码同时关闭双因子、离线重装。把利弊列清楚再选,比直接敲命令稳妥。

恢复路径适用场景风险是否丢配置
重置密码,保留原双因子手机令牌还在,只是忘了密码风险最低,只需改一个字段不丢
重置密码,关闭双因子手机令牌误删或无法恢复需要重新开启2FA并绑定新手机不丢
离线重装南墙数据库损坏、服务无法启动、文件被误删风险最高,可能丢规则和证书可能丢

绝大多数“忘记密码+误删FreeOTP”的场景,选中间那条路最合适:先重置密码,再临时关闭2FA,等重新登录后台后重新绑定新手机的令牌。如果你希望尽可能保留原seed,也可以先尝试把seed从数据库里导出再导入新手机,后面第3章会讲两种做法。

2.2 先备份,再动手

改数据库之前,先把整个WAF安装目录、证书目录和数据库文件完整拷贝一份。这一步不是为了好看,而是给自己留后悔药。哪怕后面命令敲错了,拿备份回滚就行,不至于把前端的防护规则和SSL证书一起搞没。

我常用的备份命令很简单,关键是把路径找全:

# 先看WAF服务是怎么启动的,找到安装路径 systemctl status waf 2>/dev/null || service waf status # 假设安装目录是 /usr/local/waf,做一次全量拷贝 mkdir -p /backup/waf-$(date +%Y%m%d) cp -a /usr/local/waf /backup/waf-$(date +%Y%m%d)/

如果用的是MySQL存储,数据库也别落下:

mysqldump -uroot -p safewaf > /backup/waf-$(date +%Y%m%d)/safewaf.sql

证书目录通常在Nginx或Web服务的ssl目录下,如果和WAF安装目录不在一起,也要一并备份。这里的经验是:宁可多拷,不要漏拷。一个几KB的seed字段丢了,比多拷贝几个GB文件麻烦得多。

2.3 定位数据库和认证表

如果不知道数据库具体在哪,用下面的方式快速定位。先看服务脚本,再顺着脚本里的参数找数据目录:

# 查看WAF服务脚本内容 cat /usr/lib/systemd/system/waf.service # 或者 cat /etc/init.d/waf

脚本里通常会有ExecStart=/usr/local/waf/sbin/xxx这类路径,安装目录基本就在那附近。接着找数据库文件:

find / -name "*.db" -size +1M 2>/dev/null

如果机器上有MySQL或MariaDB在跑,也可以直接检查对应库:

mysql -uroot -p -e "SHOW DATABASES;"

找到数据库后,查看认证相关的表结构。一般会有类似user、admin、sys_user的表,里面大概率包含password、totp_secret、totp_enable、twofa_status这类字段。不同版本字段命名不同,但思路都是一样的:口令哈希一个字段,双因子开关一个字段,TOTP种子一个字段。

3. 手把手恢复:重置密码和捞回FreeOTP令牌

下面按实际操作顺序来。整个过程分三步:先把密码改成新值,再确认或恢复双因子令牌,最后重启服务验证登录。这里我同时给出SQLite和MySQL两种写法,实际环境只会用到其中一种。

3.1 生成新口令哈希并写入数据库

密码不能直接写成明文,否则要么登录不上,要么系统启动时校验报错。要先在命令行生成一个新的哈希,再写进数据库。

以bcrypt为例,在服务器上用Python一行生成:

python3 -c "import bcrypt; print(bcrypt.hashpw(b'MyNewPass2024!', bcrypt.gensalt()).decode())"

把输出的哈希串复制下来,然后登录数据库写回。SQLite的写法:

sqlite3 /path/to/safewaf.db UPDATE user SET password='$2b$12$....你生成的哈希....' WHERE username='admin';

如果是MySQL:

mysql -uroot -p -e "UPDATE safewaf.user SET password='$2b$12$....' WHERE username='admin';"

这里有一个容易被忽略的细节:如果原口令哈希是以$6$开头的SHA-512格式或其它格式,而你写入的是bcrypt,系统登录时可能仍然校验失败。稳妥的做法是先看现有哈希的前缀,推断原算法,尽量选择一致的算法生成新哈希。如果实在不确定,就先把数据库里所有与认证相关的表结构打印出来看一遍,再决定改哪些字段。

重置后的密码建议用随机生成的强口令,别顺手设成admin123这种。你要恢复的是安全设备的控制权,不是给自己埋下一个更明显的漏洞。

3.2 从数据库里把“误删的FreeOTP”捞回来

如果你只是误删了手机上的FreeOTP条目,服务器上绑定关系其实没变,这时直接导出seed,在新手机上重新导入,是最优雅的恢复方式。

先在用户表里找到TOTP种子字段:

sqlite3 /path/to/safewaf.db ".schema user"

找到类似totp_secret、otp_secret、seed的字段后,查询它的值:

sqlite3 /path/to/safewaf.db "SELECT username, totp_secret FROM user WHERE username='admin';"

得到一个字符串,这个字符串通常就是base32编码的seed。接下来用Python把它转换成otpauth链接,并生成二维码:

import pyotp import qrcode secret = "这里粘贴查到的seed字符串" uri = pyotp.TOTP(secret).provisioning_uri(name="admin", issuer_name="safewaf") qrcode.make(uri).save("/tmp/totp_recover.png") print(uri)

把生成的二维码图片显示在屏幕上,或者传到手机上扫一下,就能把原来的令牌恢复到新手机里。FreeOTP本身也支持手动输入seed:打开App,选“Manual entry”,填一个账号名,粘贴seed字符串,类型选“Time-based”,时间步长30秒,算法SHA1,基本都能对上。

这个方案的唯一前提是你找得到seed字段,并且它没有被加密存储。如果南墙版本对seed做了加密或脱敏,那就别在这里耗时间,直接用第3.3节的方案,先关双因子,再重新绑定。

3.3 最省事的方案:先关闭2FA,登录后重新绑定新令牌

如果你实在找不到seed字段,或者担心导出的seed不完整,更稳妥的做法是直接把双因子临时关闭,登录后台后再重新走一遍“开启双因素认证→扫码绑定”的流程。

在数据库里,把双因子相关字段置为关闭状态:

sqlite3 /path/to/safewaf.db UPDATE user SET totp_enable=0, totp_secret=NULL WHERE username='admin';

如果字段名是twofa_status、otp_status,同样改成0。然后重启WAF服务:

systemctl restart waf

用新密码登录后台,进入安全设置或管理员管理页面,重新开启双因素认证。此时页面会生成一个新的二维码,用FreeOTP扫码绑定即可。

我建议优先走这条路,尤其是你并不在乎旧seed是否保留的时候。逻辑上它最短、最不容易出错,而且省去了验证旧seed解析是否正确的过程。唯一的代价是“临时关闭”这个动作本身意味着,那一小段时间里,WAF后台登录只依赖单因素。操作时尽量在无人值守或可信网络环境下进行。

4. 实操中最容易踩的五个坑

数据库命令本身不难,真正浪费时间的往往是这些不起眼的坑。我按出现频率从高到低整理出来。

4.1 数据库文件被进程占用,写不进去

SQLite在WAF服务运行时会持有文件锁,直接执行UPDATE可能得到database is locked的报错。遇到这种情况,别硬杠,先把服务停下再改:

systemctl stop waf sqlite3 /path/to/safewaf.db "UPDATE user SET password='...' WHERE username='admin';" systemctl start waf

MySQL一般没有文件锁问题,但要注意账号权限,干脆直接用root操作最省事。

4.2 密码改了,登录还是失败

确认哈希格式、确认改动字段正确、确认服务重启过,这三件事都要检查。还有一类隐蔽问题:南墙WAF后台可能有登录失败次数限制,或者有基于IP的临时封禁策略。你之前试密码可能已经触发了限制,这时即使密码正确也会被拦。可以等封禁时间过去,或者到数据库里把登录失败计数清零。

4.3 新手机扫码后验证码总是对不上

这种情况八成是“时间不同步”。TOTP要求客户端和服务器时间误差不能超过30秒,手机开了自动时间但时区不对,或者服务器没有配置NTP,都会导致验证码一直被拒绝。

先在服务器上校准时间:

timedatectl set-ntp true date

再确认手机时间、时区都是自动获取状态。两边的秒数误差在正负30秒以内,验证券就能对上。如果服务器没法连外网NTP,也可以手动调整时间,但要记得改完之后重新扫码绑定一次。

4.4 手动输入seed时提示无效

FreeOTP对seed格式有要求,通常必须是base32编码的字符串,只包含A-Z和2-7这32个字符,长度一般为16位或32位。如果你从数据库里翻出来的字段长得不像base32,可能你取错了字段,或者该字段本身就是经过编码处理的。

遇到这种情况,别反复试,直接看表结构里还有没有其他候选字段。实在找不到,就去走“关闭2FA→后台重新绑定”的路线,别在数据库字段上死磕。

4.5 修复完成后没有固化“后悔药”

很多人恢复登录之后就当没事发生,这是最大的隐患。下次再误删令牌、再忘密码,又要重新折腾一遍。务必把新生成的seed、恢复二维码、备份二维码都离线保存一份。动态口令工具的价值在于“你有别人没有”,所以这些备份信息要放到密码管理器或离线保险柜里,而不是写在桌面上的txt文件里。

5. 最坏情况兜底:如果数据库彻底进不去

操作系统的Shell还能用,但WAF服务起不来、数据库文件损坏、数据目录快照丢失,这种情况确实发生过。此时只能走离线重装,但重装不等于全丢,关键在于重装前抢救出两个东西:安装目录里所有配置和证书文件、还能读出来的数据库备份。

5.1 重装前的抢救动作

先把整个安装目录完整复制出来,尤其关注这几个子目录:配置目录、证书目录、规则目录、数据库目录。哪怕数据库文件损坏,也先拷贝一份,没准后面还能修复。

mkdir -p /backup/rescue cp -a /usr/local/waf /backup/rescue/ tar czvf /backup/rescue/waf-config.tar.gz /etc/waf /etc/ssl 2>/dev/null

重装南墙时,选择同版本或近版本,装完后把备份的证书和规则文件覆盖回去。数据库文件如果还能被SQLite读取,直接替换新库,然后执行第3章的重置密码步骤。如果数据库彻底打不开,那就只能重建管理员账号,规则从备份里恢复到新的WAF中。

这里有个经验:重装前一定要确认备份文件能正常读取,别只拷贝不验证。压缩包能不能解压、数据库能不能执行.tables,都测试一遍。我见过有人拷贝了十几GB数据,结果重装完才发现其中有几个关键的配置文件权限没保留,白忙一场。

5.2 恢复成功后立刻做三件事

密码重置、令牌恢复、后台登录都验证通过以后,不要急着关终端。先在后台重新生成新的双因子绑定,把seed抄到离线保管处;然后配置数据库自动备份任务,至少每天一次;最后把这次恢复过程的SOP写成文档,放到团队共享空间里。

为什么强调SOP?因为类似的“自锁”问题,不依赖某一个人的记忆。今天你可能记得怎么改,半年后的值班同事遇到同样问题,还是要重新摸索。把路径、字段名、命令都固化下来,团队整体效率会高很多。

最后分享一个我个人的习惯:在绑定任何TOTP令牌时,我都会把seed和恢复二维码存到密码管理器的“安全备注”里,而不是只存在手机。手机可能丢、可能误删,密码管理器里有备份,随时可以用新手机重新扫码。这个习惯救了我不止一次。安全设备的管理后台是攻击者最想拿下的地方,强密码加双因子是对的,但“怎么恢复访问”这件事,必须有plan B。每次做完恢复操作,我都会问自己一句:如果明天再来一次,我能更快解决吗?如果答案是否定的,就说明还有该固化的流程没固化。希望这篇恢复记录能让你少走点弯路。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询