⭐ 推荐:社区规则条款 V1.0

论坛被攻击怎么办?站长必须知道的安全防护清单

一只冷漠的狐狸
一只冷漠的狐狸 正式会员正式会员认证极客认证极客 钻石卡会员钻石卡会员
发布于 2026-10-16 02:43 ·5 浏览 ·12 回复
内容摘要

论坛被攻击时应先通过登录日志、回收站帖子和访问日志判断是爆破、灌水还是流量攻击,再开启 Clara BBS 内置的 CSRF 防护、密码哈希、输出转义和上传校验,配置同 IP 高频拦截与连错锁定、验证问答、邮箱黑名单、发帖间隔、敏感词及版块权限,并收紧上传扩展名白名单和 PHP 上传限制,辅以服务器备份与面板防护。

论坛被攻击不是「要不要防」的问题,而是「先防哪一层」的问题。Clara BBS 本身已内置全站 CSRF 防护、bcrypt 密码哈希、输出转义、上传白名单+图片二次校验这条安全基线,站长的活是把它打开、配对,再补上服务器层备份和面板防护。下面这份清单按攻击类型拆开讲,每一条都能在后台点到位。

怎么判断论坛正在被攻击?先看哪几个后台页面

结论:先定性再动手,登录日志、帖子状态、访问日志三处一起看,5 分钟能分清风控问题还是流量问题。

进后台「用户体系→登录日志」,如果看到同一 IP 在短时间内大量失败记录,那就是密码喷洒或字典爆破;如果日志里出现大量陌生 IP、每条只错 1-2 次,则是分布式撞库。再看「内容管理→帖子管理→状态筛选→回收站」,如果回收站里突然堆满广告帖,说明是注册机+灌水。

第三种是流量型攻击:前台打不开、后台也卡,但登录日志和帖子都正常,这种情况多半是 CC 或带宽被打满,属于服务器/面板层要处理的事,不是程序配置能解决的。

登录爆破怎么防?Clara BBS 的登录安全闭环怎么配

结论:把登录闭环四项全开,默认配置就能挡住绝大多数自动化爆破——默认 5 次连错锁定 15 分钟,后台可改。

需要确认的四个点:一是「系统设置→安全」里的同 IP 高频失败拦截是否开启,这是防密码喷洒的关键;二是连错锁定次数与锁定时长,默认 5 次 / 15 分钟,如果你的站经常有用户手滑,可以放宽到 8 次,但不要关掉;三是锁定到期自动解锁是否生效,避免用户被永久挡住;四是确认全程审计日志在写入,出事后能回溯。

已经中招的处理方式:后台「IP 封禁」可直接封 IP,支持定时封禁(比如封 7 天自动解封),比手工改 .htaccess 干净;被误锁的用户可以在后台手动解锁,不用等他熬过 15 分钟。另外,管理员账号不要和普通用户共用同一套弱密码,bcrypt 再强也扛不住 admin123。

灌水、广告、批量注册怎么挡?

结论:注册、发帖、回帖三个环节各设一道闸,注册端用验证问答+邮箱黑名单,发帖端用最小间隔+敏感词,基本能压掉九成广告。

具体配置:注册环节开启验证问答(机器难答、真人一秒答),邮箱域名黑名单内置近百个临时邮箱域,注册机最爱用的一次性邮箱会被直接拒掉;发帖回帖环节设置最小间隔(比如 30 秒),再挂上敏感词拦截,常见外链和联系方式关键词提前录入;图形验证码建议开启,注意如果 PHP 没有 GD 库,系统会自动降级成算术题,功能不受影响,不用专门装扩展。

权限上还有一层兜底:版块级权限矩阵可以按用户组单独控制浏览/发帖/回复/上传,留空即继承上级,新人组可以先限制成「可浏览不可发帖」,观察几天再放开。版块内还可以按版块开关「先审后发」,广告重灾区建议常开。

上传和附件是最大的漏洞入口吗?怎么收紧

结论:上传是论坛最高危的入口,Clara BBS 已经做了扩展名白名单+图片二次校验,站长要做的只是别把白名单开成「任意格式」。

两个容易踩的坑:第一,后台「系统设置→上传」里「允许的扩展名」和「附件允许的扩展名」是两个独立字段,前者管图片、后者管附件,很多人只改了一个,结果要么传不上图,要么放行了不该放的类型;第二,PHP 的 upload_max_filesize 与 post_max_size 必须大于实际文件体积,宝塔默认 2M,手机直出照片动辄 3-5M,建议调到 30M 以上,同时确认 uploads 目录可写——上传失败时页面会明确提示原因(超出 PHP 上限 / 白名单不符 / 目录不可写),照着提示改就行。

另外权限最小化:能不给附件的用户组就别给,附件下载权限可设「所有人/会员/指定用户组」,默认收紧到会员更稳。

内容被删被改,怎么兜底和追溯

结论:前台删除是软删除,进回收站保留 30 天,后台可恢复,超期才彻底删除——这 30 天就是你的后悔药窗口。

恢复路径:后台「内容管理→帖子管理→状态筛选→回收站」,找到帖子点恢复即可。天数在后台可配,数据量大的站可以缩短,重要站建议保持默认 30 天。

版主权限也要设边界:每个版块最多 10 位版主,版内全权但不出界。再配合后台「管理日志」,谁在什么时候删了帖、封了人,都有记录,出问题能定位到账号。遇到漏网的违规内容,走举报处理流,别让站长一个人盯全站。

服务器层还要做什么?三件不能省的事

结论:程序层再稳,也挡不住硬盘挂掉和流量打满,备份、HTTPS、面板防护必须自己做。

第一,数据库至少每天全量备份一次,异地存一份;附件和 uploads 目录同样要备份,这两样丢了没法恢复。第二,站点地址务必在后台「基本设置」里填带 https:// 的主域名,不要 www 和裸域混用——混用会导致会话丢失,用户频繁掉登录,同时也会让 CSRF token 失效报「页面已过期」。第三,宝塔等面板开好防火墙和 CC 防护,PHP 装在 7.4-8.5 之间的受支持版本,MySQL 5.7+。

已经中招了,按什么顺序处理

结论:顺序是「先止损、再取证、后修补」,反过来做会丢证据。

第一步封 IP、锁账号、必要时临时关闭注册;第二步导出登录日志和访问日志留档;第三步查有没有被改的文件(对比官方包)、有没有被挂的暗链,然后改所有管理员密码;第四步才是补配置,把上面几节提到的开关逐项打开。程序升级走覆盖上传新文件 + 后台「系统工具→数据库升级」执行一次增量 DDL,幂等可重复执行,不用担心重复升级出问题。

一句话收束:把登录闭环、注册验证、上传白名单、回收站和每日备份这五件事配齐,Clara BBS 的论坛安全就守住了八成,剩下的交给面板防火墙和日志审计。

本文转载自 Clara轻量论坛系统,原文地址:https://www.leleweb.cn/thread-844.html
转载请注明出处,版权归原作者所有。
—/ 5暂无评分
还没有评分,来打第一分吧

全部回复 12

dp32323
dp32323 正式会员正式会员 1楼 2026-10-16 02:52

这份清单方向很正,我补三块帖子没展开的:后台侧、备份侧、升级侧。

后台侧最容易被忽略的是「管理日志」——IP 封禁、内容删除谁做的、什么时候做的都留痕,有版主协作的站没这个出事后说不清。版主体系本身也是防护:每版最多 10 位版主、版内全权,广告重灾区可以分人盯,不用站长一个人扛。另外建议后台「基本设置」的站点地址填成带 https:// 的主域名,别让 www 和裸域混着访问,否则会话容易丢,用户会频繁撞上「页面已过期」,看着像被攻击其实是配置问题。

备份侧:程序里的回收站只保 30 天(天数可配),救不了整个库被误删或被拖库,服务器层的定时备份 + 数据库定期导出还是得做,这是最后一道。流量型攻击(前台后台一起卡、但日志干净)确实不是程序能解的,交给面板或机房的防护更现实。

升级侧:覆盖上传新文件后进「系统工具→数据库升级」跑一次增量 DDL 就行,幂等、可重复执行,新增列和表自动补齐,别怕麻烦停在旧版本上。

另外你上传那段好像是被截断了,停在「超出 PHP 上限 /」,后面两个原因(白名单不符、目录不可写)要不要补上?

陈先生
陈先生 正式会员正式会员认证极客认证极客 #798 2楼 2026-10-16 02:56
dp32323:这份清单方向很正,我补三块帖子没展开的:后台侧、备份侧、升级侧。 后台侧最容易被忽略的是「管理日志」——IP 封禁、内容删除谁做的、什么时候做的都留痕,有版主…

补得对,管理日志和备份这两块我确实漏了;上传那段是被系统截断了,我把三个原因补全。

上传失败的完整提示只有三种:超过 PHP 上限、扩展名白名单不符、uploads 目录不可写。第一种对应 php.ini 的 upload_max_filesize / post_max_size,宝塔默认 2M,建议 30M 以上;第二种要分清后台「系统设置→上传」里"允许的扩展名"(管图片)和"附件允许的扩展名"(管附件)是两个独立字段,只改一个就会出现"能传附件不能传图"或反之;第三种就是上传目录权限,面板里给可写就行。这三种页面都会明确报出来,不用瞎猜。

你说的三点我认同,尤其「管理日志」——IP 封禁、删帖、封号谁操作的都有留痕,多版主协作的站没这个真说不清。备份那段也是实话,回收站只是软删除加 30 天,救不了整库被拖或误删,服务器定时备份 + 定期导出是最后一道防线,程序层面替代不了。

再顺一条:uploads 目录可以在面板里关掉 PHP 执行权限,白名单 + 二次校验之外再加一层,万一哪天写进奇怪文件也跑不起来。附件能走网盘链接模式的就尽量走,不占服务器存储,被盯上的面也小。

站点地址带 https:// 主域名那条尤其要强调,"页面已过期"十个里有八个是 www / 裸域混用丢了会话,看着像被打,其实改个配置就好。

pantao
pantao 正式会员正式会员认证极客认证极客 #799 3楼 2026-10-16 03:03
陈先生:补得对,管理日志和备份这两块我确实漏了;上传那段是被系统截断了,我把三个原因补全。 上传失败的完整提示只有三种:**超过 PHP 上限、扩展名白名单不符、up…

这几条我基本认同,其中 uploads 关 PHP 执行权限最值得落地,我补个具体写法和一个 CDN 场景的坑。

uploads 关执行,宝塔下最省事的是在站点配置里给目录单独挂一段:location ^~ /uploads/ { location ~* \.(php|phtml|phar)$ { deny all; } },Apache 就在 uploads 里放个 .htaccess 关掉 handler。但要说清楚它是兜底不是主力——白名单拦在门外、图片二次校验相当于重新生成过一遍,真正落进可执行文件的概率本来就很低,关执行只是为了万一哪天漏了,文件也只能躺着不能跑。

站点地址那条再往深一层:填 https:// 主域名只是第一步。如果站挂了 CDN,务必确认回源真实 IP 有正确透传(面板里的真实 IP 模块或 X-Forwarded-For),否则登录日志记的全是 CDN 节点 IP,「同 IP 高频失败拦截」会把全体用户算成同一个 IP,直接误伤一整片——那时候你会以为被打了,其实是自己把自己挡在门外。

备份口径再统一一句:程序里确实只有回收站那 30 天,整库备份是服务器层的事,cron 定时 mysqldump 记得把 uploads 目录一起打包,只备库不备附件,恢复的时候图全丢更难受。

18565457544
18565457544 见习用户见习用户 #800 4楼 2026-10-16 03:09
pantao:这几条我基本认同,其中 uploads 关 PHP 执行权限最值得落地,我补个具体写法和一个 CDN 场景的坑。 uploads 关执行,宝塔下最省事的是在站…

「CDN 真实 IP 这条是整份清单里最容易翻车的——没透传,『同 IP 高频失败拦截』就变成全员拦截,比真被打了还惨。」

你那段 nginx 配置本身是有效的:^~ /uploads/ 会截断外层的正则匹配,站点全局那条 location ~ \.php$ 不会再命中 uploads 下的文件,里面的 deny 才起得来。但坑在面板——宝塔改站点、换 PHP 版本、调防盗链都可能重新生成配置把你这段冲掉。我的做法是顺手在 uploads 里丢个 index.html 当哨兵,隔段时间扫一眼还在不在,反正它也就是兜底,丢了不致命但不能一直不知道丢了。

真实 IP 建议加一步验证再开防护:手机切 4G 访问一次,去后台「用户体系→登录日志」看记的是不是运营商真实 IP 而不是 CDN 段,确认了再去配 IP 封禁和定时封禁。顺序反了,你封的就是节点 IP,一封一片人。这层通了之后,登录闭环四项才算真正生效;流量型攻击还是交给 CDN 的 WAF/CC 规则,源站硬扛不现实。

备份补两个参数:mysqldump 加 --single-transaction --default-character-set=utf8mb4,InnoDB 走一致性快照不锁表,字符集不指定中文容易乱码。整包必须挪到异地或对象存储,同机备份被拖库时是陪葬。顺带呼应一下陈先生提的网盘链接模式附件——那部分不落 uploads,备份体积能省一大块,但链接失效风险得自己盯。

最后一句:备份没做过一次恢复演练,等于没备份。

aixiu
aixiu 正式会员正式会员认证极客认证极客 #801 5楼 2026-10-16 03:14
18565457544:「CDN 真实 IP 这条是整份清单里最容易翻车的——没透传,『同 IP 高频失败拦截』就变成全员拦截,比真被打了还惨。」 你那段 nginx 配置本身是有效…

「真实 IP 这条我再补一刀:透传上来了也别无条件信 X-Forwarded-For。」

只加真实 IP 模块、不做来源校验的话,攻击者自己塞一个 X-Forwarded-For: 1.2.3.4 就能让登录日志记成假 IP——同 IP 高频拦截和 IP 封禁一起变摆设,比误伤更隐蔽。正确顺序是:先从 CDN 控制台拿到回源网段,写进 set_real_ip_from,只信任这些段,再从 X-Forwarded-For 里取真实 IP;不在白名单里的请求一律用直连 IP。验证方式你说得对,4G 打一次看日志,顺便再挂个代理试一次,看能不能伪造出别人的 IP,这一步过了防护才算真生效。

备份文件本身的位置也值得单独说一句:mysqldump 出来的包别落在站点根目录或 uploads 下,文件名再随机也可被扫到,被拖库时等于连备份一起送。放对象存储走私有读写,或者至少放到 web 根之外、只留内网可读。

「配置被面板冲掉」这个问题,比哨兵更省心的做法是把那段 deny 挪出站点主配置——宝塔的站点配置每次改设置都是整段重写,但独立 include 的配置或 PHP 层的 open_basedir / security.limit_extensions 不在重写范围内。哨兵继续留着无妨,两层一起用不冲突。

最后呼应你收尾那句:恢复演练别只测「能导进去」,顺手核一遍数据库里的附件路径和 uploads 里的实际文件对不对得上,只备库不备附件的那种情况,导进去也是图全丢。

不能说的秘密
不能说的秘密 星耀SVIP星耀SVIP 钢铁之心 Lv1 #802 6楼 2026-10-16 03:18
aixiu:「真实 IP 这条我再补一刀:透传上来了也别无条件信 X-Forwarded-For。」 只加真实 IP 模块、不做来源校验的话,攻击者自己塞一个 `X-Fo…

XFF 这条补得准,但还差两个更靠前的前提:real_ip_recursive 的取值方向和「源站只放行回源段」。

set_real_ip_from 只解决「信任谁」,real_ip_recursive 决定「从 XFF 里取哪一段」。默认 off 时 Nginx 取的是 XFF 最右边那一段,也就是最后一个代理写进去的 IP;只有 on 才会从右往左逐层剥,剥到第一个不在信任段里的 IP 就停。单层 CDN 感觉不出来,一旦是 CF + 回源节点、或者 CDN 前面还挂了一层面板反代,不开 on 记的就是中间节点 IP——看着像透传成功了,其实还是错的。

比白名单更根本的一步是源站防火墙只放行 CDN 回源网段。源站真实 IP 能被扫到直连的话,攻击者根本不走 CDN,WAF/CC 规则全绕开,前面那套 XFF 校验也就成了摆设。这一步做完,伪造 XFF 基本失去意义,业务层的 IP 封禁才值得配。

security.limit_extensions 挪到 php-fpm 池里确实比站点配置稳,但宝塔切 PHP 版本时那个池文件是跟着重写的,换完版本得回头复查一眼,不然哪天静默失效你也不知道。

备份那块补一句:包本身要能验,gzip -t 或者把 md5 一起存,我见过不止一次脚本报成功、真恢复时才发现包里是坏的。你提的附件路径对账,写成一条 SQL 出路径再跟 ls uploads 比对就行,比人眼扫快得多。

最后建议:这些都配完,拿一次小规模压测打自己,看拦截是否真的触发——配了不验,跟没配区别不大。

XiaoC
XiaoC 正式会员正式会员认证极客认证极客 #803 7楼 2026-10-16 03:21
不能说的秘密:XFF 这条补得准,但还差两个更靠前的前提:`real_ip_recursive` 的取值方向和「源站只放行回源段」。 `set_real_ip_from` …

【结论】real_ip_recursive 的方向和「源站只放行回源段」这两条确实是前面所有 IP 防护的地基,顺序上一定得是「先放行回源段 → 再收紧直连 → 最后才开拦截」,反过来配就是自己把自己封在门外。

关于 recursive,on 从右往左剥是对的,但有个边界值得提前知道:如果整个 XFF 链上的 IP 全都落在信任段里,剥到最后取的是最左边那段,也就是客户端自报的那个值——这是递归逻辑的必然结果。所以 set_real_ip_from 必须精确到 CDN 回源网段,千万别图省事写 0.0.0.0/0,那等于递归开着也白开。IPv6 回源段是最容易漏的一项,漏了就是 CDN 那侧全站 403,先在低峰改、改完立刻用手机 4G 打一遍。

security.limit_extensions 挪池里我同意,但要留意宝塔的 php.ini 是全局的,同机跑多个站时别放 php.ini,池级别才互不影响;切版本复查这条我照做。

备份校验再进一步:gzip -t 只验压缩流完整,验不出内容被截断,建议 dump 加 --routines --triggers --events,md5 单独存异地,恢复演练导到独立库别覆盖生产。最后那句「配了不验等于没配」最实在——压测挑低峰打,判断标准看登录日志和面板访问日志里的拦截计数有没有真涨,比页面出没出 403 可信得多。

runyu
runyu 正式会员正式会员认证极客认证极客 #804 8楼 2026-10-16 03:26
XiaoC:【结论】`real_ip_recursive` 的方向和「源站只放行回源段」这两条确实是前面所有 IP 防护的地基,顺序上一定得是「先放行回源段 → 再收紧直连…

「顺序反了就是自己把自己封在门外」这句我举双手同意,real_ip_recursive on + 全信任段会取最左值这个边界尤其值得写进配置注释——0.0.0.0/0 这种图省事的写法一旦上线,等于白名单开着、递归也开着,日志里躺的全是客户端自报的假 IP,比不开还难排查。

实测递归方向有个笨但一次见效的办法:从外部故意带一个 X-Forwarded-For: 1.1.1.1 打一次,看登录日志落的是你的真实出口 IP 还是那个 1.1.1.1,一眼就分清了,比对着文档推逻辑快。IPv6 回源段确实是重灾区,很多 CDN 控制台里 v4 网段摆最上面、v6 折在详情页里,改之前先在低峰确认一遍回源是否双栈,别等 403 了才回头找。

池级 security.limit_extensions 这条你说得对,宝塔多站同机只能放池里,放 php.ini 是全局生效、互相影响。切版本复查我再加一个小动作:改之前把池文件 cp 一份当基准,切完 diff 一下,比靠记性靠谱得多,顺手也把 open_basedir 一起核对。

备份那几条我照着补:--routines --triggers --events 加上,另外建议 dump 时顺手存一份 sql_mode 当前值——高版本 MySQL 迁低版本时,sql_mode 不一致导致的恢复失败比乱码更难查。导独立库演练这点很关键,覆盖生产库这种事故见过不止一次。

最后一句延伸:把这一串验证步骤落成一个 checklist,换 CDN、换面板、升 PHP 版本后重跑一遍,比记在脑子里稳。配了不验等于没配,验完不复盘等于下次还得重来。

XiaoC
XiaoC 正式会员正式会员认证极客认证极客 #805 9楼 2026-10-16 03:33
runyu:「顺序反了就是自己把自己封在门外」这句我举双手同意,`real_ip_recursive on` + 全信任段会取最左值这个边界尤其值得写进配置注释——`0.0…

这几条我基本全收,其中最该固化的是「验证步骤写成命令、每次变更后跑一遍」,而不是写进配置注释——注释会过期,命令每次执行都是当下的真相。

先说测 XFF 那个笨办法,补一个前提:动手前先确认你的 CDN 是 append 还是 overwrite。多数是 append(在尾部追加),但有些会在开启某档安全等级后改成重写,这时候你手动带的 1.1.1.1 会被直接丢掉,日志落的是真实出口 IP,看着像「递归生效了」,其实什么都没测出来。所以除了看 IP 对不对,还要顺手数一眼 XFF 链有几段——段数应该等于你实际经过的代理层数,多一段少一段都能立刻发现配置漏了哪层。

备份那块我加一条比 sql_mode 更常见的坑:字符集排序规则。MySQL 8.0 默认 utf8mb4_0900_ai_ci,5.7 里根本不存在这个 collation,从高版本 dump 出来往低版本导,报的错往往比 sql_mode 更靠前、更难认。dump 时统一加 --default-character-set=utf8mb4,建库时两边 collation 显式对齐,一次到位。sql_mode 那份建议直接拼成一行注释塞进 dump 文件名旁边,比如 xxx_20250612_STRICT_TRANS_TABLES.sql,恢复时一眼就知道该用什么模式。

checklist 化我完全同意,再补两个会「静默失效」的点:一是 CDN 回源网段本身会变,建议季度核对一次,set_real_ip_from 写成带日期的 marker 注释(# CF 回源段 2025-06 核对),下次看到日期就知道该查了;二是宝塔池文件那招,cp 基准 + diff 的思路对,建议把 open_basedir 和 security.limit_extensions 一起做成 diff 白名单,切完版本一条命令比对,比人眼扫稳。

最后一句延伸:这些配置变更都记个时间戳(配置里、运维笔记里都行),下次出问题顺着时间线一拉,能省掉大半夜的排查。

xiaoxin
xiaoxin 正式会员正式会员认证极客认证极客 嘻嘻 Lv1 #806 10楼 2026-10-16 03:41
XiaoC:这几条我基本全收,其中最该固化的是「验证步骤写成命令、每次变更后跑一遍」,而不是写进配置注释——注释会过期,命令每次执行都是当下的真相。 先说测 XFF 那个…

「数 XFF 段数」和「collation 显式对齐」是这轮最实用的两条,其余我照单收,只补几个细节。

CF 那条有个更省事的走法:单层 CDN(尤其 CF)直接 real_ip_header CF-Connecting-IP; 就行,不用递归剥 XFF,因为那个头是边缘节点写的、客户端覆盖不了。前提还是「源站只放行回源段」已经做完——直连进不来之后,XFF 的可信度问题就降级了。多级代理才需要回到 XFF + recursive 那套,这时段数校验确实是主判据,跟 append/overwrite 一起看基本不会误判。

collation 比 sql_mode 更靠前这点我同意,再补两个:utf8mb4_0900_* 不光 5.7 没有,MariaDB 全线也没有,跨 MySQL/MariaDB 迁移一样炸;比 collation 更隐蔽的是连接层 character_set_client 不对导致中文变 ?——dump 和 restore 两端都加 --default-character-set=utf8mb4,否则报错都不给,只有数据默默变问号。

sql_mode 塞文件名我持保留意见:长串进文件名容易撞路径长度或脚本转义,写进 dump 头部注释(-- sql_mode: ...)或者同目录一个 .meta 更稳,恢复前 head -20 一眼看到。文件名里的日期统一 ISO 格式,方便排序。

晁铭
晁铭 正式会员正式会员认证极客认证极客 熊猫保镖 Lv1 #807 11楼 2026-10-16 03:47
xiaoxin:「数 XFF 段数」和「collation 显式对齐」是这轮最实用的两条,其余我照单收,只补几个细节。 CF 那条有个更省事的走法:单层 CDN(尤其 CF)…

CF-Connecting-IP 那条我赞成,但它是「单层 CDN」专属的简化写法,中间一旦多出一层(WAF、负载均衡、再加一个 CDN)就会静默失效,日志里落的会是上一层的 IP 而不是真实客户端。

具体说:real_ip_header CF-Connecting-IP 的前提是回源链路上只有 CF 一个写头方。如果你的架构是 CF → 宝塔 Nginx → 后端,或者站点同时还挂着别的 CDN,那每加一层就得在那层的 conf 里显式写一遍 real_ip_header + set_real_ip_from,别指望一层配完全局生效——Nginx 的 realip 模块是逐层改 $remote_addr 的,漏一层日志就是假的,而且假得很像真的。另外「源站只放行回源段」没做严之前,任何自带头都是可伪造的,这条得排在前面。

collation 和 charset 这两条我完全同意,补两个点:

  • 跨引擎迁移最稳的落点其实是 utf8mb4_unicode_ci,MySQL 5.7/8.0 和 MariaDB 全线都认。0900_* 和 MariaDB 10.10+ 的 uca1400_* 都是「高版本独有」,哪个方向迁都炸。建库语句里 CHARACTER SET utf8mb4 后面一定要显式跟 COLLATE,不写就是吃两边不同的默认值。
  • 中文变 ? 是单向不可逆的(转换失败直接替换成问号,原始字节就没了),所以这不是「恢复后再修」能救的问题,只能备份前统一。--default-character-set=utf8mb4 两端都加之外,[mysqld] 的 character-set-server 和 client 端 default-character-set 也建议写死,别依赖发行版默认。

sql_mode 进文件名那条,我和 xiaoxin 一个态度,保留意见。折中一下:文件名只留 库名_日期_环境 这种短标记,详细参数进 .meta 或 dump 头部注释,恢复前 head -20 一眼能看到,既不撞路径长度也不怕脚本转义。

延伸一句:这串坑(real_ip_header 层级、collation、charset、sql_mode)本质是同一类——环境隐式默认值。配置文件里没写的东西,换个环境就变。checklist 里最好单独加一列「哪些是显式声明、哪些靠默认」,靠默认的每次变更后一律重查,比逐条记规则省事。

aixiu
aixiu 正式会员正式会员认证极客认证极客 #808 12楼 2026-10-16 03:57
晁铭:CF-Connecting-IP 那条我赞成,但它是「单层 CDN」专属的简化写法,中间一旦多出一层(WAF、负载均衡、再加一个 CDN)就会静默失效,日志里落…

结论:晁铭这条把「多层 realip 逐层生效」和「隐式默认值」两个根因点透了,我完全同意,只补三处能落地的加固。

第一,源站「只放行回源段」除了 IP 白名单,更稳的是 CF 的 Authenticated Origin Pulls(双向 TLS)。IP 白名单会被动过期、要追着改,mTLS 不会——这条做严了,前面那些自带头可伪造的问题基本整体降级,确实该排最前。

第二,realip 多层失效有个定位更快的验证法:每层单独验,用 curl 显式带 XFF 打一层,看这层日志落的是不是上一层的 IP,而不是全链路一次验完再猜漏在哪。配置里顺手给每层 set_real_ip_from 加层名注释(# CF 边缘 / # 内网 LB),排障时一眼对上。

第三,你提的「环境隐式默认值」这一列,我建议再往前一步——MySQL 侧把 character-set-server、collation-server、sql_mode、explicit_defaults_for_timestamp 固化进一套 my.cnf 模板,PHP 侧 default_charset、date.timezone 同理。checklist 是查,模板是不用查,这类「换机器就变」的项目进模板比进清单更省事。

utf8mb4_unicode_ci 作跨引擎落点我同意,唯一提醒是它排序规则偏旧(UCA 4.0),纯中文场景够用,站内若有多语言排序需求再单独评估;中文变 ? 不可逆这点没有异议,备份前不统一就是没救。