ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

梦幻防红COS系统部署教程:从LNMP环境到域名白名单实战

梦幻防红COS系统部署教程:从LNMP环境到域名白名单实战 简介梦幻防红cos系统带后台版无加密是一款面向网站运营者与个人站长的防DDoS攻击防红工具支持在后台自定义防红接口无需理解复杂防护技术即可完成配置尤其适合流量大、易被攻击的站点。资源共82个文件以64个png界面素材、8个css与7个php程序文件为主另含js与配置及说明文本压缩包仅624KB通过install.php即可解压安装若遇环境不兼容切换php7.0版本即可解决。系统后台地址为“域名admin.php”可便捷管理防红接口配套完整前端资源与安装说明解压即用且无加密可帮助中小站长快速搭建基础防护避免因“红”攻击导致服务中断其后台设计简洁直观技术经验有限的运营者也能轻松上手。目前已有110人学习下载适合希望低成本、轻量部署防红方案的网站管理者。1. 梦幻防红cos系统是什么一个让游戏素材页在微信里少被拦的后台“梦幻防红cos系统带后台版无加密”听起来像源码站的打包标题拆开看其实就是三件事梦幻类游戏素材站、角色外观COS展示页、以及一套“域名防红”跳转机制最后再加一个可视化管理后台。它解决的是游戏工具站和活动落地页最头疼的问题——访客从微信、QQ里点链接页面直接变成“已停止访问”的红色拦截页人还没看到内容就流失了。这个系统会先判断访客用的是什么浏览器环境微信内置浏览器就输出一个引导页让访客复制链接去外部浏览器打开普通浏览器就直接放行到COS展示页。后台负责管理域名、白名单、跳转延时、模板和访问日志。适合跑游戏素材站、做活动页、频繁换域名的人无加密意味着源码明文改逻辑、加功能都没人拦你。2. 部署前的选型LNMP环境、无加密源码与数据库表结构怎么定拿到这类系统第一件事不是急着上传代码而是先把运行环境定下来。常见做法是宝塔面板加LNMPPHP用7.4而不是8.xMySQL用5.7。原因很现实很多无加密老代码是从ThinkPHP或原生PHP 5时代改过来的用了mysql_*系列函数或者老语法PHP 8直接白屏报错你连错在哪都看不出来。PHP 7.4对老代码的兼容性最好同时又支持现代语法踩坑最少。2.1 服务器环境PHP版本与伪静态的取舍部署时我用的是Nginx PHP 7.4 MySQL 5.7。PHP版本这个参数看起来不起眼实际是这套系统能不能跑起来的第一个分水岭。你用php -v看一眼当前版本如果已经是8.2建议直接卸载重装7.4别指望代码作者已经适配过新版本。# 伪静态规则适用于大多数原生PHP/ThinkPHP结构 location / { if (!-e $request_filename) { rewrite ^/(.*)$ /index.php?s$1 last; } } location ~ \.php$ { fastcgi_pass unix:/tmp/php-cgi-74.sock; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; }这段配置里有几个参数要注意。if (!-e $request_filename)的意思是只有请求的文件或目录不存在时才走重写这么做能避免把真实的CSS、JS、图片路径也吞进index.php。fastcgi_pass后面要对着你PHP 7.4实际生成的socket文件每个PHP版本的socket路径可能都不一样写错了就是502。伪静态决定了后台里的链接能不能用“/entry/1.html”这种形式访问如果这一层没通防红规则里的URL全得改成带问号的动态地址体验会差很多。2.2 无加密源码的初始化改配置、导数据库、提权限无加密的意思是源码里所有PHP文件都是明文你直接用编辑器打开就能看逻辑。好处是改起来没障碍坏处是系统里原来的默认密码、数据库连接串一眼就能被看到上传前必须全部改掉。# 解压并移动到网站目录 unzip menghuan_cos_system_novip.zip -d /www/wwwroot/ mv /www/wwwroot/menghuan_cos_system_novip /www/wwwroot/cos_system # 语法检查先把有语法错的PHP文件揪出来 find /www/wwwroot/cos_system -name *.php -exec php -l {} \; # 给runtime和upload目录写入权限日志和模板缓存才写得进去 chown -R www:www /www/wwwroot/cos_system chmod -R 755 /www/wwwroot/cos_system/runtime chmod -R 755 /www/wwwroot/cos_system/upload # 让后台的定时清理脚本在后台跑SSH断开也不被杀掉 nohup php /www/wwwroot/cos_system/cron.php /tmp/cos_cron.log 21 php -l是PHP的语法检查命令不加这个直接部署访问某个页面时才会突然白屏。chown www:www很关键PHP-FPM默认以www用户运行如果目录属于root后台的日志和模板缓存会写不进去表现就是后台一切正常但日志永远是空的。最后一句nohup ... 是把清理脚本放到后台守护这类系统跑久了日志表会膨胀需要定期清理没这一步你可能要自己记着每天手动删表。2.3 数据库表结构防红规则、链接、日志、管理员分开建初始化完环境后要导入数据库。很多源码包里带一个install.sql直接用命令行导入就行导入后要自己确认四类核心表存在。我见过不少系统把所有内容塞进一张表结果规则多了之后查询越来越慢所以表结构建议按职责拆开。表名职责核心字段sys_links存放COS展示页链接id, target_url, template_id, status, create_timesys_rules防红规则id, rule_name, match_keyword, whitelist, target_type, sort_ordersys_logs访问与拦截日志id, link_id, browser_type, ip, ua, referer, created_atsys_admin后台管理员id, username, password_hash, login_fail_count, lock_until设计上的关键点在于sys_rules要支持多种匹配方式不能只存一个“是不是微信”。规则表里至少要有精确匹配、前缀匹配、正则匹配三种类型这样才能做到“某些链接在微信内直接放行另一些必须走引导页”。sort_order是规则的生效优先级数字小的先执行这个字段决定了防红逻辑是先放行还是先拦截。日志表里browser_type单独拎出来建索引后台统计页要按它做分组查询没索引的话数据过万就开始卡。导入SQL时还要注意字符集。命令行导入默认可能是latin1中文全变问号。我一般会在导入前先执行SET NAMES utf8mb4;导入后用mysql SHOW CREATE TABLE sys_links;确认表的默认字符集是utf8mb4。字符集不一致的后果是后台精心配置的引导文案显示成乱码而且很难排查。3. 后台管理的核心落点域名白名单、COS页面模板、访问日志怎么配部署只是把骨架立起来真正让这套系统按你意愿工作的是后台配置。入口通常在/admin路径登录后第一眼看到的应该是仪表盘今日访问、今日拦截、放行率、以及最近几笔拦截记录。很多无加密系统的后台长得像十年前的PHP后台这很正常别急着嫌弃——重点看它能配什么。3.1 域名白名单与生效顺序先精确后模糊的规则设计后台里最重要的模块就是防红规则。理解它有个前提防红不是把所有访问都拦截而是只拦截“从微信等内置浏览器进来的、访问了被判定为危险链接的”访客。所以规则要能精确区分比如你有一个COS展示页里面含敏感词被微信误伤过那这条链接就要走引导页但同域名下的其他页面比如网站首页在微信里直接打开毫无问题那就要放行。-- 查询当前链接应该命中的规则按优先级排序 SELECT rule_name, match_keyword, target_type, whitelist FROM sys_rules WHERE status 1 AND ( match_keyword /cos/detail/101 OR LEFT(/cos/detail/101, CHAR_LENGTH(match_keyword)) match_keyword OR /cos/detail/101 REGEXP match_pattern ) ORDER BY sort_order ASC LIMIT 1;这条SQL把三种匹配方式都考虑进去了精确匹配整条路径、前缀匹配、正则匹配。排序后取第一条就是最终要执行的规则。注意safe_red这个字段在前端表现为一个开关“该规则是否启用白名单直放”启用后命中的链接不做任何判断直接302到目标地址。我一般建议把首页和后台地址都加进精确白名单里这两类地址不需要防红否则用户在微信里打开你的后台也会被拦到引导页去自己把自己绊倒。3.2 COS页面模板占位符替换与外部依赖本地化模板管理决定了访客最终看到的长什么样。这类系统的COS模板一般放在templates/目录下每个模板一个HTML文件里面用{target_url}、{site_name}、{thanks_word}这类占位符标注动态内容。后台编辑模板时实际上是在改这些HTML文件保存后PHP会做占位符替换然后把页面返回给访客。!DOCTYPE html html langzh-CN head meta charsetUTF-8 title{site_name} - 页面访问提示/title meta nameviewport contentwidthdevice-width, initial-scale1.0 style body { font-family: -apple-system, PingFang SC, sans-serif; text-align: center; padding: 40px 16px; } .btn { display: inline-block; padding: 12px 28px; border-radius: 8px; background: #4a90d9; color: #fff; text-decoration: none; } .link-box { width: 80%; margin: 16px auto; padding: 8px; border: 1px dashed #999; word-break: break-all; } /style /head body h1请在浏览器中打开/h1 p当前页面无法直接访问请复制下方链接到手机浏览器打开/p div classlink-box{target_url}/div button classbtn onclickcopyLink()复制链接/button script function copyLink() { var box document.querySelector(.link-box); var range document.createRange(); range.selectNode(box); window.getSelection().removeAllRanges(); window.getSelection().addRange(range); document.execCommand(copy); alert(链接已复制请到浏览器打开); } /script /body /html模板里我刻意用了document.execCommand(copy)而不是navigator.clipboard.writeText()因为微信内置浏览器的clipboard权限限制很严新版API在非https页面上经常静默失败老API反而稳定。{target_url}替换出来的字符串一定要做htmlspecialchars转义否则链接里带了参数时会被解析成HTML实体访客复制出来的链接是坏的这是模板配置里最容易忽视的一点。另外模板里的CSS和JS必须全部本地化不要外链CDN或静态资源微信对第三方域名的静态资源拦截率很高一个外链script就能让整个模板失效。3.3 后台数据统计按来源、按浏览器、按时段看拦截率日志统计这块是很多人装上系统后就不管的部分却是调优的依据。后台一般都有“访问统计”页按日期展示PV、拦截次数和放行次数。我习惯每天看两个数微信内的拦截占比以及普通浏览器误拦占比。前者决定了防红策略值不值后者决定了误杀有多严重。-- 统计各浏览器环境的访问量以及拦截占比 SELECT browser_type, COUNT(*) AS total_visits, SUM(is_blocked) AS blocked_count, ROUND(SUM(is_blocked) / COUNT(*) * 100, 2) AS block_rate FROM sys_logs WHERE created_at DATE_SUB(NOW(), INTERVAL 7 DAY) GROUP BY browser_type ORDER BY total_visits DESC;如果block_rate在wechat和qq这两行是100%说明只要是从微信和QQ点进来的人全部被你拦截了一个都没放行。这种情况要回头检查是不是规则写得太宽——比如match_keyword留空导致所有链接都命中。正常情况下微信内置浏览器的拦截率应该远低于100%因为有一部分访客是从朋友圈分享点进来的老用户他们的打开方式已经在浏览器里不需要再拦一次。多看几天的趋势再改规则别刚上线两小时看到拦截数据高就急着调白名单样本量不够的判断全是玄学。4. 防红跳转的代码级实现UA识别、白名单、延时跳转与记录后台配置再多最终都要落到底层防红逻辑上。无加密系统的优势这时候就体现出来了你可以打开核心PHP文件逐行看它到底怎么判断、怎么跳、怎么记录。这不是为了改源码而看源码而是为了精准控制跳转行为。你要知道UA识别在哪里写的、白名单优先级在哪里生效、日志在哪里落库出了奇怪问题才能快速定位。4.1 核心判断逻辑用PHP识别微信、QQ与抖音内置浏览器防红的第一步是识别访客浏览器环境。原理很简单每个内置浏览器在请求头里的User-Agent字符串都带有自己的特征词。微信带MicroMessengerQQ浏览器带QQ/抖音带aweme支付宝带AliApp。判断逻辑就是把这些关键词逐个匹配一遍。?php // anti_red.php 核心判断模块 function detect_browser(string $ua): string { $ua strtolower($ua); $marks [ wechat micromessenger, // 微信内置浏览器特征 qq qq/, // QQ内置浏览器特征 tiktok aweme, // 抖音内置浏览器特征 alipay aliapp, // 支付宝内置浏览器特征 ]; foreach ($marks as $browser $mark) { if (strpos($ua, $mark) ! false) { return $browser; } } return normal; } // 使用示例入口文件调用 $ua $_SERVER[HTTP_USER_AGENT] ?? ; $device detect_browser($ua);这段代码里的关键词不能写错大小写因为我统一strtolower了所以匹配串也得全小写。注意qq的写法是 qq/前面有个空格因为很多安卓手机的UA里会包含xxxqq这种单词不带空格会把“三无设备”也识别成QQ内置浏览器误伤率很高。抖音的aweme是抖音App的包名特征出现在UA的末尾只要是抖音扫码进来的都能命中。支付宝场景也值得保留很多游戏素材站的支付跳转页在支付宝里打开如果支付宝内被限制也要走引导逻辑。4.2 跳转策略meta refresh、JS跳转与302并行处理判断出浏览器类型后接下来的问题是“怎么跳”。正常浏览器直接302到目标页内置浏览器输出引导页。这里有个细节引导页本身也可以尝试直接跳转但要以一种不会导致死循环的方式跳。我见过不少系统在引导页里也写了一个自动跳转的meta refresh结果用户在微信里打开引导页试图跳回目标页目标页又判断UA是微信又跳回引导页循环到浏览器报错。?php // 入口判断后的跳转处理 if ($device normal) { // 普通浏览器直接放行302不缓存 header(Location: . $target_url, true, 302); exit; } // 内置浏览器先检查是否命中白名单 $allow_direct check_whitelist($link_id, $device, $ua); if ($allow_direct) { header(Location: . $target_url, true, 302); exit; } // 未命中白名单输出引导页 $tpl file_get_contents(APP_PATH . templates/ . $template_file); $tpl str_replace({target_url}, htmlspecialchars($target_url), $tpl); $tpl str_replace({site_name}, $site_name, $tpl); echo $tpl; exit;逻辑顺序是先判断设备再查白名单最后决定是302还是输出引导页。注意302在PHP里要带302状态码不要默认用303或307部分老版本安卓WebView对307处理有问题。引导页里如果放了自动跳转代码就要加一个超过5秒的延时并且跳转目标不能是原地址而是引导页自身的某个静态资源否则又套回死循环。4.3 日志落库访问记录里到底该存哪些字段防红系统最怕的不是拦截不了而是不知道拦了什么。日志落库的作用就是让每次判断都有据可查。在输出响应之前先把当前请求的关键信息写入sys_logs。日志表字段有限但每个字段都有用途?php // 日志记录模块 $log_data [ link_id $link_id, browser_type $device, ip ip2long($_SERVER[REMOTE_ADDR] ?? 0.0.0.0), ua mb_substr($ua, 0, 255), referer mb_substr($_SERVER[HTTP_REFERER] ?? , 0, 255), is_blocked $allow_direct || $device normal ? 0 : 1, created_at date(Y-m-d H:i:s), ];ip字段我用ip2long转成整数存储比直接存字符串省空间。但要注意ip2long对IPv6地址返回false如果服务器同时有IPv6访客就要在写入前做判断否则日志里会出现一堆0。ua和referer都做了长度截断因为UA最长能到几百字节不加限制的话日志表会被超长字符串撑爆。is_blocked这字段是我后来自己加的原来只存了browser_type统计拦截率时还得现算加上之后一条SQL就能出报表。4.4 后台操作日志与登录控制无加密源码的第一道防线无加密源码等于把后台密码的存储方式都公开了如果不改默认密码、不设失败锁定被爆破只是时间问题。后台登录逻辑建议至少做三层第一层是登录时校验验证码第二层是连续失败5次锁定10分钟第三层是后台路径改名。?php // 登录失败锁定逻辑 session_start(); if ($_POST[username] $admin_user password_verify($_POST[password], $admin_hash)) { $_SESSION[is_admin] true; unset($_SESSION[login_fails]); } else { $_SESSION[login_fails] ($_SESSION[login_fails] ?? 0) 1; if ($_SESSION[login_fails] 5) { $_SESSION[lock_until] time() 600; // 锁定10分钟 $fails $_SESSION[login_fails]; $_SESSION[login_fails] 0; // TODO: 此处用SMTP发送告警邮件给站长 } } if (isset($_SESSION[lock_until]) time() $_SESSION[lock_until]) { exit(登录失败次数过多请10分钟后再试); }锁定的实现依赖PHP Session多台服务器负载均衡时Session不共享锁定就会失效但单机部署足够。SMTP告警是值得加的一步用网易企业邮箱或QQ邮箱的SMTP服务把密码爆破的IP和时间发到运维邮箱。这块配置在后台“系统设置”里通常有预留接口只要填上smtp_host、smtp_port、smtp_user、smtp_pass就行。5. 上线后最常踩的5个坑死循环、误拦截、乱码与后台被爆破部署和配置都跑通之后真正的考验才开始。这套系统的坑不在功能逻辑有多复杂而在于它工作在前端环境和平台机制的夹缝里任何一环没考虑周全访客看到的就是白屏、死循环、或者复制不了链接。我按踩坑频率整理了5条每一条都是真实会遇到的。5.1 跳转死循环白名单没带上自己的域名现象访客从微信里打开引导页引导页点击“继续访问”页面又跳回了引导页浏览器提示“太多重定向”。原因引导页里的“继续访问”按钮指向的还是原目标地址而这个地址再次被防红规则命中于是形成了“拦截-引导-跳回-再拦截”的死循环。解决在规则表里加一条高优先级的精确白名单把当前域名下所有引导页相关的路径加进去。检查方法是在手机上用微信打开链接观察浏览器地址栏最终停在哪个URL如果停在引导页反复刷新就是白名单没生效。5.2 微信里打开还是“已停止访问”防红不是解封现象部署完防红系统满怀信心地在微信里测试结果页面照样显示“已停止访问该网页”。原因防红机制只负责把访客引导到外部浏览器打开它不能解除域名在微信侧的封禁状态。你的域名如果已经被举报或者触发风险拦截防红页本身也会被拦。解决换一个新域名作为入口把旧的被封域名作为备用跳转目标。常见做法是在后台配置3到5个备用域名做成一个入口域名池哪个域名健康就用哪个。这是这套系统真正价值所在——不是让域名变红而是让你在域名变红之后能快速切换把流量损失降到最低。5.3 苹果手机复制链接失效剪贴板权限与静态二维码备用现象安卓手机上引导页点“复制链接”能正常弹提示iPhone上点了没反应或者提示复制成功但粘贴时是空的。原因iOS微信对navigator.clipboard权限限制非常严只有在页面获得焦点且由用户主动点击时才能调用而且必须走HTTPS协议。有些系统模板用的是老旧的document.execCommand(copy)但没把复制内容放到选中区域导致iOS上复制到的是空内容。解决复制按钮的点击事件里先创建textarea元素把链接赋值进去选中后再调用execCommand(copy)用完立刻移除。同时在模板里放一个比链接文字稍大的二维码头图让访客长按识别作为复制失败的兜底方案。5.4 后台数据乱码与链接参数丢失字符集和伪静态的双重夹击现象后台添加的中文规则名称变成问号访客点击带utm_sourcewechat参数的COS链接时参数被截断只剩主路径。原因两个问题叠加。乱码是SQL文件导入时字符集没设置成utf8mb4连接数据库时也没指定字符集参数丢失是Nginx伪静态规则写得太激进把?后面的查询字符串给干掉了。解决连接数据库的PHP代码里加一行$pdo-exec(SET NAMES utf8mb4);伪静态规则改成只在文件不存在时才重写。改完后重新测试一下带参链接确认$_GET能取到值才算完。5.5 后台路径被爆破无加密等于给攻击者送了张地图现象后台登录日志里出现大量陌生IP尝试登录用户名是admin密码是常见的123456、admin888。原因无加密系统的源码是公开的任何拿到源码的人都知道后台默认路径是/admin默认密码写死在安装包里。解压源码包的人不需要逆向破解直接照着源码里的密码试就行。解决第一件事就是进数据库把sys_admin表里的密码改成password_hash(你的强密码, PASSWORD_DEFAULT)生成的值。第二件事把后台入口文件从根目录挪到二级目录并改名比如/manage/entry.php然后删掉原来的admin目录。第三件事就是本章前面写的登录失败锁定缺一不可。6. 用真实链路验证防红效果从日志调优到H5后台部署系统跑起来之后用逻辑判断“应该没问题”是完全不够的必须走真实链路验证。验证分两层第一层是模拟请求用curl带不同UA请求入口地址看返回的HTML是否符合预期第二层是真实设备拿安卓和iPhone各一台分别从微信、QQ、普通浏览器扫码打开链接观察跳转路径。# 模拟微信内置浏览器访问入口应返回引导页HTML curl -s -A Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) MicroMessenger/8.0.40 \ https://yourdomain.com/entry/101 | head -30 # 模拟普通浏览器访问同一入口应返回302跳转 curl -s -I -A Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0 \ https://yourdomain.com/entry/101 | grep -E HTTP|Location模拟微信UA那一条返回内容里应该出现请在浏览器中打开的字样模拟正常浏览器那一条响应头里应该有302 Found和Location: 目标链接。如果两条结果跟预期不一致先别急着改代码去后台日志表里查刚才这两条记录看browser_type字段到底识别成了什么往往问题出在UA匹配串上。再往后可以做两件进阶的事。第一件是把COS展示页从静态模板升级成H5应用——现在后台管理系统用Vue3是常态你可以用Vue3把COS展示页写成一个单页应用再用uniapp打包成H5部署到后台目录体验比静态模板好很多。查日志时如果发现普通浏览器的误拦率超过5%多半是UA判断写得太宽把一些国产浏览器的UA里含qq或micro字样的设备也拦了需要逐个加白。第二件是接SMTP异常告警把后台登录锁定、某个链接单日拦截量突增这些事件推送到邮箱不用时刻盯着后台异常会主动找上门。我第一次给朋友搭这种系统时就是没做真机验证直接在电脑上测全部通过结果手机微信里一打开就是死循环前前后后折腾了两轮才白名单调对。现在的习惯是每次改完规则先用curl扫一遍三条链路再拿两台真机各点一遍半小时的事能省下后面一整天的返工。希望帮到你。本文还有配套的精品资源点击获取
返回列表