简介这套迅风DNS Pro V3.1.2二级域名分发系统源码面向域名服务商、主机商及独立站长提供一套完整的域名解析与分发管理方案。通过插件化设计可接入阿里、腾讯、Cloudflare、华为、百度、宝塔等多家DNS平台后台统一管理解析记录、订单、工单和日志并支持支付、VIP、实名认证、违规检测等业务功能。资源包共2000个文件以PHP源码为主搭配JavaScript、CSS、JSON和SQL等配置文件整包11.26MB目录结构清晰便于二次开发与部署。附件附有搭建教程覆盖环境准备、插件安装、数据库迁移及主题切换等环节能帮助读者快速搭建可运营的域名分发平台。目前已有205人学习下载适合具备一定开发基础和域名业务需求的人群。1. 二级域名分发这个场景为什么值得自己搭一套系统做DNS解析服务或者给客户开子站的时候最烦的就是今天建一个解析、明天改一个CNAME全在服务商面板里手工点。二级域名分发就是把「主域名下自动生成子域名并绑定到指定目标」这套动作系统化而迅风DNS Pro V3.1.2正是一份完整可部署的PHP源码自带管理后台和二次开发接口。搭好之后用户可以自己在页面上申请二级域名系统自动写入解析记录并生效整个过程不用你手动碰DNS控制台。适合做域名分发服务的站长、SaaS产品里给租户分配独立域名、以及想统一管理内网解析记录的运维。下面直接讲落地路径。2. 从源码到跑起来迅风DNS Pro的部署环境与初始化配置2.1 环境选型PHP版本、Web服务和解析服务怎么搭先明确范围拿到“迅风DNS Pro V3.1.2系统源码”后你实际要部署的是两层东西。一层是PHP写的管理后台跑在Nginx或Apache上负责用户登录、域名录入、解析记录展示另一层是DNS解析服务端负责接收查询请求并返回你库里的记录。多数同类源码会把解析服务做成独立的PHP/Go进程或者要求你装BIND后对接它的zone文件。V3.1.2这套我见过的部署说明通常是PHP MySQL Nginx 一个解析服务组件。选型上我最常用的组合是PHP 7.4、MySQL 5.7、Nginx 1.20。PHP 8.0不是不行但老代码里高频出没的ereg、each函数在PHP 8里已经移除如果你不想花时间改兼容就锁在7.4。上车先检查三方版本php -v mysql --version nginx -v这段命令没什么好解释的但它能帮你快速排除环境不匹配的翻车。注意如果php -v显示出 8.1 以上而源码说明写明“仅支持 PHP 7.x”不要赌兼容直接装7.4。解析服务端如果带CLI模式还可以执行php think version看框架版本但不同源码入口不同以你解压后的说明文档为准。2.2 解开源码包后的目录辨识与配置文件修改源码解压前先把它放到服务器上处理不建议Windows下解压再zip上传那样权限位和软链接都会变成普通文件后面跑起来会出现一堆“文件不存在”的玄学问题。常见做法是用unzip在服务器端解压mkdir -p /www/wwwroot/dnspro unzip 迅风DNS_Pro_V3.1.2.zip -d /www/wwwroot/dnspro cd /www/wwwroot/dnspro ls -la解压后你通常能看到几个固定角色application是业务逻辑目录public是Web入口目录sql或install.sql是数据库初始化文件docs或README.txt是教程。先改数据库连接配置不要急着改其他文件cp application/config/database.php application/config/database.php.bak vim application/config/database.php配置里必改四个字段hostname默认127.0.0.1、database库名、username和password。另外注意dbprefix如果SQL文件里表名带dns_前缀而配置里这个值留空后台会去查不带前缀的表结果就是登录后列表全空。这一点在避坑那一章还会重点讲。改完保存后用php -l做一下语法检查再进下一步。为什么这套系统要刻意区分web根目录public是唯一能让Nginx直接访问的目录其它目录暴露出去会被扫描到源码路径、配置文件甚至SQL备份。部署时把Nginx的root指向public这样即使别人猜到源码目录也访问不到配置文件。2.3 数据库初始化手动建库导入SQL而不是依赖网页安装器很多搭建教程会直接让你打开域名然后走网页安装向导但网页安装器非常依赖PHP函数的安全设置稍有禁用项就会卡在“写入配置文件”这一步而且装完还会在根目录留一个install目录忘记删的话等于给攻击者开了后门。所以我更习惯手动初始化。mysql -uroot -p -e CREATE DATABASE dnspro DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; mysql -uroot -p dnspro sql/dnspro.sql第一行建库参数DEFAULT CHARACTER SET utf8mb4让库表存储全面支持emoji和生僻字二级域名如果涉及中文转码全靠它兜底。第二行把安装文件里的表结构导入。注意导入前确认SQL文件用的是utf8mb4如果是老项目可能还是utf8国际域名没问题但中文域名或带后缀的解析记录可能会丢数据。导入完成后登陆MySQL检查一下是否生成了表USE dnspro; SHOW TABLES;看到dns_domains、dns_users这类表就对了。表名前缀和配置文件中的dbprefix一致后面API查询才能命中正确的表。这套源码把解析记录落库而不是直接改DNS服务配置是因为二级域名分发天然是一个高并发写场景。当用户自助申请时系统先在库里插入一条状态为“pending”的记录再异步通知解析服务端加载或重载配置查询时解析服务端只在库里找对应子域名。这样分发请求和你底层DNS服务解耦避免每次申请都重启一个zone导致服务抖动。明白了这一层你在设置定时同步任务时就会知道它存在的意义。3. 二级域名分发到底怎么工作解析模板与API下发逻辑3.1 泛解析是让子域名先进来的前提二级域名分发系统并没有“注册域名”的能力它的前提是你的主域名已经在服务商那边完成了泛解析也就是把*.example.com这种通配记录指向这台服务器的IP。这样无论用户申请的子域名有没有在库中DNS查询都会先到达你的服务器再由Web层或解析服务去数据库里匹配。这里有个常见误用很多人只在DNS服务商处加了一条A记录指向IP没加泛解析结果后台创建的user123.example.com在外部DNS上根本查不到。验证方法很简单dig 8.8.8.8 abc123.example.com A short如果你看到返回了你服务器的IP说明泛解析已生效如果返回空或看到NXDOMAIN先去服务商面板检查通配解析。注意TTL不要设太短泛解析记录建议600秒太短会导致外部递归DNS频繁回源太长的话你迁移服务器IP后用户会持续访问旧地址这是一对权衡。生产环境我一般用600~900秒配合API刷新机制已经够用。3.2 解析记录的类型与模板配置泛解析把流量放进来之后系统要决定每个子域名最终指向哪里。二级域名分发最常见的记录类型是A记录和CNAME记录A记录直接指向IPv4地址适合给客户分配独立服务器的场景CNAME指向另一个域名适合让用户绑定自己域名的场景。在这个后台里你通常需要在“域名模板”里预设好默认记录类型再在分发填表时让用户选。比如你打算给每个SaaS租户分配一个租户ID.saas.example.com并且该子域名需要经过CDN那么模板就选CNAME目标值填CDN分配的别名。如果目标是用户自己的服务器IP就选A记录。系统写入数据库的记录字段一般是子域前缀、记录类型、目标值、TTL、状态。INSERT INTO dns_domains (prefix, record_type, target, ttl, status) VALUES (user123, A, 203.0.113.10, 600, active);这条SQL不是一个固定的源码操作但它是这套系统数据库层最核心的动作把用户申请变成一条可查询的解析记录。注意prefix不要写成user123.example.com的完整域名系统在生成最终域名时会自动拼接主域名否则会产生user123.example.com.example.com的双后缀错误。入库时也建议对prefix做正则校验只允许小写字母、数字和连字符这是二级域名命名的硬约束。3.3 把API开放出来让分发过程可编程如果每次申请二级域名都要登录后台点一次那还是手工挡不住。迅风DNS Pro V3.1.2这类源码通常会在后台提供一个API配置页面生成一个专属密钥用外部系统带着密钥调用接口来创建和删除解析记录。拿到源码后先去后台找到“API密钥”设置生成一个新的key并保存。然后先拿curl做通联测试API_KEY这里填你后台生成的密钥 curl -sS -X POST https://dns.example.com/api/v1/domain/create \ -H X-API-Key: $API_KEY \ -d prefixuser123record_typeAtarget203.0.113.10ttl600接口地址不一定就长这样不同版本的后台路由名称有差别但通用的鉴权方式是Header里带密钥。返回的JSON里code为0或200表示成功msg是错误说明data里会带着新创建的域名比如user123.example.com。参数里prefix是子域前缀record_type是解析类型target是目标地址ttl是解析缓存寿命。调试期有几个细节要盯紧第一密钥不要明文打印在日志里curl测试时用变量替代线上代码里从配置文件读取第二API一旦创建成功是立即生效还是写入待处理队列要看源码实现如果它不是即时同步到解析服务就需要第五章说的定时任务去触发第三有的版本会在API入口做IP白名单你本地curl时先用本机出口IP试通不通就去查白名单配置这一步是新手最容易卡的。4. 迅风DNS Pro搭建避坑笔记五个最容易翻车的环节这节按我在实际部署中遇到的频率排序。前三个属于PHP部署常见问题后两个是DNS服务本身和数据库的问题。无论你是照着教程搭还是自己摸着石头过河这些问题基本会在某个阶段碰到。很多所谓的“玄学”其实就是这些环境配置错位造成的。4.1 泛解析配了子域名却全落在默认页现象后台创建子域名成功外部dig也能解析到服务器IP但访问user123.example.com打开的是Nginx默认欢迎页而不是你预期的站点。原因Nginx没有把泛域名*.example.com匹配到源码的站点配置上或者站点配置里没有加载源码自带的rewrite规则。流量到了80端口但没有对应的server_name认领它就落到了默认server块。解决确认Nginx站点配置中的server_name写法泛解析要同时写通配符和裸域server { listen 80; server_name *.example.com example.com; root /www/wwwroot/dnspro/public; include /www/wwwroot/dnspro/nginx_rewrite.conf; location ~ \.php$ { fastcgi_pass unix:/tmp/php-cgi-74.sock; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } }这里的include指向源码包里的rewrite文件如果你没有在include里加载它后面所有伪静态路由都会404。改完配置先nginx -t再 reload。注意默认server块会吃掉所有未匹配的域名最好把默认server里的return 444;配置上这样不认识的域名直接断连。4.2 后台能登录解析列表却是空的现象管理员账号可以进后台但二级域名列表一张表都看不到手动添加域名提示成功刷新后也不在列表里。原因配置文件里的dbprefix和数据库实际表前缀不一致。比如SQL建了dns_domains表而dbprefix配置为空代码去查domainsMySQL返回Table doesnt exist被源码吞掉后表现为空列表。解决去数据库里看真实表名SHOW TABLES FROM dnspro;如果表名统一带dns_前缀就把配置文件里的dbprefix改成dns_保存后清一下缓存有的框架需要删除runtime缓存目录。这是典型的黑匣子问题表面是数据丢失实际是配置错位。4.3 整个后台除了首页全是404现象域名打开后首页正常点后台菜单跳转后路由全部404浏览器地址栏能看到index.php说明路径重写没生效。原因Nginx配置里没有把非真实文件的请求转发给index.php作为入口。PHP项目的URL重写是根规则少了它所有带路由的页面都会打到不存在路径上。解决在站点server块中加入转发规则location / { if (!-e $request_filename) { rewrite ^(.*)$ /index.php?s$1 last; } }如果你的源码是基于ThinkPHP的规则通常长这样如果是其它框架原理一样把请求交给唯一入口。注意if (!-e $request_filename)是为了排除静态文件避免CSS和JS也被重写。在宝塔面板里就是开启“伪静态”功能选择对应框架模板。这个坑第一次搭建几乎必踩先改配置再排查其他问题。4.4 导入SQL后中文数据乱码现象后台填写的中文域名备注或标题显示成问号或者API接口新增记录后返回乱码重启MySQL后依旧。原因建库时没有指定字符集MySQL默认用了latin1也可能SQL文件本身是utf8但导入连接没声明字符集。二级域名分发虽然大多数记录是ASCII但用户昵称、域名描述、备案备注可能全是中文乱码一旦入库很难洗回。解决删库重建时显式指定utf8mb4导入前设置连接字符集mysql -uroot -p --default-character-setutf8mb4 dnspro sql/dnspro.sql再用下面这条SQL确认表字符集SELECT TABLE_NAME, TABLE_COLLATION FROM information_schema.TABLES WHERE TABLE_SCHEMAdnspro;看到utf8mb4_unicode_ci就正常了。早期我图省事用utf8结果中文域名IDN转码后全乱后来统一改成utf8mb4就再没出过问题。4.5 解析服务启动报53端口被占用现象启动解析服务时日志报Address already in use或bind: 53 failed服务一直处于重启循环。原因很多云服务器默认开启了systemd-resolved它监听本机53端口做内部DNS解析。解析服务也想绑53两个进程抢同一个端口。解决先看谁占了53ss -lntup | grep :53 确认是systemd-resolved后编辑/etc/systemd/resolved.conf设置[Resolve] DNSStubListenerno然后重启systemd-resolved再用ss确认53已经空出来。这样操作不会影响服务器的外网DNS解析因为实际DNS查询仍走/etc/resolv.conf的上游配置。如果用的是容器或面板环境也先检查是否有其它DNS进程占用了53端口别一上来就调防火墙。5. 把迅风DNS Pro接进正式环境定时同步、安全加固与性能参数5.1 用crontab让解析状态自己转起来二级域名分发做到生产级别解析记录不是写进数据库就算完。用户的域名可能到期要下线IP可能变更需要更新这些状态变化必须有一个后台任务去扫描并把变更推给运行中的解析服务。常见做法是用cron每分钟执行一次同步脚本*/1 * * * * cd /www/wwwroot/dnspro php think dns:sync runtime/logs/dns_sync.log 21命令里的php think dns:sync是假设源码基于ThinkPHP写的CLI命令具体命令名要看源码docs。逻辑上这个定时任务的职责是从dns_domains表里找出状态为pending或已过期的记录更新解析服务的内存配置。 runtime/logs/dns_sync.log是必要的否则PHP报错时cron会静默失败你连从哪排查都不知道。cron写完后用crontab -l确认然后手动运行一次那个命令看看日志输出是否符合预期。定时任务最常见的失败是环境变量问题cron运行在一个极其精简的PATH环境里脚本里的php命令会报command not found。所以写cron时最好用绝对路径比如/usr/bin/php。你可以用which php查到完整路径后写进crontab。这个坑在cron里很经典宁可路径长一点也别用模糊命令。如果不需要独立的解析服务而是直接改bind的zone文件那么定时任务就要改成“根据数据库重新生成本地zone文件然后rndc reload”。这两种方式在源码文档里会写清楚不要混着用。5.2 后台安全加固IP白名单与API密钥管理部署到公网后最容易被扫描的是两样东西后台登录入口和API创建接口。后台登录接口如果对外开放爆破用户密码只是时间问题。常见做法是在Nginx层对后台目录做IP白名单location ^~ /admin { allow 192.168.1.0/24; allow 203.0.113.8; deny all; }这样非白名单地址访问/admin会直接403不再经过PHP。API密钥管理方面源码一般会在config里放一套API鉴权配置建议你只在代码里保留一个主密钥同时开启请求签名校验的话客户端每次都要用密钥做HMAC签名避免密钥明文暴露。不要把API密钥写进前端JS里一旦你的管理后台被XSS密钥等于拱手送出。给API接口也加上频率限制比如单IP每分钟最多创建20个子域名防止有人拿你的分发系统当批量域名注册机。最后务必给后台加HTTPS。解析分发系统后台会持有API密钥和用户数据明文HTTP传输在安全扫描里基本是必检项。如果没有现成证书用acme.sh申请免费证书比自签证书更省事然后把Nginx里80端口请求301跳转到443。自签证书虽然也能让浏览器访问但监控和第三方回调时往往要额外关闭验证不建议在生产上使用。后端日志建议按天滚动不要让它把磁盘写满。还可以做一套配置备份的日常流程。DNS系统的核心资产是数据库里的解析记录和API密钥一旦误操作批量删除了dns_domains里的记录整个分发业务就全瘫痪了。我一般会写一条cron每天凌晨备份数据库0 3 * * * mysqldump -uroot -p密码 dnspro | gzip /backup/dnspro_$(date \%F).sql.gzdate %F生成当天日期gzip压缩后一天一个文件保留7天就删。这条备份策略的成本很低但能让你在误删记录后有一粒后悔药。备份路径要写在系统盘以外否则磁盘满了会反过来影响MySQL这是运维常识。5.3 数据库与PHP-FPM的关键参数调优到了几十个用户同时创建二级域名、上百个解析查询的并发水平默认配置就不够用了。下面是我常用的几个参数参考值基于2核4G的云主机参数默认值建议值说明MySQL max_connections151256连接数上限qps高时调高innodb_buffer_pool_size128M1G内存够大时尽量调到约内存一半PHP memory_limit128M256M解析列表分页和批量操作会吃内存PHP-FPM pm.max_children1020按CPU核数乘以5起步Nginx worker_processes12与CPU核数一致更合理不一定要照抄因为你的Linux发行版默认分配不同。调参后记得重启对应服务。这里有个判断方法如果后台打开慢、CPU不高但MySQL连接满就加连接数和缓冲池如果PHP进程被占满、访问出现502就调大pm.max_children。解析服务本身如果用内存缓存记录占内存很少瓶颈主要在数据库和PHP进程之间。除了调参数还要留一条状态观察路径。最直接的办法是用crontab每5分钟请求一次解析服务的管理端口如果连续3次失败就告警。也可以利用源码自带的日志文件关注dns_sync.log是否持续增长日志不增长可能是定时任务挂了也可能是因为没有新变更。我遇到过一次cron脚本里PHP路径错误日志文件连续一周没有任何新记录最后排查半天才发现是命令绝对路径写错。6. 验证整个分发链路的一个实用技巧部署完成不等于能用。我给自己定了一个固定的验证顺序从DNS解析查到API变更最后落回HTTP访问。分享一个半自动化脚本你可以根据实际接口地址改着用#!/bin/bash DOMAINuser123.example.com APIhttps://dns.example.com/api/v1/domain/create KEYyour_api_key # 1. 创建子域名 curl -sS -X POST $API -H X-API-Key: $KEY \ -d prefixuser123record_typeAtarget203.0.113.10ttl600 # 2. 等待解析同步 sleep 60 # 3. 验证外部DNS解析 dig $DOMAIN A short # 4. 验证HTTP响应 curl -sS -o /dev/null -w %{http_code}\n http://$DOMAIN这里sleep 60是因为很多递归DNS缓存不会立刻刷新如果泛解析TTL是600秒刚创建的子域名可能要到一分钟之后才能被外部稳定查到。脚本最后一步的curl -w %{http_code}只输出了状态码200就代表从解析到Web入口已经全部走通。这个脚本不能替代所有测试但对于一次新部署来说它能帮你把“DNS配置错了”和“Web配置错了”快速区分开。我的习惯是注册一个端到端测试记录跑一遍确认无误后再用API删除掉避免测试域名留在库里被扫描器发现。第一次部署时我就忘了删除测试记录三个月后翻日志发现一堆漏洞扫描流量都打在这个幽灵域名上从那以后验证脚本末尾一定会带清理动作。提示删除接口的调用方式和创建接口对应调试期不要用后台手动删因为你要保证API的增删权限是闭环的。验证通过后这个方案就值得投入了。二级域名分发真正的价值在于把重复的解析操作变成一次自助申请只要泛解析和API接口稳定后续所有业务的子域名开通都能自动流转起来。希望帮到你。本文还有配套的精品资源点击获取