尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

青龙面板被扫端口?应急响应全流程:从改密码到收端口加固

青龙面板被扫端口?应急响应全流程:从改密码到收端口加固 如果你不是第一次在服务器上部署青龙面板那你大概率见过这种场面凌晨两三点日志里突然冒出一大堆陌生IP反复访问5700端口间隔几秒换一组账号密码在尝试登录面板后台偶尔还会多出几条不是你创建的任务。这基本就是“被扫端口”了。端口暴露在公网上扫描器不需要什么高级技术只需要把默认端口、默认admin账号往登录页一撞就能撞出一片能上车的机器。这类事件的应急处理绝对不能只停留在“把密码改回来”这一步。密码重置只是止血真正要解决的是“攻击者从哪个口子进来的、进来了之后做了什么、以后怎么不让他再进来”。这篇文章就按我实际处理过的服务器应急排查流程来写先判断危害程度再重置面板密码然后收端口、看日志、清理痕迹最后把常态加固做起来。不管是Docker部署还是本机部署、不管你是把面板暴露在公网还是只在内网用这套思路都值得先存一份。1. 先判断到底是“被扫端口”还是“已经被日”很多人一看到扫描日志就慌上来就重置密码结果折腾半天发现攻击者早就在系统里留了后门。所以动手之前先花十五分钟判断一下事件性质这比急着改密码更重要。1.1 端口扫描的典型特征被端口扫描的机器通常有这几个共同特征你可以对照看一下面板访问日志里出现大量集中式访问同一时间段内十几个不同IP连续请求/login或/api/login接口UA五花八门但请求时间间隔非常短。尝试的账号高度集中基本都是admin、root、test这类默认用户名密码则是一长串常见弱口令组合。访问来源IP段分散经常是云厂商的扫描节点、住宅宽带出口或者IDC机房IP不一定能反查到具体是谁。除5700外同一台服务器上的其他端口比如22、3306、8888也可能同时出现探测记录这说明是网段级扫描不是专门盯上你。如果只看到以上现象说明攻击者大概率还在“撞库”阶段并没有真正进入面板。此时应急处理的窗口期还在按下面的顺序操作就行。1.2 应急处理的优先级排序我给自己定的处置顺序一直是“先隔离、再评估、后恢复”先把面板的入口收回来改掉默认监听端口、临时封禁扫描IP、或者直接在外层防火墙把面板端口丢进黑名单先把门关上。再确认账号是否失陷检查面板里有没有异常登录记录、异常任务、异常设备列表同时看系统层面有没有新增用户、定时任务、可疑进程。然后重置密码和登录凭证无论有没有发现异常密码都要改登录token、cookie、API令牌也要全部撤销。最后才是恢复服务和加固配置把端口收进内网、加反向代理、上强口令策略避免下一次再被扫中。这套顺序的核心逻辑是防止攻击者在你还毫无防备的时候继续操作面板。如果你先重置密码再关端口中间这几分钟里扫描器可能又撞进了新密码等于白改。先关门再换锁这才是正经的应急姿势。2. 重置青龙面板登录密码的实操路线青龙面板的密码不是存在配置文件里的明文而是存在SQLite数据库的auth_user表中。所以重置密码有三种路线改配置重启、直接改数据库、重建数据库。三种方案适用场景完全不同我一个个拆开讲。2.1 方法一修改config.sh并重启服务青龙面板的config/config.sh里有一项admin变量这是首次初始化时创建管理员账号用的。如果你的面板还没有完全初始化或者数据库里不存在admin账号修改这个参数后重启管理员密码会被重置为这里的值。首先是找到配置文件。Docker部署的话配置文件通常在宿主机的/ql/config/config.sh也可能在容器里/ql/config/config.sh。操作如下# 找到你的qinglong容器名 docker ps | grep qinglong # 进入容器 docker exec -it 容器名 bash # 查看当前配置里的admin项 cat /ql/config/config.sh | grep ^admin看到类似adminadmin的内容后改成你的新密码sed -i s/^admin.*/adminMyNewPassword2025/ /ql/config/config.sh然后退出容器并重启docker restart 容器名这个方法能不能生效取决于你的面板版本和部署方式。很多用户在初始化之后数据库里已经存在admin用户记录纯改环境变量并不会同步更新数据库里的密码。我这边实测下来2.x早期版本用这个方法不一定成功所以如果重启后旧密码仍然能登录说明环境变量法不适用别纠结直接看方法二。2.2 方法二直接操作auth_user数据库这是我最常用、也最推荐的重置方式。青龙的账号信息保存在/ql/db/ql.dbSQLite数据库里表名auth_user核心字段是username、password和salt。不同版本的密码哈希算法有差异不过逻辑一般是“盐值密码哈希”。我用下面这种方法处理过多个版本操作前建议先备份数据库防止改坏# 进入容器 docker exec -it 容器名 bash # 先备份数据库再动手 cp /ql/db/ql.db /ql/db/ql.db.bak_$(date %Y%m%d%H%M%S) # 安装/确认sqlite3可用 sqlite3 /ql/db/ql.db .tables查看auth_user表当前结构sqlite3 /ql/db/ql.db SELECT id, username, salt, length(password) FROM auth_user;看到表结构之后你就可以用下面的SQL更新密码。新密码哈希的计算方式在不同版本里不太一样这里给出最通用的方案sqlite3 /ql/db/ql.db UPDATE auth_user SET password 新密码的哈希值, salt 你自己生成的盐值 WHERE username admin; 那这个哈希怎么生成如果你面板里的密码字段是盐值MD5(密码盐值)的拼接格式那么可以用以下命令生成新值SALTabcdefgh # 8到16位随机字符 NEWPASSMyNewPassword2025 HASH$(echo -n $NEWPASS$SALT | md5sum | cut -d -f1) NEWSTORED$SALT$HASH echo $NEWSTORED然后把得到的NEWSTORED填入SQL的password字段再执行一次更新。更新完重启容器docker restart 容器名这里要提醒一句如果你对哈希结构拿不准千万别反复瞎试。每次试错都要先备份数据库否则连续改错几次账户数据会被搞乱最后只能走下面的兜底方案。2.3 方法三最保险的兜底——重建数据库慎用如果密码改不动、账号也被搞坏了还有一个终极办法把数据库初始化。青龙面板在检测不到auth_user表时会自动初始化一套新账号。你可以先把数据库文件改名让面板重新生成docker exec -it 容器名 bash mv /ql/db/ql.db /ql/db/ql.db.broken_$(date %s) exit docker restart 容器名重启后面板会回到初始状态用默认admin和你配置的admin变量登录但你的任务、环境变量、订阅配置、执行历史记录都会丢失。这相当于把整台机器重装了一遍。所以这个方法我只建议在两种极端情况下使用第一数据库已经损坏面板起不来第二你不确定数据库里被攻击者塞了多少后门账号、后门任务与其一个一个排查不如整个推倒重来。其余情况优先使用方法二。3. 从“改密码”到“收端口”公网暴露的应急收敛密码重置成功不代表安全。扫描器能扫到5700端口这件事本身就已经说明你的面板是裸露在公网的如果不把端口收回来今晚的暴力破解就会变成明晚的登录成功记录。3.1 快速切换监听端口和容器映射第一种应急手段是立刻换端口。这个操作的价值在于扫描器对旧端口的探测脚本还在持续跑你换一个新端口等于把门上的锁眼换掉了大批量扫描器短时间内不会追着新端口打。Docker部署的面板改端口改的是启动参数或compose文件里的映射关系。比如原来映射是-p 5700:5700把它改成docker run -d \ --name qinglong \ -p 127.0.0.1:5700:5700 \ -v /path/to/ql:/ql \ qinglong:latest上面这个写法有个关键点127.0.0.1:5700:5700表示只有本机回环地址可以访问5700公网IP一律无法直连。如果你是单机使用、或者打算用Nginx反代统一出口这就是最稳的映射方式。已经创建好的容器可以用下面这种方式改端口映射以Docker Compose为例services: qinglong: image: qinglong:latest ports: - 127.0.0.1:5700:5700然后重新加载docker compose up -d改完端口后再用外网IP测试一遍新端口是否能访问。如果还能访问说明你没有把宿主机防火墙和云安全组一起改掉外层还在放行继续看下一节。3.2 用Nginx反代收紧入口很多人觉得面板自带Web服务直接访问就行没必要套反代。但实际安全效果差很多。青龙面板本身没有完善的限流、IP黑白名单、登录失败锁定能力所有安全策略都得靠外层去卡。Nginx反代是最好的第一道闸。我这里分享一个我常用的反代配置带基础的IP限制和访问频率限制limit_req_zone $binary_remote_addr zoneqinglong_limit:10m rate10r/m; server { listen 5701 ssl; server_name panel.example.com; # SSL相关配置省略建议使用certbot自动签证书 # 只允许内网IP或指定IP访问可以按需放开 allow 192.168.1.0/24; # allow x.x.x.x; # 你自己的出口IP deny all; location / { limit_req zoneqinglong_limit burst20 nodelay; proxy_pass http://127.0.0.1:5700; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }这里有几个细节允许访问的IP段尽量写具体能不写0.0.0.0/0就不写。如果你人在公司或家里就把办公网/家庭宽带的出口IP加进去甚至可以直接全部置为deny all需要时再临时放行。limit_req是限流每秒允许的请求数别调太高。对于个人面板10r/m基本够用登录接口再怎么扫也扫不了几次。SSL证书一定要配。不加SSL的话所有请求都是明文传输攻击者在中间截获一次就能拿到你的登录凭证比暴力破解快多了。配置完了记得nginx -t nginx -s reload3.3 防火墙与云安全组双向拦截改映射和反代都是应用层的事网络层也得同时堵住。如果你的服务器有云厂商的安全组第一件事就是把5700以及你刚改的映射端口在公网入方向规则中删除只保留来自内网或特定IP的入站规则。云安全组是挡在服务器最前面的改完立即生效优先级最高。宿主机上的防火墙也要配合。以Linux自带的nftables或iptables为例直接给5700端口设置默认拒绝# 使用iptables示例 iptables -A INPUT -p tcp --dport 5700 -j DROP iptables -A INPUT -p tcp --dport 5700 -s 127.0.0.1 -j ACCEPT如果只允许特定IP访问那就把DROP前的ACCEPT规则指向你的IP段iptables -A INPUT -p tcp --dport 5700 -s 192.168.1.0/24 -j ACCEPT iptables -A INPUT -p tcp --dport 5700 -j DROP顺手把系统里其他无用的对外端口也过一遍22端口如果没有特殊需求尽量用密钥登录并关闭密码登录能挡住一大波扫SSH的脚本。4. 日志排查判断失陷程度并清理可疑痕迹收完端口、换完密码还要回答一个更扎心的问题在先前的空窗期里攻击者到底有没有成功登录过如果登录过又做了什么这块必须靠日志说话。4.1 查看登录与操作日志青龙面板本身的登录日志不算太详细但数据库的登录事件表会记录一部分。以SQLite为例可以查看login_log或log相关表版本不同表名不同sqlite3 /ql/db/ql.db .tables找到登录记录后重点查看失败和成功的登录条目sqlite3 /ql/db/ql.db SELECT * FROM login_log ORDER BY id DESC LIMIT 50;你需要关注的信息主要是这几类登录IP是否为陌生地址登录时间是不是凌晨或你在睡觉的时间段登录后的操作路径中是否包含修改配置、创建任务、查看环境变量等敏感动作。如果面板的日志不够用那就去查宿主机上的访问日志。如果你是Nginx反代/var/log/nginx/access.log会把每一条请求都记录下来可以直接用grep过滤出面板路径grep -E /(login|api|config) /var/log/nginx/access.log | tail -n 200把突然出现的、来源IP明显不属于你的访问记录单独摘出来这就是排查失陷的关键线索。4.2 检查任务与脚本目录中的可疑文件攻击者成功登录面板后最常干的动作之一就是新建一个定时任务拉一段远程脚本执行。这个脚本可能是挖矿程序、批量爆破工具或者反弹shell。检查方法很直接先去面板后台的任务列表里看有没有自己不认识的脚本。实际排查时我还会去文件系统里清一遍# 查看定时任务配置文件 cat /ql/config/user.db # 旧版本 # 或 ls -la /ql/config/ # 新版任务相关文件可能在config下 # 查看脚本目录里最近被修改的文件 find /ql/scripts -type f -mtime -3找到可疑脚本后不要急着删先把它压缩备份再去看它的内容重点留意里面有没有高权限下载、横向扫描、反弹shell之类的行为。确认无害后再清理任务和文件。系统层面也不能漏掉。用下面几组命令快速排查# 新增用户 cat /etc/passwd | awk -F: $31000{print $1,$3,$7} # 当前登录会话 who lastlog # 最近修改的shell脚本 find /tmp /var/tmp /home -name *.sh -mtime -2 -exec ls -l {} \; # 定时任务 crontab -l cat /etc/crontab4.3 清理会话、令牌与后门账号就算没有发现实质性入侵重置密码之后也要把所有旧凭证作废。这里的“凭证”不光是密码还包括面板的登录token、推送token、Web API令牌。青龙面板里设备的登录状态可以通过系统设置或设备管理页面一键清理。如果你不自觉地在哪台手机上长期挂着登录攻击者拿到同一条token后就能一直维持会话单纯改密码是踢不掉他的。所以务必把所有已登录设备全部踢下线重新登录一遍。数据库层面也可以直接删除会话记录sqlite3 /ql/db/ql.db DELETE FROM auth_sess; DELETE FROM access_token; DELETE FROM login_log;这条命令的意思是删除会话表、访问令牌表和登录日志。下次登录时所有设备都要重新验证身份顺手还把痕迹清掉了。如果你怕漏可以直接把auth_user表里除admin外的其他账号一并删除防止攻击者给自己建了后门管理员。5. 常见问题速查与避坑经验处理这类应急事件多了总会有几个反复被问到的问题。我直接做成一张速查表后面再补充几条自己的踩坑经验。5.1 高频问题速查表问题原因解决方案重置密码后无法登录修改的密码字段格式与版本不匹配备份数据库后重新核对auth_user表结构和字段长度必要时按版本源码中的密码生成逻辑重新计算面板一直提示密码错误数据库被写入过多个admin记录查询auth_user表确认有无重复账号删除多余记录后重试改完端口外网还能访问云安全组或防火墙还在放行旧端口云控制台安全组入方向删除5700宿主机执行iptables -L -n核对规则明明重置了密码扫描器还在撞攻击者正通过已登录会话维持访问清理auth_sess和登录令牌将所有设备踢下线并更换API token任务列表多了陌生脚本面板已被登录并新建任务备份可疑脚本到离线目录在任务列表删除排查系统级后门后再取消隔离数据库直接改坏了反复执行SQL语句出现语法错误用之前的备份恢复cp ql.db.bak_文件名 ql.db重启面板5.2 操作心得与不建议踩的坑处理了这个多案例后我有几条很深的体会。第一永远不要只改密码就收工。我在处理一台被扫端口的面板时用户信誓旦旦说密码已经改了结果我上去一看auth_user表里除了admin外还有一个名为support的账号创建时间正好是扫描日志爆发的时间点。攻击者进的不是正门而是自己开的窗户。如果你不把数据库翻一遍、不把系统用户翻一遍根本发现不了。第二配置绝对不要把面板端口直接映射到公网。我自己现在的服务器即使在内网也坚持用Nginx反代加IP白名单因为安全边际不是靠运气堆出来的。你可以想象一下5700端口就像你自己家里的门牌号发在公开黄页上每天都有陌生人上门敲两下。哪怕你密码再强时间久了总有人想尽办法撬锁。把端口藏起来让外面根本看不到你这扇门才是治本。第三备份数据库是任何重置操作的前置条件。青龙面板的数据库里不只有密码还有任务历史、执行日志、环境变量配置。改错一次就可能把重要数据弄丢。我的习惯是每次操作前都先复制一份ql.db带时间戳存到/ql/db/backup/下这样就算操作失误也能快速还原不用走重建数据库的极端路线。第四有条件的话直接加一层登录失败锁定和IP黑白名单策略。青龙面板自身在这一块比较薄弱你可以用脚本定时扫描日志发现有IP连续失败超过5次就自动封禁。把这些自动化堵塞逻辑做成例行任务比每次出事后再动手救援省心太多。这几次应急处理下来我最大的感受是端口被扫并不恐怖恐怖的是被扫之后你不当回事。改密码、换端口、看日志、清后门这一套流程听起来标准但每一步都有细节。你按上面走一遍至少能把大部分风险挡在门外。
返回列表