This commit is contained in:
Alex Yang
2026-01-16 11:09:11 +08:00
parent 8159577be0
commit cdac4fcf43
284 changed files with 2813570 additions and 14 deletions

File diff suppressed because one or more lines are too long

View File

@@ -2,13 +2,15 @@
"dns": {
"port": 53,
"upstreamDNS": [
"10.35.10.200"
"10.35.10.200",
"223.5.5.5",
"223.6.6.6"
],
"dnssecUpstreamDNS": [
"208.67.220.220",
"208.67.222.222"
],
"saveInterval": 30,
"saveInterval": 10,
"cacheTTL": 60,
"enableDNSSEC": false,
"queryMode": "fastest-ip",
@@ -43,7 +45,7 @@
"amazehome.xyz",
".cn"
],
"enableIPv6": true
"enableIPv6": false
},
"http": {
"port": 8080,
@@ -139,12 +141,12 @@
],
"updateInterval": 3600,
"blockMethod": "NXDOMAIN",
"customBlockIP": "",
"customBlockIP": "0.0.0.2",
"statsSaveInterval": 60
},
"gfwList": {
"ip": "10.35.10.200",
"content": "/root/dns/data/gfwlist.txt",
"ip": "",
"content": "",
"enabled": false
},
"log": {

2572
data/gflist.txt Normal file

File diff suppressed because it is too large Load Diff

7552
data/gfwlist.txt Normal file

File diff suppressed because it is too large Load Diff

24
data/hosts.txt Normal file
View File

@@ -0,0 +1,24 @@
# DNS Server Hosts File
# Generated by DNS Server
10.35.10.200 google.com
10.35.10.200 www.v2ex.com
::1 localhost
10.35.10.200 github.com
10.35.10.200 www.google.com
10.35.10.200 update.googleapis.com
10.35.10.200 www.google.com.hk
10.35.10.200 www.google.com.fr
10.35.10.200 prod.otel.kaizen.nvidia.com
10.35.10.200 release-assets.githubusercontent.com
10.35.10.200 payment-website-pci.ol.epicgames.com
10.35.10.200 github.io
10.35.10.200 clients3.google.com
10.35.10.200 map.google.com
10.35.10.200 play.google.com
10.35.10.200 waa-pa.clients6.google.com
10.35.10.200 www.epochtimes.com
10.35.10.200 cdn.v2ex.com
10.35.10.200 ngx.download.nvidia.com
10.35.10.200 ogads-pa.clients6.google.com
10.35.10.200 maps.google.com

254
data/hosts.txt.bak Normal file
View File

@@ -0,0 +1,254 @@
# DNS Server Hosts File
# Generated by DNS Server
10.35.10.200 cdn.akamai.steamstatic.com
10.35.10.200 badges.roblox.com
10.35.10.200 www.fandom.com
10.35.10.200 gql.twitch.tv
::1 localhost
10.35.10.200 gist.github.com
10.35.10.200 ucaf37cba09486e69c215bdfe2e2.dl.dropboxusercontent.com
10.35.10.200 www.mega.nz
10.35.10.200 translate.google.com
10.35.10.200 skyapi.onedrive.live.com
10.35.10.200 www.youtube.com
10.35.10.200 vercel.app
10.35.10.200 fufufu23.imgur.com
10.35.10.200 uc957f785cc03b9b273234fd24f9.dl.dropboxusercontent.com
10.35.10.200 apresolve.spotify.com
10.35.10.200 id.twitch.tv
10.35.10.200 thumbnails.roblox.com
10.35.10.200 pubster.twitch.tv
10.35.10.200 api-partner.spotify.com
10.35.10.200 api.github.com
10.35.10.200 uc07aaf207f16a978a3dbc24a1c9.dl.dropboxusercontent.com
10.35.10.200 api.twitch.tv
10.35.10.200 aleksi.artstation.com
10.35.10.200 assets.help.twitch.tv
10.35.10.200 i.ytimg.com
10.35.10.200 storage.live.com
10.35.10.200 dashboard.twitch.tv
10.35.10.200 develop.roblox.com
10.35.10.200 accounts.youtube.com
10.35.10.200 raw.githubusercontent.com
10.35.10.200 s.pinimg.com
10.35.10.200 mega.co.nz
10.35.10.200 media.steampowered.com
10.35.10.200 gds-vhs-drops-campaign-images.twitch.tv
10.35.10.200 yourihoek.artstation.com
10.35.10.200 archiveprogram.github.com
10.35.10.200 img.youtube.com
10.35.10.200 files.nexus-cdn.com
10.35.10.200 mega.io
10.35.10.200 www.github.io
10.35.10.200 epic-games-api.arkoselabs.com
10.35.10.200 beta.mod.io
10.35.10.200 g.cdn1.mega.co.nz
10.35.10.200 thepoy.imgur.com
10.35.10.200 uc4b4b602d4b01e27782f92ce984.dl.dropboxusercontent.com
10.35.10.200 origin-a.akamaihd.net
10.35.10.200 login.steampowered.com
10.35.10.200 fonts.googleapis.com
10.35.10.200 ucb277f9a438d6b3f4ea2147ac26.dl.dropboxusercontent.com
10.35.10.200 g.api.mega.co.nz
10.35.10.200 www.dropbox.com
10.35.10.200 prod-ireland.arkoselabs.com
10.35.10.200 contacts.roblox.com
10.35.10.200 github.dev
10.35.10.200 presence.roblox.com
10.35.10.200 resources.github.com
10.35.10.200 pinterest.com
10.35.10.200 twitch.tv
10.35.10.200 cdn-learning.artstation.com
10.35.10.200 store.akamai.steamstatic.com
10.35.10.200 versioncompatibility.api.roblox.com
10.35.10.200 github.com
10.35.10.200 ephemeralcounters.api.roblox.com
10.35.10.200 help.twitch.tv
10.35.10.200 dl.dropboxusercontent.com
10.35.10.200 imgs.hcaptcha.com
10.35.10.200 www.roblox.com
10.35.10.200 fonts.gstatic.com
10.35.10.200 apis.roblox.com
10.35.10.200 www.google.com
10.35.10.200 video-edge-00252e.pdx01.abs.hls.ttvnw.net
10.35.10.200 fandom.com
10.35.10.200 vod-storyboards.twitch.tv
10.35.10.200 t.imgur.com
10.35.10.200 aem.dropbox.com
10.35.10.200 nl.roblox.com
10.35.10.200 twostepverification.roblox.com
10.35.10.200 avatars1.githubusercontent.com
10.35.10.200 pinimg.com
10.35.10.200 cdnb.artstation.com
10.35.10.200 docs.hcaptcha.com
10.35.10.200 groups.roblox.com
10.35.10.200 vod-metro.twitch.tv
10.35.10.200 www.hcaptcha.com
10.35.10.200 uca3a40eb53259715309022eb9fd.dl.dropboxusercontent.com
10.35.10.200 extension-files.twitch.tv
10.35.10.200 mod.io
10.35.10.200 panels.twitch.tv
10.35.10.200 steamcommunity.com
10.35.10.200 spotify.com
10.35.10.200 local.steampp.net
10.35.10.200 auth.mod.io
10.35.10.200 cvp.twitch.tv
10.35.10.200 blog.mod.io
10.35.10.200 pages.github.com
10.35.10.200 t.email.roblox.com
10.35.10.200 camo.githubusercontent.com
10.35.10.200 blog.imgur.com
10.35.10.200 google.com
10.35.10.200 imgur.com
10.35.10.200 imgs3.hcaptcha.com
10.35.10.200 appcenter.ms
10.35.10.200 accounts.google.pl
10.35.10.200 cellcow.imgur.com
10.35.10.200 gravatar.com
10.35.10.200 metrics.roblox.com
10.35.10.200 accounts.google.com
10.35.10.200 abs.hls.ttvnw.net
10.35.10.200 notifications.roblox.com
10.35.10.200 clientsettings.api.roblox.com
10.35.10.200 accountsettings.roblox.com
10.35.10.200 staticstats.nexusmods.com
10.35.10.200 clips.twitch.tv
10.35.10.200 help.steampowered.com
10.35.10.200 roblox.com
10.35.10.200 githubapp.com
10.35.10.200 i.stack.imgur.com
10.35.10.200 private-user-images.githubusercontent.com
10.35.10.200 supervisor.ext-twitch.tv
10.35.10.200 checkout.steampowered.com
10.35.10.200 app.twitch.tv
10.35.10.200 blog.twitch.tv
10.35.10.200 countess.twitch.tv
10.35.10.200 rishablue.artstation.com
10.35.10.200 userstroage.mega.co.nz
10.35.10.200 client-event-reporter.twitch.tv
10.35.10.200 www.spotify.com
10.35.10.200 cf-files.nexusmods.com
10.35.10.200 community.steamstatic.com
10.35.10.200 www.imgur.com
10.35.10.200 dev.twitch.tv
10.35.10.200 link.twitch.tv
10.35.10.200 avatars.githubusercontent.com
10.35.10.200 supporter-files.nexus-cdn.com
10.35.10.200 users.nexusmods.com
10.35.10.200 player.twitch.tv
10.35.10.200 steamuserimages-a.akamaihd.net
10.35.10.200 google.com.hk
10.35.10.200 vod-secure.twitch.tv
10.35.10.200 www.google.com.hk
10.35.10.200 onedrive.live.com
10.35.10.200 trades.roblox.com
10.35.10.200 www.steamcommunity.com
10.35.10.200 api.imgur.com
10.35.10.200 update.greasyfork.org
10.35.10.200 www.artstation.com
10.35.10.200 steamcdn-a.akamaihd.net
10.35.10.200 gamejoin.roblox.com
10.35.10.200 staticdelivery.nexusmods.com
10.35.10.200 assets.twitch.tv
10.35.10.200 m.imgur.com
10.35.10.200 cdna.artstation.com
10.35.10.200 gds.google.com
10.35.10.200 music.twitch.tv
10.35.10.200 id-cdn.twitch.tv
10.35.10.200 binary.lge.modcdn.io
10.35.10.200 js.hcaptcha.com
10.35.10.200 gameinternationalization.roblox.com
10.35.10.200 nexusmods.com
10.35.10.200 https://accounts.google.com.hk/
10.35.10.200 realtime-signalr.roblox.com
10.35.10.200 themes.googleusercontent.com
10.35.10.200 community.akamai.steamstatic.com
10.35.10.200 clips-media-assets2.twitch.tv
10.35.10.200 trowel.twitch.tv
10.35.10.200 store.ubisoft.com
10.35.10.200 user-images.githubusercontent.com
10.35.10.200 us-west-2.uploads-regional.twitch.tv
10.35.10.200 mega.nz
10.35.10.200 newassets.hcaptcha.com
10.35.10.200 uploads.github.com
10.35.10.200 auth.roblox.com
10.35.10.200 education.github.com
10.35.10.200 translate.googleapis.com
10.35.10.200 githubusercontent.com
10.35.10.200 s.imgur.com
10.35.10.200 cdn.artstation.com
10.35.10.200 i.pinimg.com
10.35.10.200 ajax.googleapis.com
10.35.10.200 magazine.artstation.com
10.35.10.200 client-api.arkoselabs.com
10.35.10.200 ecsv2.roblox.com
10.35.10.200 play.google.com
10.35.10.200 avatars3.githubusercontent.com
10.35.10.200 discuss.dev.twitch.tv
10.35.10.200 passport.twitch.tv
10.35.10.200 github.githubassets.com
10.35.10.200 ww.artstation.com
10.35.10.200 github.io
10.35.10.200 hub.docker.com
10.35.10.200 open.spotify.com
10.35.10.200 www.gravatar.com
10.35.10.200 irc-ws.chat.twitch.tv
10.35.10.200 lh3.googleusercontent.com
10.35.10.200 games.roblox.com
10.35.10.200 users.roblox.com
10.35.10.200 g.static.mega.co.nz
10.35.10.200 www.twitch.tv
10.35.10.200 locale.roblox.com
10.35.10.200 p.imgur.com
10.35.10.200 economy.roblox.com
10.35.10.200 badges.twitch.tv
10.35.10.200 cdn.arkoselabs.com
10.35.10.200 translate.google.cn
10.35.10.200 onedrive.live
10.35.10.200 raw.github.com
10.35.10.200 aroll.artstation.com
10.35.10.200 uc9c83355d6aa8bc75f7f597c7d6.dl.dropboxusercontent.com
10.35.10.200 huggingface.co
10.35.10.200 greasyfork.org
10.35.10.200 avatars.akamai.steamstatic.com
10.35.10.200 assetgame.roblox.com
10.35.10.200 hcaptcha.com
10.35.10.200 web.roblox.com
10.35.10.200 avatars2.githubusercontent.com
10.35.10.200 api.mod.io
10.35.10.200 www.mega.co.nz
10.35.10.200 store.steampowered.com
10.35.10.200 support-assets.githubassets.com
10.35.10.200 artstation.com
10.35.10.200 www.nexusmods.com
10.35.10.200 docs.mod.io
10.35.10.200 translate-pa.googleapis.com
10.35.10.200 premium-files.nexus-cdn.com
10.35.10.200 in.appcenter.ms
10.35.10.200 chat.roblox.com
10.35.10.200 inspector.twitch.tv
10.35.10.200 i.imgur.com
10.35.10.200 objects.githubusercontent.com
10.35.10.200 assets.hcaptcha.com
10.35.10.200 myaccount.google.com
10.35.10.200 play-lh.googleusercontent.com
10.35.10.200 static.mod.io
10.35.10.200 maxcdn.bootstrapcdn.com
10.35.10.200 dya.artstation.com
10.35.10.200 www.pinterest.com
10.35.10.200 m.twitch.tv
10.35.10.200 pubsub-edge.twitch.tv
10.35.10.200 uc87442e427766fe8cf2a7a07827.dl.dropboxusercontent.com
10.35.10.200 friends.roblox.com
10.35.10.200 cloud.githubusercontent.com
10.35.10.200 www.google.com.pl
10.35.10.200 sm.pinimg.com
10.35.10.200 irc-ws-r.chat.twitch.tv
10.35.10.200 accounts.google.com.hk
10.35.10.200 stream.twitch.tv
10.35.10.200 api.steampowered.com
10.35.10.200 secure.gravatar.com
10.35.10.200 dropbox.com
10.35.10.200 ucc541451e9df780e40777d477eb.dl.dropboxusercontent.com
10.35.10.200 avatars0.githubusercontent.com

295368
data/querylog.json Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,734 @@
!Title: AWAvenue Ads Rule
!--------------------------------------
!Total lines: 725
!Version: 1.5.5-release
!Homepage: https://github.com/TG-Twilight/AWAvenue-Ads-Rule
!License: https://github.com/TG-Twilight/AWAvenue-Ads-Rule/blob/main/LICENSE
||1010pic.com^
||16dd-advertise-1252317822.file.myqcloud.com^
||16dd-advertise-1252317822.image.myqcloud.com^
||8le8le.com^
||a0.app.xiaomi.com^
||aaid.umeng.com^
||abtest-ch.snssdk.com^
||ad-cache.dopool.com^
||ad-cdn.qingting.fm^
||ad-cmp.hismarttv.com^
||ad-download.hismarttv.com^
||ad-imp.hismarttv.com^
||ad-scope.com^
||ad-scope.com.cn^
||ad-sdk-config.youdao.com^
||ad-sdk.huxiu.com^
||ad.12306.cn^
||ad.51wnl.com^
||ad.bwton.com^
||ad.cctv.com^
||ad.cyapi.cn^
||ad.doubleclick.net^
||ad.partner.gifshow.com^
||ad.qingting.fm^
||ad.qq.com^
||ad.richmob.cn^
||ad.tencentmusic.com^
||ad.toutiao.com^
||ad.v3mh.com^
||ad.winrar.com.cn^
||ad.xelements.cn^
||ad.xiaomi.com^
||ad.ximalaya.com^
||ad.zijieapi.com^
||adapi.izuiyou.com^
||adapi.yynetwk.com^
||adashbc.ut.taobao.com^
||adc.hpplay.cn^
||adcdn.hpplay.cn^
||adcdn.tencentmusic.com^
||adclick.g.doubleclick.net^
||adclick.tencentmusic.com^
||adcolony.com^
||adexpo.tencentmusic.com^
||adfilter.imtt.qq.com^
||adfstat.yandex.ru^
||adguanggao.eee114.com^
||adjust.cn^
||adjust.com^
||adkwai.com^
||adlink-api.huan.tv^
||adm.funshion.com^
||ads-api-o.api.leiniao.com^
||ads-api.tiktok.com^
||ads-api.twitter.com^
||ads-img-qc.xhscdn.com^
||ads-jp.tiktok.com^
||ads-marketing-vivofs.vivo.com.cn^
||ads-sg.tiktok.com^
||ads-us.tiktok.com^
||ads-video-al.xhscdn.com^
||ads-video-qc.xhscdn.com^
||ads.95516.com^
||ads.google.cn^
||ads.heytapmobi.com^
||ads.huan.tv^
||ads.huantest.com^
||ads.icloseli.cn^
||ads.linkedin.com^
||ads.music.126.net^
||ads.oppomobile.com^
||ads.pinterest.com^
||ads.servebom.com^
||ads.service.kugou.com^
||ads.tiktok.com^
||ads.v3mh.com^
||ads.youtube.com^
||ads3-normal-hl.zijieapi.com^
||ads3-normal-lf.zijieapi.com^
||ads3-normal-lq.zijieapi.com^
||ads3-normal.zijieapi.com^
||ads5-normal-hl.zijieapi.com^
||ads5-normal-lf.zijieapi.com^
||ads5-normal-lq.zijieapi.com^
||ads5-normal.zijieapi.com^
||adse.test.ximalaya.com^
||adse.wsa.ximalaya.com^
||adse.ximalaya.com^
||adsebs.ximalaya.com^
||adsense.google.cn^
||adserver.unityads.unity3d.com^
||adservice.google.cn^
||adservice.google.com^
||adserviceretry.kugou.com^
||adsfile.bssdlbig.kugou.com^
||adsfile.qq.com^
||adsfilebssdlbig.ali.kugou.com^
||adsfileretry.service.kugou.com^
||adsfs-sdkconfig.heytapimage.com^
||adsfs.oppomobile.com^
||adslvfile.qq.com^
||adsmart.konka.com^
||adsmind.gdtimg.com^
||adsmind.ugdtimg.com^
||adsp.xunlei.com^
||adstats.tencentmusic.com^
||adstore-1252524079.file.myqcloud.com^
||adstore-index-1252524079.file.myqcloud.com^
||adtago.s3.amazonaws.com^
||adtech.yahooinc.com^
||adtrack.quark.cn^
||adukwai.com^
||adv.fjtv.net^
||adv.sec.intl.miui.com^
||adv.sec.miui.com^
||advertiseonbing.azureedge.net^
||advertising-api-eu.amazon.com^
||advertising-api-fe.amazon.com^
||advertising-api.amazon.com^
||advertising.apple.com^
||advertising.yahoo.com^
||advertising.yandex.ru^
||advice-ads.s3.amazonaws.com^
||adview.cn^
||adx-ad.smart-tv.cn^
||adx-bj.anythinktech.com^
||adx-cn.anythinktech.com^
||adx-drcn.op.dbankcloud.cn^
||adx-open-service.youku.com^
||adx-os.anythinktech.com^
||adx.ads.heytapmobi.com^
||adx.ads.oppomobile.com^
||adxlog-adnet.vivo.com.cn^
||adxlog-adnet.vivo.com.cn.dsa.dnsv1.com.cn^
||adxserver.ad.cmvideo.cn^
||aegis.qq.com^
||afs.googlesyndication.com^
||aiseet.aa.atianqi.com^
||ali-ad.a.yximgs.com^
||alog.umeng.com^
||als.baidu.com^
||amdcopen.m.taobao.com^
||amdcopen.m.umeng.com^
||an.facebook.com^
||analysis.yozocloud.cn^
||analytics-api.samsunghealthcn.com^
||analytics.126.net^
||analytics.95516.com^
||analytics.google.com^
||analytics.pinterest.com^
||analytics.pointdrive.linkedin.com^
||analytics.query.yahoo.com^
||analytics.rayjump.com^
||analytics.s3.amazonaws.com^
||analytics.tiktok.com^
||analytics.woozooo.com^
||analyticsengine.s3.amazonaws.com^
||analyze.lemurbrowser.com^
||andrqd.play.aiseet.atianqi.com^
||ap.dongqiudi.com^
||apd-pcdnwxlogin.teg.tencent-cloud.net^
||apd-pcdnwxnat.teg.tencent-cloud.net^
||apd-pcdnwxstat.teg.tencent-cloud.net^
||api-access.pangolin-sdk-toutiao.com^
||api-access.pangolin-sdk-toutiao1.com^
||api-access.pangolin-sdk-toutiao2.com^
||api-access.pangolin-sdk-toutiao3.com^
||api-access.pangolin-sdk-toutiao4.com^
||api-access.pangolin-sdk-toutiao5.com^
||api-ad-product.huxiu.com^
||api-adservices.apple.com^
||api-gd.hiaiabc.com^
||api-htp.beizi.biz^
||api.ad.xiaomi.com^
||api.e.kuaishou.com^
||api.htp.hubcloud.com.cn^
||api.hzsanjiaomao.com^
||api.installer.xiaomi.com^
||api.jietuhb.com^
||api.kingdata.ksyun.com^
||api.statsig.com^
||api5-normal-quic-lf.ixigua.com^
||apiyd.my91app.com^
||apks.webxiaobai.top^
||app-measurement.com^
||appcloud2.in.zhihu.com^
||applog.lc.quark.cn^
||applog.uc.cn^
||applog.zijieapi.com^
||ata-sdk-uuid-report.dreport.meituan.net^
||auction.unityads.unity3d.com^
||audid-api.taobao.com^
||audid.umeng.com^
||azr.footprintdns.com^
||b1-data.ads.heytapmobi.com^
||baichuan-sdk.alicdn.com^
||baichuan-sdk.taobao.com^
||bdad.123pan.cn^
||bdapi-ads.realmemobile.com^
||bdapi-in-ads.realmemobile.com^
||bdapi.ads.oppomobile.com^
||beacon-api.aliyuncs.com^
||beacon.qq.com^
||beaconcdn.qq.com^
||beacons.gvt2.com^
||beizi.biz^
||bes-mtj.baidu.com^
||bgg.baidu.com^
||bianxian.com^
||bingads.microsoft.com^
||bj.ad.track.66mobi.com^
||books-analytics-events.apple.com^
||browsercfg-drcn.cloud.dbankcloud.cn^
||bsrv.qq.com^
||bugly.qq.com^
||business-api.tiktok.com^
||c.bidtoolads.com^
||c.evidon.com^
||c.gj.qq.com^
||c.kuaiduizuoye.com^
||c.sayhi.360.cn^
||c2.gdt.qq.com^
||canvas-cdn.gdt.qq.com^
||catalog.fjwhcbsh.com^
||cbjs.baidu.com^
||ccs.umeng.com^
||cctv.adsunion.com^
||cdn-ad.wtzw.com^
||cdn-ads.oss-cn-shanghai.aliyuncs.com^
||cdn-plugin-sync-upgrade-juui.hismarttv.com^
||cdn.ad.xiaomi.com^
||cdn.ynuf.aliapp.org^
||cfg.imtt.qq.com^
||chat1.jd.com^
||chiq-cloud.com^
||cj.qidian.com^
||ck.ads.oppomobile.com^
||click.googleanalytics.com^
||click.oneplus.cn^
||clog.miguvideo.com^
||cnlogs.umeng.com^
||cnlogs.umengcloud.com^
||cnzz.com^
||collect.kugou.com^
||commdata.v.qq.com^
||config.chsmarttv.com^
||config.unityads.unity3d.com^
||cpro.baidustatic.com^
||crashlytics.com^
||crashlyticsreports-pa.googleapis.com^
||csjplatform.com^
||cws-cctv.conviva.com^
||data.ads.oppomobile.com^
||data.chsmarttv.com^
||data.mistat.india.xiaomi.com^
||data.mistat.rus.xiaomi.com^
||data.mistat.xiaomi.com^
||diagnosis.ad.xiaomi.com^
||dig.bdurl.net^
||dl.zuimeitianqi.com^
||dlogs.bwton.com^
||dm.toutiao.com^
||domain.aishengji.com^
||doubleclick-cn.net^
||download.changhong.upgrade2.huan.tv^
||downloadxml.changhong.upgrade2.huan.tv^
||drcn-weather.cloud.huawei.com^
||dsp-x.jd.com^
||dsp.fcbox.com^
||dualstack-logs.amap.com^
||dutils.com^
||dxp.baidu.com^
||e.ad.xiaomi.com^
||eclick.baidu.com^
||edge.ads.twitch.tv^
||ef-dongfeng.tanx.com^
||entry.baidu.com^
||errlog.umeng.com^
||errnewlog.umeng.com^
||event.tradplusad.com^
||events-drcn.op.dbankcloud.cn^
||events.reddit.com^
||events.redditmedia.com^
||firebaselogging-pa.googleapis.com^
||flurry.com^
||g-adnet.hiaiabc.com^
||g-staic.ganjingworld.com^
||g2.ganjing.world^
||game.loveota.com^
||gdfp.gifshow.com^
||gemini.yahoo.com^
||geo.yahoo.com^
||getui.cn^
||getui.com^
||getui.net^
||ggx.cmvideo.cn^
||ggx01.miguvideo.com^
||ggx03.miguvideo.com^
||globalapi.ad.xiaomi.com^
||google-analytics.com^
||googleads.g.doubleclick.net^
||googleadservices-cn.com^
||googleadservices.com^
||googletagservices-cn.com^
||googletagservices.com^
||gorgon.youdao.com^
||gromore.pangolin-sdk-toutiao.com^
||grs.dbankcloud.com^
||grs.hicloud.com^
||grs.platform.dbankcloud.ru^
||h-adashx.ut.taobao.com^
||h.trace.qq.com^
||hanlanad.com^
||hexagon-analytics.com^
||hm.baidu.com^
||hmma.baidu.com^
||houyi.kkmh.com^
||hpplay.cn^
||httpdns.bcelive.com^
||httpdns.ocloud.oppomobile.com^
||hugelog.fcbox.com^
||huichuan.sm.cn^
||hw-ot-ad.a.yximgs.com^
||hw.zuimeitianqi.com^
||hwpub-s01-drcn.cloud.dbankcloud.cn^
||hya.comp.360os.com^
||hybrid.miniapp.taobao.com^
||hye.comp.360os.com^
||hyt.comp.360os.com^
||i.snssdk.com^
||iad.apple.com^
||iadctest.qwapi.com^
||iadsdk.apple.com^
||iadworkbench.apple.com^
||ifacelog.iqiyi.com^
||ifs.tanx.com^
||igexin.com^
||ii.gdt.qq.com^
||imag8.pubmatic.com^
||imag86.pubmatic.com^
||image-ad.sm.cn^
||imageplus.baidu.com^
||images.outbrainimg.com^
||images.pinduoduo.com^
||img-c.heytapimage.com^
||img.adnyg.com^
||img.adnyg.com.w.kunlungr.com^
||imtmp.net^
||iot-eu-logser.realme.com^
||iot-logser.realme.com^
||ipv4.kkmh.com^
||irc.qubiankeji.com^
||itv2-up.openspeech.cn^
||ixav-cse.avlyun.com^
||iyfbodn.com^
||janapi.jd.com^
||jiguang.cn^
||jpush.cn^
||jpush.html5.qq.com^
||jpush.io^
||jswebcollects.kugou.com^
||kepler.jd.com^
||kl.67it.com^
||knicks.jd.com^
||ks.pull.yximgs.com^
||launcher.smart-tv.cn^
||launcherimg.smart-tv.cn^
||lf3-ad-union-sdk.pglstatp-toutiao.com^
||lf6-ad-union-sdk.pglstatp-toutiao.com^
||litchiads.com^
||liveats-vod.video.ptqy.gitv.tv^
||livemonitor.huan.tv^
||livep.l.aiseet.atianqi.com^
||lives.l.aiseet.atianqi.com^
||lives.l.ott.video.qq.com^
||lm10111.jtrincc.cn^
||log-api-mn.huxiu.com^
||log-api.huxiu.com^
||log-api.pangolin-sdk-toutiao-b.com^
||log-api.pangolin-sdk-toutiao.com^
||log-report.com^
||log-sdk.gifshow.com^
||log-upload-os.hoyoverse.com^
||log-upload.mihoyo.com^
||log.ad.xiaomi.com^
||log.aispeech.com^
||log.amemv.com^
||log.appstore3.huan.tv^
||log.avlyun.com^
||log.avlyun.sec.intl.miui.com^
||log.byteoversea.com^
||log.fc.yahoo.com^
||log.kuwo.cn^
||log.pinterest.com^
||log.snssdk.com^
||log.stat.kugou.com^
||log.tagtic.cn^
||log.tbs.qq.com^
||log.vcgame.cn^
||log.web.kugou.com^
||log.zijieapi.com^
||log1.cmpassport.com^
||logbak.hicloud.com^
||logs.amap.com^
||logservice.hicloud.com^
||logservice1.hicloud.com^
||logtj.kugou.com^
||logupdate.avlyun.sec.miui.com^
||m-adnet.hiaiabc.com^
||m.ad.zhangyue.com^
||m.atm.youku.com^
||m.kubiqq.com^
||m1.ad.10010.com^
||mapi.m.jd.com^
||masdkv6.3g.qq.com^
||mazu.m.qq.com^
||mbdlog.iqiyi.com^
||metrics.apple.com^
||metrics.data.hicloud.com^
||metrics.icloud.com^
||metrics.mzstatic.com^
||metrics2.data.hicloud.com^
||metrika.yandex.ru^
||mi.gdt.qq.com^
||miav-cse.avlyun.com^
||mime.baidu.com^
||mine.baidu.com^
||mission-pub.smart-tv.cn^
||miui-fxcse.avlyun.com^
||mnqlog.ldmnq.com^
||mobads-logs.baidu.com^
||mobads-pre-config.cdn.bcebos.com^
||mobads.baidu.com^
||mobile.da.mgtv.com^
||mobilelog.upqzfile.com^
||mobileservice.cn^
||mon.zijieapi.com^
||monitor-ads-test.huan.tv^
||monitor-uu.play.aiseet.atianqi.com^
||monitor.music.qq.com^
||monitor.uu.qq.com^
||monsetting.toutiao.com^
||mssdk.volces.com^
||mssdk.zijieapi.com^
||mtj.baidu.com^
||newvoice.chiq5.smart-tv.cn^
||nmetrics.samsung.com^
||notes-analytics-events.apple.com^
||nsclick.baidu.com^
||o2o.api.xiaomi.com^
||oauth-login-drcn.platform.dbankcloud.com^
||offerwall.yandex.net^
||omgmta.play.aiseet.atianqi.com^
||open.e.kuaishou.cn^
||open.e.kuaishou.com^
||open.kuaishouzt.com^
||open.kwaishouzt.com^
||open.kwaizt.com^
||optimus-ads.amap.com^
||orbit.jd.com^
||oth.eve.mdt.qq.com^
||oth.str.mdt.qq.com^
||otheve.play.aiseet.atianqi.com^
||outlookads.live.com^
||p.l.qq.com^
||p.s.360.cn^
||p1-be-pack-sign.pglstatp-toutiao.com^
||p1-lm.adkwai.com^
||p2-be-pack-sign.pglstatp-toutiao.com^
||p2-lm.adkwai.com^
||p2p.huya.com^
||p3-be-pack-sign.pglstatp-toutiao.com^
||p3-lm.adkwai.com^
||p3-tt.byteimg.com^
||p4-be-pack-sign.pglstatp-toutiao.com^
||p5-be-pack-sign.pglstatp-toutiao.com^
||p6-be-pack-sign.pglstatp-toutiao.com^
||pagead2.googleadservices.com^
||pagead2.googlesyndication.com^
||pangolin-sdk-toutiao-b.com^
||pay.sboot.cn^
||pgdt.ugdtimg.com^
||pglstatp-toutiao.com^
||pig.pupuapi.com^
||pixon.ads-pixiv.net^
||pkoplink.com^
||plbslog.umeng.com^
||pms.mb.qq.com^
||policy.video.ptqy.gitv.tv^
||pos.baidu.com^
||proxy.advp.apple.com^
||public.gdtimg.com^
||q.i.gdt.qq.com^
||qqdata.ab.qq.com^
||qwapi.apple.com^
||qzs.gdtimg.com^
||recommend-drcn.hms.dbankcloud.cn^
||report.tv.kohesport.qq.com^
||res.hubcloud.com.cn^
||res1.hubcloud.com.cn^
||res2.hubcloud.com.cn^
||res3.hubcloud.com.cn^
||resolve.umeng.com^
||review.gdtimg.com^
||rms-drcn.platform.dbankcloud.cn^
||roi.soulapp.cn^
||rpt.gdt.qq.com^
||rtb.voiceads.cn^
||s.amazon-adsystem.com^
||s1.qq.com^
||s2.qq.com^
||s3.qq.com^
||saad.ms.zhangyue.net^
||samsung-com.112.2o7.net^
||samsungads.com^
||sanme2.taisantech.com^
||saveu5-normal-lq.zijieapi.com^
||scdown.qq.com^
||scs.openspeech.cn^
||sdk-ab-config.qquanquan.com^
||sdk-cache.video.ptqy.gitv.tv^
||sdk.1rtb.net^
||sdk.beizi.biz^
||sdk.cferw.com^
||sdk.e.qq.com^
||sdk.hzsanjiaomao.com^
||sdk.markmedia.com.cn^
||sdk.mobads.adwangmai.com^
||sdkconf.avlyun.com^
||sdkconfig.ad.intl.xiaomi.com^
||sdkconfig.ad.xiaomi.com^
||sdkconfig.play.aiseet.atianqi.com^
||sdkconfig.video.qq.com^
||sdkoptedge.chinanetcenter.com^
||sdktmp.hubcloud.com.cn^
||sdownload.stargame.com^
||search.ixigua.com^
||search3-search.ixigua.com^
||search5-search-hl.ixigua.com^
||search5-search.ixigua.com^
||securemetrics.apple.com^
||securepubads.g.doubleclick.net^
||sensors-log.dongqiudi.com^
||service.changhong.upgrade2.huan.tv^
||service.vmos.cn^
||sf16-static.i18n-pglstatp.com^
||sf3-fe-tos.pglstatp-toutiao.com^
||shouji.sogou.com^
||sigmob.cn^
||sigmob.com^
||skdisplay.jd.com^
||slb-p2p.vcloud.ks-live.com^
||smad.ms.zhangyue.net^
||smart-tv.cn^
||smartad.10010.com^
||smetrics.samsung.com^
||sms.ads.oppomobile.com^
||sngmta.qq.com^
||snowflake.qq.com^
||stat.dongqiudi.com^
||stat.y.qq.com^
||static.ads-twitter.com^
||statics.woozooo.com^
||stats.qiumibao.com^
||stats.wp.com^
||statsigapi.net^
||stg-data.ads.heytapmobi.com^
||success.ctobsnssdk.com^
||syh-imp.cdnjtzy.com^
||szbdyd.com^
||t-dsp.pinduoduo.com^
||t.l.qq.com^
||t.track.ad.xiaomi.com^
||t002.ottcn.com^
||t1.a.market.xiaomi.com^
||t2.a.market.xiaomi.com^
||t3.a.market.xiaomi.com^
||tangram.e.qq.com^
||tdc.qq.com^
||tdsdk.cpatrk.net^
||tdsdk.xdrig.com^
||tencent-dtv.m.cn.miaozhen.com^
||terms-drcn.platform.dbankcloud.cn^
||test.ad.xiaomi.com^
||test.e.ad.xiaomi.com^
||tj.b.qq.com^
||tj.video.qq.com^
||tmead.y.qq.com^
||tmeadcomm.y.qq.com^
||tmfmazu-wangka.m.qq.com^
||tmfmazu.m.qq.com^
||tmfsdk.m.qq.com^
||tmfsdktcpv4.m.qq.com^
||tnc3-aliec1.toutiaoapi.com^
||tnc3-aliec2.bytedance.com^
||tnc3-aliec2.toutiaoapi.com^
||tnc3-alisc1.bytedance.com^
||tnc3-alisc1.zijieapi.com^
||tnc3-alisc2.zijieapi.com^
||tnc3-bjlgy.bytedance.com^
||tnc3-bjlgy.toutiaoapi.com^
||tnc3-bjlgy.zijieapi.com^
||toblog.ctobsnssdk.com^
||trace.qq.com^
||tracelog-debug.qquanquan.com^
||track.lc.quark.cn^
||track.uc.cn^
||tracker.ai.xiaomi.com^
||tracker.gitee.com^
||tracking.miui.com^
||tracking.rus.miui.com^
||tsvrv.com^
||tvuser-ch.cedock.com^
||tx-ad.a.yximgs.com^
||tx-kmpaudio.pull.yximgs.com^
||tz.sec.xiaomi.com^
||uapi.ads.heytapmobi.com^
||udc.yahoo.com^
||udcm.yahoo.com^
||uedas.qidian.com^
||ulog-sdk.gifshow.com^
||ulogjs.gifshow.com^
||ulogs.umeng.com^
||ulogs.umengcloud.com^
||umengacs.m.taobao.com^
||umengjmacs.m.taobao.com^
||umini.shujupie.com^
||umsns.com^
||union.baidu.cn^
||union.baidu.com^
||update.avlyun.sec.miui.com^
||update.lejiao.tv^
||upgrade-update.hismarttv.com^
||us.l.qq.com^
||v.adintl.cn^
||v.adx.hubcloud.com.cn^
||v1-ad.video.yximgs.com^
||v2-ad.video.yximgs.com^
||v2-api-channel-launcher.hismarttv.com^
||v2.gdt.qq.com^
||v2mi.gdt.qq.com^
||v3-ad.video.yximgs.com^
||v3.gdt.qq.com^
||video-ad.sm.cn^
||video-dsp.pddpic.com^
||video.dispatch.tc.qq.com^
||virusinfo-cloudscan-cn.heytapmobi.com^
||vlive.qqvideo.tc.qq.com^
||volc.bj.ad.track.66mobi.com^
||vungle.com^
||w.l.qq.com^
||w1.askwai.com^
||w1.bskwai.com^
||w1.cskwai.com^
||w1.dskwai.com^
||w1.eskwai.com^
||w1.fskwai.com^
||w1.gskwai.com^
||w1.hskwai.com^
||w1.iskwai.com^
||w1.jskwai.com^
||w1.kskwai.com^
||w1.lskwai.com^
||w1.mskwai.com^
||w1.nskwai.com^
||w1.oskwai.com^
||w1.pskwai.com^
||w1.qskwai.com^
||w1.rskwai.com^
||w1.sskwai.com^
||w1.tskwai.com^
||w1.uskwai.com^
||w1.vskwai.com^
||w1.wskwai.com^
||w1.xskwai.com^
||w1.yskwai.com^
||w1.zskwai.com^
||watson.microsoft.com^
||watson.telemetry.microsoft.com^
||weather-analytics-events.apple.com^
||weather-community-drcn.weather.dbankcloud.cn^
||webstat.qiumibao.com^
||webview.unityads.unity3d.com^
||widgets.outbrain.com^
||widgets.pinterest.com^
||win.gdt.qq.com^
||wn.x.jd.com^
||ws-keyboard.shouji.sogou.com^
||ws.sj.qq.com^
||www42.zskwai.com^
||wxa.wxs.qq.com^
||wximg.wxs.qq.com^
||wxsmw.wxs.qq.com^
||wxsnsad.tc.qq.com^
||wxsnsdy.wxs.qq.com^
||wxsnsdythumb.wxs.qq.com^
||xc.gdt.qq.com^
||xiaomi-dtv.m.cn.miaozhen.com^
||xiaoshuo.wtzw.com^
||xlivrdr.com^
||xlmzc.cnjp-exp.com^
||xlog.jd.com^
||xlviiirdr.com^
||xlviirdr.com^
||yk-ssp.ad.youku.com^
||ykad-data.youku.com^
||ykad-gateway.youku.com^
||youku-acs.m.taobao.com^
||youxi.kugou.com^
||zeus.ad.xiaomi.com^
||zhihu-web-analytics.zhihu.com^
/.*\.*\.shouji\.sogou\.com/
/.*\.[a-zA-Z0-9.-]skwai\.com/
/.*\.a\.market\.xiaomi\.com/
/.*\.data\.hicloud\.com/
/.*\.log\.aliyuncs\.com/
/[a-zA-Z0-9.-]*-ad-[a-zA-Z0-9.-]*\.byteimg\.com/
/[a-zA-Z0-9.-]*-ad\.sm\.cn/
/[a-zA-Z0-9.-]*-ad\.video\.yximgs\.com/
/[a-zA-Z0-9.-]*-ad\.wtzw\.com/
/[a-zA-Z0-9.-]*-be-pack-sign\.pglstatp-toutiao\.com/
/[a-zA-Z0-9.-]*-lm\.adkwai\.com/
/[a-zA-Z0-9.-]*-normal-[a-zA-Z0-9.-]*\.zijieapi\.com/
/[a-zA-Z0-9.-]*-normal\.zijieapi\.com/
/cloudinject[a-zA-Z0-9.-]*-dev\.*\.[a-zA-Z0-9.-]*-[a-zA-Z0-9.-]*-[a-zA-Z0-9.-]*\.amazonaws\.com/

15
data/rules.txt Normal file
View File

@@ -0,0 +1,15 @@
||clarity.microsoft.com
||reke.at.sohu.com
||lb.e.so.com
||localhost.msn.cn
||c.msn.cn
||ad.*
||admin.zlhj.top
||events-sandbox.data.msn.cn
||vbng.at.sohu.com
||e.so.com
@@||www.csjplatform.com
@@||api.tw06.xlmc.sec.miui.com
@@||mpcdn.weixin.qq.com
@@||szminorshort.weixin.qq.com
@@||apd-pcdnwxlogin.teg.tencent-cloud.net

5
data/shield_stats.json Normal file
View File

@@ -0,0 +1,5 @@
{
"blockedDomainsCount": {},
"resolvedDomainsCount": {},
"lastSaved": "2026-01-16T11:02:25.950873675+08:00"
}

45104
data/stats.json Normal file

File diff suppressed because it is too large Load Diff

3
data/test_hosts.txt Normal file
View File

@@ -0,0 +1,3 @@
# Hosts文件
# 格式IP 域名
# 例如127.0.0.1 localhost

3
data/test_rules.txt Normal file
View File

@@ -0,0 +1,3 @@
# 本地规则文件
# 格式:域名
# 例如example.com

View File

@@ -0,0 +1,5 @@
{
"blockedDomainsCount": {},
"resolvedDomainsCount": {},
"lastSaved": "2025-12-16T00:38:44.046867267+08:00"
}

37
data/test_stats.json Normal file
View File

@@ -0,0 +1,37 @@
{
"stats": {
"Queries": 1,
"Blocked": 0,
"Allowed": 1,
"Errors": 0,
"LastQuery": "2025-12-16T00:38:14.408835937+08:00",
"AvgResponseTime": 6,
"TotalResponseTime": 6,
"QueryTypes": {
"A": 1
},
"SourceIPs": {
"127.0.0.1": true
},
"CpuUsage": 8.270676691729323
},
"blockedDomains": {},
"resolvedDomains": {
"google.com": {
"Domain": "google.com",
"Count": 1,
"LastSeen": "2025-12-16T00:38:14.416155945+08:00"
}
},
"clientStats": {
"127.0.0.1": {
"IP": "127.0.0.1",
"Count": 1,
"LastSeen": "2025-12-16T00:38:14.408844699+08:00"
}
},
"hourlyStats": {},
"dailyStats": {},
"monthlyStats": {},
"lastSaved": "2025-12-16T00:38:44.043395448+08:00"
}

Binary file not shown.

24
dns-server.service Normal file
View File

@@ -0,0 +1,24 @@
[Unit]
Description=Monitor Agent (Binary Service)
After=network.target
Wants=network.target
[Service]
Type=forking
User=root
Group=root
ExecStart=/root/dns/start.sh start
ExecStop=/root/dns/start.sh stop
WorkingDirectory=/root/dns
Restart=always
RestartSec=3
StartLimitInterval=60s
StartLimitBurst=5
KillSignal=SIGTERM
TimeoutStopSec=10
PrivateTmp=true
ProtectSystem=strict
NoNewPrivileges=true
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1,119 @@
# DNSSEC判断和显示逻辑分析与改进
## 1. 当前实现分析
### DNSSEC判断逻辑
1. **核心位置**`dns/server.go` 中的 `forwardDNSRequestWithCache` 函数
2. **判断流程**
- 检查配置是否启用DNSSEC (`s.config.EnableDNSSEC`)
- 从响应中提取所有DNSKEY和RRSIG记录
- 验证DNSSEC签名有效性
- 设置响应的Authenticated Data (AD) 标志
- 优先返回包含有效的DNSSEC记录的响应
- 如果没有有效的DNSSEC记录使用备选响应
### DNSSEC显示逻辑
1. **前端显示**`static/js/logs.js` 中的 `updateLogsTable` 函数
2. **显示方式**
```javascript
${log.DNSSEC ? ', <span class="text-green-500"><i class="fa fa-lock"></i> DNSSEC</span>' : ''}
```
- 当DNSSEC为true时显示绿色锁图标和"DNSSEC"文字
- 否则不显示
### DNSSEC状态存储
1. **`domainDNSSECStatus` 映射**存储域名的DNSSEC状态
2. **`resolvedDomains` 结构**包含每个域名的DNSSEC状态
3. **查询日志**每条日志记录包含DNSSEC状态
## 2. 存在的问题
1. **显示逻辑单一**只在日志页面显示DNSSEC状态没有在仪表盘或其他关键位置显示
2. **状态判断简单**只检查响应中是否包含RRSIG记录没有考虑签名验证结果
3. **缺少统计信息**没有统计使用DNSSEC的查询比例
4. **配置界面缺失**没有在配置界面提供DNSSEC相关的配置选项
5. **缺少用户反馈**用户无法直观了解当前DNSSEC的整体使用情况
## 3. 改进方案
### 3.1 增强DNSSEC判断逻辑
- **改进位置**`dns/server.go`
- **改进内容**
- 增加DNSSEC验证结果的详细记录
- 区分"DNSSEC可用"和"DNSSEC验证成功"两种状态
- 记录DNSSEC验证失败的具体原因
### 3.2 扩展DNSSEC显示范围
- **改进位置**
- `static/js/dashboard.js`在仪表盘添加DNSSEC统计卡片
- `static/js/logs.js`增强日志中的DNSSEC显示
- **改进内容**
- 在仪表盘添加"DNSSEC使用率"统计卡片
- 在TOP域名列表中显示DNSSEC状态
- 在日志记录中显示DNSSEC验证结果成功/失败/未使用)
### 3.3 添加DNSSEC配置界面
- **改进位置**:配置页面
- **改进内容**
- 添加DNSSEC启用/禁用开关
- 添加DNSSEC验证严格程度选项
- 显示当前DNSSEC状态信息
### 3.4 增强DNSSEC统计功能
- **改进位置**`dns/server.go`
- **改进内容**
- 统计DNSSEC查询总数
- 统计DNSSEC验证成功/失败次数
- 计算DNSSEC使用率
- 在API中提供DNSSEC统计数据
### 3.5 改进DNSSEC状态存储
- **改进位置**`dns/server.go`
- **改进内容**
- 增加DNSSEC验证结果的存储
- 记录DNSSEC状态的有效期
- 优化域名DNSSEC状态的更新逻辑
## 4. 实现计划
1. **第一步**增强DNSSEC判断逻辑改进验证结果记录
2. **第二步**添加DNSSEC统计功能扩展API返回数据
3. **第三步**在仪表盘添加DNSSEC统计卡片
4. **第四步**增强日志中的DNSSEC显示
5. **第五步**添加DNSSEC配置界面
6. **第六步**优化DNSSEC状态存储和更新逻辑
## 5. 预期效果
- 用户可以在仪表盘直观了解DNSSEC使用情况
- 日志中显示详细的DNSSEC验证结果
- 提供灵活的DNSSEC配置选项
- 增强DNSSEC状态的准确性和可靠性
- 提高DNSSEC相关问题的可调试性
## 6. 代码修改点
### 后端修改
- `dns/server.go`增强DNSSEC判断和统计
- `config/config.go`添加DNSSEC相关配置选项
- API接口扩展返回DNSSEC统计数据
### 前端修改
- `static/js/dashboard.js`添加DNSSEC统计卡片
- `static/js/logs.js`:增强日志显示
- 配置页面添加DNSSEC配置选项
## 7. 风险评估
- DNSSEC验证可能会增加响应延迟
- 错误的DNSSEC配置可能导致解析失败
- 增强的统计功能可能增加内存使用
## 8. 测试计划
- 测试DNSSEC启用/禁用功能
- 测试不同域名的DNSSEC显示
- 测试DNSSEC统计数据的准确性
- 测试DNSSEC验证失败时的处理逻辑
通过以上改进可以使DNSSEC判断和显示逻辑更加完善提供更好的用户体验和更详细的DNSSEC状态信息。

View File

@@ -0,0 +1,79 @@
## DNS服务器性能优化方案
### 问题分析
1. **并行查询模式**:当前配置使用`parallel`模式,会等待所有上游服务器响应后才返回,受最慢服务器影响
2. **DNSSEC验证开销**启用了DNSSEC验证增加了额外的计算和网络请求
3. **过多上游服务器**DNSSEC上游服务器多达5个响应时间差异大
4. **调试级别日志**`debug`级别日志记录大量信息占用CPU和I/O资源
5. **缓存TTL过短**10秒的缓存TTL导致频繁向上游请求
6. **黑名单规则过多**14个启用的黑名单每次请求都需要检查
### 优化方案
#### 1. 修改查询模式为快速返回
*`queryMode``parallel`改为`fastest-ip`或优化默认模式
* 快速返回模式会返回第一个有效响应,而不是等待所有响应
#### 2. 优化DNSSEC配置
* 减少DNSSEC上游服务器数量只保留2-3个可靠的
* 对国内域名禁用DNSSEC验证已配置部分可扩展
#### 3. 调整缓存策略
* 增加`cacheTTL`到60秒或更高减少上游请求频率
* 优化缓存实现,减少锁竞争
#### 4. 降低日志级别
* 将日志级别从`debug`改为`info``warn`,减少日志写入开销
#### 5. 优化黑名单处理
* 合并重复的黑名单规则
* 考虑使用更高效的域名匹配算法
#### 6. 代码优化
* 减少DNSSEC验证的重复调用
* 优化响应合并逻辑,避免不必要的计算
* 调整超时设置,避免过长等待
### 具体修改点
1. **config.json**
* 修改`queryMode``fastest-ip`
* 减少`dnssecUpstreamDNS`数量
* 增加`cacheTTL`到60
* 将日志级别改为`info`
2. **dns/server.go**
* 优化`forwardDNSRequestWithCache`函数减少DNSSEC重复验证
* 优化响应合并逻辑,避免不必要的计算
* 调整并行模式的超时处理
### 预期效果
* 减少响应时间,从当前的秒级降低到毫秒级
* 减少CPU和I/O资源占用
* 提高并发处理能力
* 保持DNS解析的准确性和可靠性

View File

@@ -0,0 +1,62 @@
# DNS查询页面实现计划
## 问题分析
目前DNS查询页面只是一个简单的占位符显示"DNS查询页面内容待实现"没有实际的功能。我需要实现完整的DNS查询功能包括
1. DNS域名查询功能
2. 查询结果展示
3. 查询历史记录
4. 响应式设计
## 解决方案
### 1. 更新HTML结构
`query-content`区域添加完整的UI组件包括
- 查询表单(域名输入框、查询按钮)
- 查询结果展示区域
- 查询历史记录
- 响应式布局设计
### 2. 实现JavaScript功能
创建或更新`query.js`文件,实现以下功能:
- 处理DNS查询请求
- 展示查询结果
- 管理查询历史
- 与后端API对接
### 3. 实现具体功能
#### 3.1 DNS域名查询
- 调用`/api/query`接口进行DNS查询
- 支持输入域名进行查询
- 显示查询结果,包括是否被屏蔽、屏蔽原因等
#### 3.2 查询结果展示
- 以清晰的方式展示查询结果
- 区分不同的查询结果状态(被屏蔽、正常、错误等)
- 显示详细的查询信息
#### 3.3 查询历史记录
- 保存查询历史到本地存储
- 支持查看历史查询记录
- 支持从历史记录中重新查询
## 实现步骤
1. **更新HTML结构**:修改`index.html`中的`query-content`区域添加完整的UI组件
2. **实现JavaScript功能**:更新`query.js`文件实现与后端API的交互
3. **测试功能**:确保所有功能正常工作
4. **优化用户体验**:添加加载状态、错误提示、成功反馈等
## 预期效果
通过以上实现DNS查询页面将具备完整的查询功能用户可以
- 输入域名进行DNS查询
- 查看详细的查询结果
- 查看查询历史记录
- 从历史记录中重新查询
页面将采用响应式设计,确保在不同屏幕尺寸下都能正常显示。

View File

@@ -0,0 +1,25 @@
## Problem
The build is failing because the HTTP server is trying to access DNSSEC-related fields (`DNSSECQueries`, `DNSSECSuccess`, `DNSSECFailed`, `DNSSECEnabled`) from the `dns.Stats` struct, but these fields don't exist in the struct definition.
## Solution
Add the missing DNSSEC-related fields to the `Stats` struct in `dns/server.go` and ensure they're properly initialized and updated.
## Implementation Steps
1. **Add DNSSEC fields to Stats struct** in `/root/dns/dns/server.go`:
- Add `DNSSECQueries int64` field
- Add `DNSSECSuccess int64` field
- Add `DNSSECFailed int64` field
- Add `DNSSECEnabled bool` field
2. **Initialize DNSSEC fields in NewServer** function:
- Set `DNSSECEnabled` based on config.EnableDNSSEC
- Initialize other DNSSEC fields to 0
3. **Update DNSSEC stats in query handling**:
- Increment `DNSSECQueries` when a DNSSEC query is processed
- Update `DNSSECSuccess` and `DNSSECFailed` based on DNSSEC validation results
4. **Test the fix** by running `go build` to ensure all errors are resolved
## Expected Outcome
The build will succeed and the HTTP server will be able to access the DNSSEC-related stats fields.

View File

@@ -0,0 +1,65 @@
# Web页面屏蔽管理功能实现计划
## 问题分析
目前web页面的屏蔽管理功能尚未完全实现主要问题包括
1. **前端UI缺失**`shield-content`区域只有简单的提示文本,没有实际的管理界面
2. **功能被禁用**`shield.js`文件中的所有功能都已被禁用无法与后端API交互
3. **缺少完整的管理功能**无法管理本地规则、远程黑名单和hosts条目
## 解决方案
### 1. 更新屏蔽管理页面HTML结构
-`shield-content`区域添加完整的UI组件
- 实现以下功能模块:
- 屏蔽规则统计信息展示
- 本地规则管理(添加、删除)
- 远程黑名单管理(添加、删除、更新)
- hosts条目管理添加、删除
### 2. 实现屏蔽管理JavaScript功能
- 重新启用并实现`shield.js`中的功能
- 与后端API对接实现完整的CRUD操作
- 添加错误处理和用户反馈
### 3. 实现具体功能
#### 3.1 屏蔽规则统计信息
- 调用`/api/shield`接口获取统计数据
- 展示规则数量、黑名单数量等信息
#### 3.2 本地规则管理
- 实现规则列表展示
- 实现添加新规则功能
- 实现删除规则功能
#### 3.3 远程黑名单管理
- 调用`/api/shield/blacklists`接口获取黑名单列表
- 实现添加新黑名单功能
- 实现删除黑名单功能
- 实现更新单个黑名单功能
#### 3.4 hosts条目管理
- 调用`/api/shield/hosts`接口获取hosts列表
- 实现添加新hosts条目功能
- 实现删除hosts条目功能
## 实现步骤
1. **更新HTML结构**:修改`index.html`中的`shield-content`区域添加完整的UI组件
2. **实现JavaScript功能**:更新`shield.js`文件实现与后端API的交互
3. **测试功能**:确保所有功能正常工作,包括添加、删除、更新操作
4. **优化用户体验**:添加加载状态、错误提示、成功反馈等
## 预期效果
通过以上实现web页面将具备完整的屏蔽管理功能用户可以
- 查看屏蔽规则统计信息
- 管理本地规则
- 管理远程黑名单
- 管理hosts条目
所有功能都将与后端API对接实现数据的实时更新和持久化存储。

View File

@@ -0,0 +1,60 @@
# Web页面适配问题解决方案
## 问题分析
通过分析当前web页面的HTML、CSS和JavaScript代码我发现了以下适配问题
1. **统计卡片布局问题**:在小屏幕设备上,统计卡片可能会出现布局问题
2. **图表布局问题**:三个图表在同一行显示,在小屏幕设备上可能会挤在一起
3. **表格溢出问题**:在小屏幕设备上,表格可能会溢出容器
4. **服务器状态组件适配问题**:在小屏幕上可能显示不全
5. **侧边栏响应式处理不完整**:当前只在窗口大小改变时更新,没有考虑其他情况
6. **图表大小更新不完整**:窗口大小改变时只更新了部分图表
7. **配置表单适配问题**:在小屏幕上的布局需要优化
## 解决方案
### 1. 优化统计卡片布局
- 修改统计卡片网格布局,增加更细粒度的响应式控制
- 在小屏幕上使用单列布局,在中等屏幕上使用双列布局,在大屏幕上使用四列布局
### 2. 改进图表布局
- 修改图表网格布局,确保在不同屏幕尺寸下都能正常显示
- 在小屏幕上使用单列布局,在中等屏幕上使用双列布局,在大屏幕上使用三列布局
### 3. 解决表格溢出问题
- 为所有表格添加响应式处理,确保在小屏幕设备上可以水平滚动
- 优化表格样式,提高在小屏幕上的可读性
### 4. 优化服务器状态组件
- 在小屏幕上简化服务器状态组件,只显示核心指标
- 添加响应式逻辑,根据屏幕尺寸动态调整显示内容
### 5. 完善侧边栏响应式处理
- 确保侧边栏在所有情况下都能正确响应屏幕尺寸变化
- 添加触摸事件支持,提高移动端体验
### 6. 完整更新图表大小
- 在窗口大小改变时,更新所有图表的大小
- 确保图表容器大小正确,避免图表变形
### 7. 优化配置表单布局
- 修改配置表单网格布局,确保在小屏幕上也能正常显示
- 调整表单元素大小和间距,提高在小屏幕上的可用性
## 实现步骤
1. 修改HTML文件中的网格布局类增加更细粒度的响应式控制
2. 更新CSS样式优化各组件在不同屏幕尺寸下的显示效果
3. 修改JavaScript代码完善响应式处理逻辑
4. 测试各组件在不同屏幕尺寸下的显示效果
5. 优化用户体验,确保在各种设备上都能正常使用
## 预期效果
通过以上优化web页面将能够在各种设备上正常显示包括
- 桌面设备(大屏幕)
- 平板设备(中等屏幕)
- 移动设备(小屏幕)
页面布局将更加灵活,能够根据屏幕尺寸自动调整,提高用户体验。

View File

@@ -0,0 +1,37 @@
## 问题分析
规则处理存在问题:`||domain` 规则应该是屏蔽一个绝对域名及其子域名,而不是正则匹配屏蔽,也不应该屏蔽所有包含该顶级域名的网站。
## 问题根源
`manager.go` 文件中,`addDomainRule` 函数第444行存在逻辑错误
1. 当添加 `||example.com` 规则时,函数正确地将 `example.com` 添加到域名规则列表中
2. 但随后,函数错误地将域名拆分为各个部分,并为每个部分添加规则
3. 例如,对于 `||example.com`,它会添加 `example.com``com` 到规则列表中
4. 这导致所有 `.com` 域名都被屏蔽,而不仅仅是 `example.com` 及其子域名
## 修复方案
修改 `addDomainRule` 函数,移除错误的子域名处理逻辑。因为 `CheckDomainBlockDetails` 函数已经实现了正确的子域名检查逻辑:它会检查域名的所有子域名部分,从最长到最短,所以不需要在添加规则时就将所有子域名都添加到规则列表中。
## 修复步骤
1. 修改 `manager.go` 文件中的 `addDomainRule` 函数
2. 移除第457-474行和第487-503行的子域名处理逻辑
3. 确保只添加精确的域名到规则列表中
4. 保持 `CheckDomainBlockDetails` 函数的子域名检查逻辑不变
## 预期效果
修复后,`||example.com` 规则将只屏蔽:
- `example.com`
- `www.example.com`
- `subdomain.example.com`
而不会屏蔽:
- `anotherexample.com`
- `google.com`
- 其他所有 `.com` 域名
这符合 AdGuard Home 规则的标准行为,即 `||example.com^` 匹配该域名及其所有子域名。

View File

@@ -0,0 +1,33 @@
## 问题分析
web界面保存配置后配置没有同步到config文件。从代码分析来看当前的`handleConfig`函数第1064行只处理了`shield`部分的配置更新而没有处理其他配置项如DNS服务器配置、HTTP服务器配置等。
## 解决方案
1. **扩展`handleConfig`函数**修改该函数以处理所有配置项包括DNS、HTTP和Log配置
2. **更新配置保存逻辑**确保所有配置都能正确保存到config.json文件中
3. **添加重启服务逻辑**:在配置保存成功后,调用重启服务的逻辑,确保配置更改能立即生效
## 修复步骤
1. 修改`server.go`文件中的`handleConfig`函数
- 扩展请求结构,包含所有配置项
- 更新配置处理逻辑处理DNS、HTTP和Log配置
- 确保所有配置都能正确保存到config.json文件中
2. 修改`handleConfig`函数的返回逻辑
- 在配置保存成功后,调用重启服务的逻辑
- 返回更详细的成功信息
3. 测试修复效果
- 确保web界面上的所有配置项都能正确保存到config.json文件中
- 确保服务能在配置保存后正确重启
## 预期效果
修复后当用户在web界面点击"保存配置"按钮时:
1. 所有配置项包括DNS、HTTP、Shield和Log配置都会被保存到config.json文件中
2. 服务器会自动重启,使配置更改生效
3. 用户会看到配置保存成功的提示
这将确保用户在web界面上的所有配置更改都能正确保存和生效。

View File

@@ -0,0 +1,38 @@
## 修复API不可用问题
### 问题分析
1. **配置文件中API被禁用**:在`config.json`中,`http.enableAPI`设置为`false`
2. **缺少默认启用配置**:在`config/config.go``LoadConfig`函数中,没有为`EnableAPI`设置默认值
3. **API路由条件注册**:在`http/server.go`所有API端点都在`if s.config.EnableAPI`条件下注册
### 解决方案
#### 1. 修改配置文件启用API
`config.json`中的`http.enableAPI`值从`false`改为`true`立即启用API功能。
#### 2. 设置API默认启用
`config/config.go``LoadConfig`函数中添加默认值设置确保API在配置文件未指定时自动启用
```go
if !config.HTTP.EnableAPI {
config.HTTP.EnableAPI = true
}
```
### 实施步骤
1. 编辑`config.json`文件,将`http.enableAPI`设置为`true`
2. 修改`config/config.go`,在`LoadConfig`函数中添加API默认启用逻辑
3. 重启服务使配置生效
### 预期结果
- API端点将可用包括
- `/api/stats` - 统计信息
- `/api/shield` - 屏蔽规则管理
- `/api/shield/localrules` - 本地规则
- `/api/shield/remoterules` - 远程规则
- `/api/query` - DNS查询
- 以及其他统计和管理端点
- Swagger UI页面可通过`/api`访问
### 文件修改清单
1. `config.json` - 启用API
2. `config/config.go` - 添加API默认启用配置

View File

@@ -0,0 +1,21 @@
# DNSSEC记录缺失问题修复计划
## 问题分析
从日志中可以看到所有DNS查询都显示"DNS响应不包含DNSSEC记录"这表明虽然DNSSEC被启用但服务器没有从上游DNS服务器获取到DNSSEC记录。
## 根本原因
当启用DNSSEC时DNS服务器需要在发送给上游服务器的请求中设置**DNSSEC OK (DO)标志**这样上游服务器才会返回DNSSEC记录如RRSIG、DNSKEY等。但当前代码直接使用原始请求发送给上游服务器没有添加DO标志。
## 修复方案
修改`forwardDNSRequestWithCache`函数,在向上游服务器发送请求之前:
1. 检查是否启用了DNSSEC
2. 如果启用为请求添加EDNS0选项并设置DO标志
3. 确保修改后的请求被正确发送
## 具体实现步骤
1.`/root/dns/dns/server.go`文件中,找到`forwardDNSRequestWithCache`函数
2. 在发送请求前第625行附近添加DO标志设置逻辑
3. 确保请求被正确发送到上游服务器
## 预期效果
修复后启用DNSSEC时服务器会向上游发送带有DO标志的请求上游服务器将返回DNSSEC记录从而实现完整的DNSSEC验证和记录返回。

View File

@@ -0,0 +1,82 @@
# DNSSEC功能修复计划
## 问题分析
当前DNSSEC实现存在以下问题
1. 当启用DNSSEC时系统只是验证上游服务器返回的DNSSEC签名但不会主动请求DNSSEC记录
2. 当上游服务器返回的响应没有DNSSEC记录时系统只是将其作为备选响应
3. 没有专门从8.8.8.8/1.1.1.1获取DNSSEC记录进行验证
4. 缓存时没有优先考虑DNSSEC记录
## 修复方案
### 1. 改进DNS请求转发逻辑
**修改文件:** `dns/server.go`
**修改函数:** `forwardDNSRequestWithCache`
- 当启用DNSSEC且响应中没有DNSSEC记录时主动向8.8.8.8/1.1.1.1发送DNS请求
- 比较不同服务器返回的结果优先使用带有DNSSEC记录的响应
- 如果DNSSEC结果不匹配优先使用8.8.8.8/1.1.1.1提供的解析记录
### 2. 增强DNSSEC验证机制
**修改文件:** `dns/server.go`
- 完善DNSSEC记录提取和验证逻辑
- 确保正确处理DNSKEY和RRSIG记录
- 改进AD标志Authenticated Data的设置
### 3. 优化缓存机制
**修改文件:** `dns/cache.go``dns/server.go`
- 缓存时标记DNSSEC状态
- 优先返回带有DNSSEC记录的缓存项
- 改进缓存键生成考虑DNSSEC属性
### 4. 增加DNSSEC特定服务器配置
**修改文件:** `config.json`
- 添加专门用于DNSSEC查询的服务器配置
- 默认为8.8.8.8和1.1.1.1
## 具体实现步骤
1. **修改`forwardDNSRequestWithCache`函数**
- 当启用DNSSEC且主响应没有DNSSEC记录时向DNSSEC专用服务器发送请求
- 比较所有响应选择最优结果优先DNSSEC记录其次是可靠服务器
- 实现DNSSEC结果验证和比较逻辑
2. **改进缓存获取逻辑**
-`handleDNSRequest`函数中优先检查是否有带有DNSSEC记录的缓存项
- 如果有,直接返回;否则再检查普通缓存项
3. **优化DNSSEC记录验证**
- 增强`verifyDNSSEC`函数的实现
- 确保正确验证所有RRSIG记录
- 改进错误处理和日志记录
4. **添加DNSSEC服务器配置**
- 在配置文件中添加`dnssecUpstreamDNS`配置项
- 默认值为["8.8.8.8:53", "1.1.1.1:53"]
## 测试计划
1. 启动DNS服务器启用DNSSEC
2. 使用`dig`命令测试DNSSEC记录获取
3. 验证带有DNSSEC记录的响应被正确返回
4. 验证缓存机制优先返回DNSSEC记录
5. 测试DNSSEC验证失败时的处理逻辑
## 预期效果
1. 启用DNSSEC后系统会主动请求并验证DNSSEC记录
2. 优先返回带有DNSSEC记录的解析结果
3. 当DNSSEC结果不匹配时优先使用8.8.8.8/1.1.1.1提供的记录
4. 缓存机制正确处理DNSSEC标记优先返回DNSSEC记录
5. 完善的日志记录,便于调试和监控
## 代码修改范围
- `dns/server.go`核心DNSSEC逻辑修改
- `dns/cache.go`:缓存机制优化
- `config.json`:配置项添加
通过以上修改将解决当前DNSSEC功能的问题确保启用DNSSEC后能够正确获取、验证和返回DNSSEC记录。

View File

@@ -0,0 +1,58 @@
# DNSSEC状态显示问题修复计划
## 问题分析
用户报告已在配置中启用DNSSEC`enableDNSSEC: true`但界面显示DNSSEC为禁用状态且使用率为0%。经过代码检查,发现问题出在`GetStats`函数中,该函数返回的`Stats`结构体缺少DNSSEC相关字段导致前端无法获取正确的DNSSEC状态和统计信息。
## 修复方案
### 1. 修复`GetStats`函数
**修改文件:** `dns/server.go`
**修改函数:** `GetStats`
**问题:** 当前`GetStats`函数返回的`Stats`结构体缺少DNSSEC相关字段包括
* `DNSSECEnabled`
* `DNSSECQueries`
* `DNSSECSuccess`
* `DNSSECFailed`
**解决方案:**`GetStats`函数返回的`Stats`结构体中添加所有DNSSEC相关字段确保前端能获取到正确的DNSSEC状态和统计数据。
## 具体实现步骤
1. **修改`GetStats`函数**
* 在返回的`Stats`结构体中添加`DNSSECEnabled`字段
* 添加`DNSSECQueries`字段
* 添加`DNSSECSuccess`字段
* 添加`DNSSECFailed`字段
2. **测试修复效果**
* 重新编译DNS服务器
* 启动服务器
* 使用API查询统计信息确认DNSSEC状态和统计数据正确返回
* 检查前端界面是否显示正确的DNSSEC状态
## 预期效果
1. 前端界面显示DNSSEC状态为"已启用"
2. DNSSEC使用率根据实际查询情况更新
3. 成功、失败和总查询数统计正确显示
4. 系统正常记录DNSSEC相关统计数据
## 代码修改范围
* `dns/server.go`:修复`GetStats`函数添加缺失的DNSSEC字段

View File

@@ -0,0 +1,52 @@
1. **修改QueryLog结构体**
*`dns/server.go`中的`QueryLog`结构体添加`ResponseCode`字段
2. **修改addQueryLog函数**
*`dns/server.go`中的`addQueryLog`函数添加`responseCode`参数
* 将响应代码记录到QueryLog结构体中
3. **修改DNS请求处理逻辑**
*`handleDNSRequest`函数中,获取实际的响应代码
* 将响应代码传递给`addQueryLog`函数
4. **修改前端模板**
*`static/js/logs.js`中,将响应代码的硬编码值"无"替换为从日志数据中获取的实际响应代码
* 添加响应代码映射,将数字响应代码转换为可读的字符串
5. **编译和测试**
* 重新编译项目
* 测试DNS查询详情中响应代码是否正确显示
**DNS响应代码映射**
* 0: NOERROR
* 1: FORMERR
* 2: SERVFAIL
* 3: NXDOMAIN
* 4: NOTIMP
* 5: REFUSED
* 6: YXDOMAIN
* 7: YXRRSET
* 8: NXRRSET
* 9: NOTAUTH
* 10: NOTZONE

View File

@@ -0,0 +1,42 @@
1. **调整DNS超时时间**
* 将配置文件中的`timeout`值从5毫秒增加到5000毫秒5秒
* 5毫秒的超时时间对于DNS查询来说太短导致大部分查询都超时失败
2. **优化查询模式**
* 将查询模式从`parallel`(并行)改为`loadbalance`(负载均衡)
* 并行模式在短超时时间下会导致大量超时,负载均衡模式更可靠
3. **检查上游DNS服务器配置**
* 确保所有配置的上游DNS服务器都能正常工作
* 移除或调整可能不可达的DNS服务器
4. **调整DNSSEC配置**
* 检查DNSSEC专用服务器的可达性
* 考虑暂时禁用DNSSEC验证观察是否能改善性能
5. **增强错误处理**
* 优化`forwardDNSRequestWithCache`函数的错误处理逻辑
* 确保在所有服务器都超时的情况下有合理的回退机制
6. **监控和日志优化**
* 添加更详细的日志记录每个DNS服务器的响应情况
* 增加监控指标追踪DNS查询成功率和响应时间
7. **测试验证**
* 在修改后进行DNS查询测试确保服务器能正常响应
* 监控日志确认不再出现大量DNS查询失败的情况

View File

@@ -0,0 +1,53 @@
## 问题分析
DNS服务器出现"Server Failed"的根本原因是当用户配置的DNS服务器地址没有包含端口号时代码直接将其传递给`dns.Client.Exchange()`方法,而该方法需要完整的"IP:端口"格式地址。
## 解决方案
### 1. 创建DNS服务器地址处理函数
- **功能**确保DNS服务器地址始终包含端口号默认添加53端口
- **实现**:创建`normalizeDNSServerAddress`函数,检查并添加端口号
### 2. 应用地址处理函数到所有DNS服务器配置
**需要修改的位置**
- **主DNS服务器**`s.config.UpstreamDNS`
- **DNSSEC专用服务器**`s.config.DNSSECUpstreamDNS`
- **域名特定DNS服务器**`s.config.DomainSpecificDNS`
- **所有调用`resolver.Exchange()`的地方**:确保传递的服务器地址包含端口号
### 3. 修改具体代码位置
**文件**`dns/server.go`
**修改点**
1. **添加地址处理函数**:在文件中添加`normalizeDNSServerAddress`函数
2. **在parallel模式中使用**修改第865行附近的代码
3. **在loadbalance模式中使用**修改第1063行附近的代码
4. **在fastest-ip模式中使用**修改第1189行附近的代码
5. **在default模式中使用**修改第1311行附近的代码
6. **在DNSSEC专用服务器请求中使用**修改第1452行附近的代码
7. **在本地解析中使用**修改第1550行附近的代码
### 4. 确保配置文件加载时也处理地址
- 检查配置文件加载代码确保在加载配置时就处理DNS服务器地址
- 或者在每次使用DNS服务器地址时动态处理
## 修复步骤
1. **创建地址处理函数**:实现`normalizeDNSServerAddress`函数
2. **修改所有DNS查询点**:在所有调用`resolver.Exchange()`的地方使用该函数
3. **测试修复效果**重启DNS服务器并测试查询功能
4. **验证各种配置场景**测试带端口和不带端口的DNS服务器配置
## 预期效果
- 当用户配置DNS服务器为`223.5.5.5`时,自动添加端口变为`223.5.5.5:53`
- 当用户配置DNS服务器为`8.8.8.8:53`时,保持不变
- DNS查询成功率显著提高不再出现"Server Failed"错误
- 支持各种DNS服务器配置格式提高系统兼容性
## 关键文件修改
- `/root/dns/dns/server.go`添加地址处理函数并应用到所有DNS查询点

View File

@@ -0,0 +1,52 @@
## 问题分析
当前DNS服务器的解析记录显示存在以下问题
1. 前端`logs.js`中使用了`console.log`来调试和显示解析记录
2. 需要确保API返回的解析记录是正确的JSON格式
3. 前端需要正确解析API返回的JSON数据来显示解析记录
## 解决方案
### 1. 优化API返回格式
**文件**`dns/server.go`
**修改内容**
- 确保`QueryLog`结构体的`Answers`字段正确序列化为JSON
- 检查`DNSAnswer`结构体的JSON标签是否正确
### 2. 清理前端console.log代码
**文件**`static/js/logs.js`
**修改内容**
- 删除或注释掉第1047、1054行等console.log调试代码
- 优化解析记录提取逻辑确保正确处理API返回的JSON数据
### 3. 优化解析记录显示逻辑
**文件**`static/js/logs.js`
**修改内容**
- 完善`extractDNSRecords`函数,确保正确处理各种格式的解析记录
- 优化解析记录的HTML渲染逻辑确保显示格式清晰
- 确保支持`log.answers`字段(小写)和`log.Answers`字段(大写)
### 4. 测试验证
**步骤**
- 重启DNS服务器
- 使用API测试工具验证`/api/logs/query`返回的解析记录格式正确
- 测试前端页面解析记录显示正常
## 预期效果
- API返回的解析记录格式为标准JSON
- 前端页面不再使用console.log显示解析记录
- 解析记录显示清晰、格式统一
- 支持各种情况下的解析记录提取
## 关键文件修改
1. **`dns/server.go`**:确保解析记录正确序列化
2. **`static/js/logs.js`**优化解析记录显示逻辑移除console.log代码

View File

@@ -0,0 +1,43 @@
## 问题分析
当前服务器代码存在以下问题:
1. `QueryLog`结构体中只有部分字段有JSON标签
2. 缺少完整的JSON序列化支持导致API返回的JSON格式不完整
3. 需要确保所有字段都能正确序列化为JSON
## 解决方案
### 1. 完善QueryLog结构体的JSON标签
**文件**`dns/server.go`
**修改内容**
-`QueryLog`结构体的所有字段添加正确的JSON标签
- 确保`Timestamp`字段正确序列化为ISO格式时间
- 确保`Answers`字段序列化为`"answers"`(小写)
### 2. 确保API返回完整的JSON数据
**文件**`http/server.go`
**修改内容**
- 检查`handleLogsQuery`函数,确保返回完整的日志数据
- 确保日志查询API返回包含所有必要字段的JSON数据
### 3. 测试验证
**步骤**
- 重启DNS服务器
- 使用API测试工具验证`/api/logs/query`返回的JSON格式正确
- 确保所有字段都正确序列化
## 预期效果
- API返回的JSON数据包含所有日志字段
- 前端能够正确解析API返回的JSON数据
- 解析记录通过API查询方式显示不再使用console.log
## 关键文件修改
1. **`dns/server.go`**:完善`QueryLog`结构体的JSON标签
2. **`http/server.go`**确保API返回完整的JSON数据

View File

@@ -0,0 +1,31 @@
## 问题分析
从用户提供的截图可以看到解析记录显示存在问题只显示了IP地址"104.26.24.30",而没有完整的解析记录格式,如"A: 104.26.24.30 (ttl=193)"。
## 根本原因
通过分析代码,发现问题可能出在以下几个方面:
1. 解析记录的显示样式可能存在问题
2. 或者在生成解析记录字符串时出现了问题
3. 或者是在处理`dnsAnswers`数组时出现了问题
## 修复方案
1. 修改解析记录的生成逻辑确保完整显示记录类型、值和TTL
2. 检查并调整HTML元素的样式确保多行文本正确显示
## 具体修改点
1. **修改解析记录的生成逻辑**
-`showLogDetailModal`函数中修改解析记录的生成逻辑确保即使记录类型或TTL为空也能正确显示
- 确保每个解析记录都按照"类型: 值 (ttl=TTL)"的格式显示
2. **调整HTML元素的样式**
- 检查并调整解析记录显示容器的样式,确保多行文本正确显示
- 确保`whitespace-pre-wrap`样式正确应用
## 修复原则
- 确保解析记录完整显示包括记录类型、值和TTL
- 保持良好的可读性
- 确保样式兼容各种浏览器
## 验证方法
1. 修复代码后,重新加载页面
2. 查看解析记录是否完整显示包括记录类型、值和TTL
3. 测试不同类型的解析记录,确保都能正确显示

View File

@@ -0,0 +1,34 @@
## 移除查询日志详情中的屏蔽规则列
### 1. 问题分析
- 用户要求移除查询日志详情弹窗中的屏蔽规则列
- 屏蔽规则列位于响应细节部分,显示在响应时间和响应代码之间
- 该列显示了DNS查询被屏蔽时的规则信息
### 2. 实现方案
- 编辑`showLogDetailModal`函数找到响应细节部分的HTML模板
- 移除其中包含"规则"标题和`${blockRule}`变量的整个div元素
- 保持其他响应细节(响应时间、响应代码、缓存状态)不变
### 3. 代码修改
- 修改文件:`/root/dns/static/js/logs.js`
- 修改函数:`showLogDetailModal`
- 移除位置:响应细节部分的`responseGrid` HTML模板
- 移除内容:包含"规则"标题和`${blockRule}`变量的div元素
### 4. 预期效果
- 查询日志详情弹窗中将不再显示屏蔽规则列
- 响应细节部分将只显示:响应时间、响应代码、缓存状态
- 保持弹窗的整体布局和样式不变
- 不影响其他功能的正常运行
### 5. 技术细节
- 使用HTML模板字符串修改DOM结构
- 移除不必要的DOM元素简化UI
- 保持代码的可读性和可维护性
### 6. 测试验证
- 验证修改后的代码是否有语法错误
- 验证查询日志详情弹窗是否正常显示
- 验证屏蔽规则列已被成功移除
- 验证其他功能是否正常工作

View File

@@ -0,0 +1,56 @@
## 移除查询日志详情中的屏蔽规则列
### 1. 问题分析
* 用户要求移除查询日志详情弹窗中的屏蔽规则列
* 屏蔽规则列位于响应细节部分,显示在响应时间和响应代码之间
* 该列显示了DNS查询被屏蔽时的规则信息
### 2. 实现方案
* 编辑`showLogDetailModal`函数找到响应细节部分的HTML模板
* 移除其中包含"规则"标题和`${blockRule}`变量的整个div元素
* 保持其他响应细节(响应时间、响应代码、缓存状态)不变
### 3. 代码修改
* 修改文件:`/root/dns/static/js/logs.js`
* 修改函数:`showLogDetailModal`
* 移除位置:响应细节部分的`responseGrid` HTML模板
* 移除内容:包含"规则"标题和`${blockRule}`变量的div元素
### 4. 预期效果
* 查询日志详情弹窗中将不再显示屏蔽规则列
* 响应细节部分将只显示:响应时间、响应代码、缓存状态
* 保持弹窗的整体布局和样式不变
* 不影响其他功能的正常运行
### 5. 技术细节
* 使用HTML模板字符串修改DOM结构
* 移除不必要的DOM元素简化UI
* 保持代码的可读性和可维护性
### 6. 测试验证
* 验证修改后的代码是否有语法错误
* 验证查询日志详情弹窗是否正常显示
* 验证屏蔽规则列已被成功移除
* 验证其他功能是否正常工作

View File

@@ -0,0 +1,51 @@
## 优化DNS请求处理逻辑减少返回客户端超时
### 1. 问题分析
* 服务器请求上游解析成功,但返回给客户端超时
* 主要原因是`forwardDNSRequestWithCache`函数等待所有上游服务器响应,导致某个慢服务器拖慢整体响应
* 虽然是并行查询,但没有实现快速响应返回机制
* 阻塞式等待所有响应完成,而不是优先返回最快的成功响应
### 2. 实现方案
* 优化`forwardDNSRequestWithCache`函数,实现快速响应返回机制
* 当收到第一个成功响应时,立即返回给客户端,不再等待其他服务器响应
* 保持后台继续接收其他响应,更新最佳响应和服务器状态
* 优化并行查询逻辑,提高响应速度
* 保持代码的可读性和可维护性
### 3. 代码修改
* 修改文件:`/root/dns/dns/server.go`
* 修改函数:`forwardDNSRequestWithCache`
* 优化位置:`parallel`模式和`default`模式下的响应处理逻辑
* 优化内容:
- 实现快速响应返回机制
- 当收到第一个成功响应时,立即返回给客户端
- 保持后台处理其他响应
- 优化并行查询逻辑
### 4. 预期效果
* 减少DNS查询的平均响应时间
* 避免因某个上游服务器响应慢而导致整体超时
* 提高DNS服务器的吞吐量和并发处理能力
* 保持对上游服务器状态的准确跟踪
* 不影响现有功能的正常运行
### 5. 技术细节
* 使用通道和goroutine实现非阻塞响应处理
* 当收到第一个成功响应时,立即返回给客户端
* 保持后台继续接收其他响应,更新最佳响应和服务器状态
* 优化并行查询逻辑,提高响应速度
* 保持代码的可读性和可维护性
### 6. 测试验证
* 验证修改后的代码是否有语法错误
* 验证DNS查询响应时间是否明显减少
* 验证是否解决了返回客户端超时的问题
* 验证其他功能是否正常工作
* 验证上游服务器状态跟踪是否准确

View File

@@ -0,0 +1,78 @@
## 优化DNS请求处理逻辑减少返回客户端超时
### 1. 问题分析
* 服务器请求上游解析成功,但返回给客户端超时
* 主要原因是`forwardDNSRequestWithCache`函数等待所有上游服务器响应,导致某个慢服务器拖慢整体响应
* 虽然是并行查询,但没有实现快速响应返回机制
* 阻塞式等待所有响应完成,而不是优先返回最快的成功响应
### 2. 实现方案
* 优化`forwardDNSRequestWithCache`函数,实现快速响应返回机制
* 当收到第一个成功响应时,立即返回给客户端,不再等待其他服务器响应
* 保持后台继续接收其他响应,更新最佳响应和服务器状态
* 优化并行查询逻辑,提高响应速度
* 保持代码的可读性和可维护性
### 3. 代码修改
* 修改文件:`/root/dns/dns/server.go`
* 修改函数:`forwardDNSRequestWithCache`
* 优化位置:`parallel`模式和`default`模式下的响应处理逻辑
* 优化内容:
* 实现快速响应返回机制
* 当收到第一个成功响应时,立即返回给客户端
* 保持后台处理其他响应
* 优化并行查询逻辑
### 4. 预期效果
* 减少DNS查询的平均响应时间
* 避免因某个上游服务器响应慢而导致整体超时
* 提高DNS服务器的吞吐量和并发处理能力
* 保持对上游服务器状态的准确跟踪
* 不影响现有功能的正常运行
### 5. 技术细节
* 使用通道和goroutine实现非阻塞响应处理
* 当收到第一个成功响应时,立即返回给客户端
* 保持后台继续接收其他响应,更新最佳响应和服务器状态
* 优化并行查询逻辑,提高响应速度
* 保持代码的可读性和可维护性
### 6. 测试验证
* 验证修改后的代码是否有语法错误
* 验证DNS查询响应时间是否明显减少
* 验证是否解决了返回客户端超时的问题
* 验证其他功能是否正常工作
* 验证上游服务器状态跟踪是否准确

View File

@@ -0,0 +1,20 @@
# 修复域名匹配机制问题
## 问题分析
通过详细检查domain-info.json文件我发现了问题的根本原因
- JSON文件的结构存在错误`domains`对象只包含了网易公司
- 其他公司(如阿里云、百度等)被错误地放在了`domains`对象之外
- 这导致域名匹配机制只能找到网易公司的信息,而无法匹配其他公司
## 修复计划
1. **修复JSON文件结构**:将所有公司信息正确地包含在`domains`对象中
2. **优化域名匹配逻辑**根据用户需求实现优先匹配完整URL域名再匹配主域名的逻辑
3. **测试修复效果**:验证所有公司的域名都能被正确匹配
## 预期效果
- 修复后的JSON文件结构正确所有公司都包含在`domains`对象中
- 域名匹配机制能够正确识别所有公司的域名
- 匹配规则:
- 优先匹配完整URL域名如baike.baidu.com
- 如果没有匹配上则匹配主域名如baidu.com
- 输出对应的公司名称(如北京百度网讯科技有限公司)

View File

@@ -0,0 +1,33 @@
## 问题分析
通过测试脚本的输出我发现了kdocs.cn无法匹配到域名信息的原因
1. **JSON结构错误**domain-info.json文件中字节跳动公司的结构存在错误导致解析后的对象结构不正确。
2. **遍历顺序问题**由于JSON结构错误当遍历到字节跳动公司时脚本没有正确跳过company属性而是继续处理字节跳动对象内部的属性然后遇到了一个名为"company"的公司这个公司的属性值是categories对象的值。
3. **遍历不完整**由于结构错误脚本在遍历到字节跳动公司后就无法继续遍历到金山办公公司而金山办公公司正是kdocs.cn所属的公司。
## 解决方案
### 1. 修复domain-info.json文件的结构
修复字节跳动公司的结构错误,确保其包含正确的闭合括号和逗号:
- 修复抖音视频对象的闭合括号
- 确保今日头条API服务和豆包对象是字节跳动公司的直接子对象
- 确保company属性是字节跳动公司的直接子属性
### 2. 测试修复效果
修复后重新运行测试脚本验证kdocs.cn和www.kdocs.cn能够正确匹配到金山办公公司的金山文档。
## 实施步骤
1. 修改domain-info.json文件修复字节跳动公司的结构错误
2. 运行test-fetch.js测试脚本验证修复效果
3. 确认kdocs.cn和www.kdocs.cn能够正确匹配到域名信息
## 预期效果
修复后kdocs.cn和www.kdocs.cn将能够正确匹配到金山办公公司的金山文档显示网站名称、图标、类别和所属公司。

View File

@@ -0,0 +1,32 @@
# 移除负载均衡查询模式
## 问题分析
用户要求移除负载均衡查询模式,目前代码中支持多种查询模式,包括 "loadbalance"(负载均衡)、"parallel"(并行请求)、"fastest-ip"最快的IP地址。负载均衡模式使用加权随机选择算法来选择上游服务器。
## 解决方案
1. 从配置中移除 "loadbalance" 作为可用选项
2. 从代码中移除 "loadbalance" 分支
3. 确保其他使用 `selectWeightedRandomServer` 函数的地方不受影响
## 实施步骤
1. 修改 `config/config.go` 文件,更新 `QueryMode` 字段的注释,移除 "loadbalance" 选项
2. 修改 `dns/server.go` 文件,移除 switch 语句中的 "loadbalance" 分支
3. 确保所有使用 `selectWeightedRandomServer` 函数的地方仍然正常工作
4. 测试修改后的代码,确保 DNS 服务器仍然正常运行
## 修改内容
- 文件:`/root/dns/config/config.go`
- 修改点:更新 `QueryMode` 字段的注释,移除 "loadbalance" 选项
- 文件:`/root/dns/dns/server.go`
- 修改点:移除 switch 语句中的 "loadbalance" 分支第1139-1260行
## 预期效果
- 负载均衡查询模式将不再可用
- DNS 服务器仍然支持其他查询模式parallel、fastest-ip
- 其他功能不受影响
- 代码更加简洁,减少了维护成本
## 注意事项
- `selectWeightedRandomServer` 函数不仅用于负载均衡模式,还用于选择 DNSSEC 服务器和本地服务器,所以不能删除这个函数
- 确保修改后所有其他功能仍然正常工作

View File

@@ -0,0 +1,32 @@
# 清理无关代码
## 问题分析
我已经成功移除了负载均衡查询模式的主要代码,但还有一些相关的残留代码需要清理,包括:
1. CHANGELOG.md文件中提到了loadbalance模式
2. 可能还有其他未使用的代码或配置
## 解决方案
1. 更新CHANGELOG.md文件移除或修改与loadbalance模式相关的条目
2. 检查是否有其他未使用的代码或配置
3. 确保所有修改都不会影响现有功能
## 实施步骤
1. 修改CHANGELOG.md文件移除或修改与loadbalance模式相关的条目
2. 检查是否有其他未使用的代码或配置
3. 编译并测试修改后的代码,确保功能正常
## 修改内容
- 文件:`/root/dns/CHANGELOG.md`
- 修改点1第106行移除或修改与loadbalance模式相关的条目
- 修改点2第112行移除或修改与loadbalance模式相关的条目
## 预期效果
- 代码库中不再有与已移除功能相关的残留代码
- 文档与实际代码保持一致
- 现有功能不受影响
- 代码库更加整洁,易于维护
## 注意事项
- 不要修改数据文件中的loadbalance相关规则这些是广告过滤规则不是代码
- 确保所有修改都不会影响现有功能
- 编译并测试修改后的代码,确保功能正常

View File

@@ -0,0 +1,113 @@
## 支持Base64编码GFWList格式的实现计划
### 问题分析
当前的GFWList加载代码直接按行解析文件内容无法处理Base64编码的GFWList格式。Base64编码的GFWList文件包含
1. 头部注释行(以!开头)
2. Base64编码的规则内容整个文件或主要部分
3. 可能的尾部注释
### 解决方案
修改`gfw/manager.go`中的`LoadRules`函数添加Base64解码支持
1. **检测Base64编码**
- 读取文件内容
- 跳过注释行
- 检查剩余内容是否为Base64编码
2. **解码Base64内容**
- 如果是Base64编码使用`encoding/base64`包解码
- 解码后得到原始规则文本
3. **解析规则**
- 按行分割解码后的内容
- 调用现有的`parseRule`函数处理每一行
### 具体修改点
1. **添加Base64依赖**
-`gfw/manager.go`中添加`encoding/base64`导入
2. **修改LoadRules函数**
- 读取文件内容
- 过滤注释行收集可能的Base64内容
- 尝试Base64解码
- 解析解码后的规则
3. **测试**
- 使用现有的Base64编码GFWList文件测试
- 确保解码和规则解析正常工作
### 预期效果
- 服务器能够正确加载Base64编码的GFWList文件
- 兼容现有的纯文本GFWList格式
- 规则解析结果与原格式一致
### 代码修改示例
```go
// 在import中添加encoding/base64
import (
// 现有导入
"encoding/base64"
// 现有导入
)
// 修改LoadRules函数
func (m *GFWListManager) LoadRules() error {
// 现有代码...
// 从文件路径读取GFWList内容
content, err := os.ReadFile(m.config.Content)
if err != nil {
return fmt.Errorf("读取GFWList文件失败: %w", err)
}
// 处理Base64编码
rawContent := string(content)
// 过滤注释行收集Base64内容
var base64Content strings.Builder
lines := strings.Split(rawContent, "\n")
for _, line := range lines {
line = strings.TrimSpace(line)
if line == "" || strings.HasPrefix(line, "!") || strings.HasPrefix(line, "[") {
// 跳过注释行和头信息
continue
}
base64Content.WriteString(line)
}
// 尝试Base64解码
decoded, err := base64.StdEncoding.DecodeString(base64Content.String())
if err == nil {
// 解码成功,使用解码后的内容
rawContent = string(decoded)
} else {
// 解码失败,使用原始内容(可能是纯文本格式)
}
// 按行解析规则
ruleLines := strings.Split(rawContent, "\n")
for _, line := range ruleLines {
line = strings.TrimSpace(line)
if line == "" || strings.HasPrefix(line, "!") || strings.HasPrefix(line, "[") {
// 跳过空行、注释行和头信息行
continue
}
m.parseRule(line)
}
// 现有代码...
}
```
### 实施步骤
1. 修改`gfw/manager.go`添加Base64支持
2. 编译并测试
3. 验证规则加载是否正常
这个修改将使服务器能够同时支持纯文本和Base64编码的GFWList格式提高了兼容性和灵活性。

View File

@@ -0,0 +1,203 @@
# 平均响应时间计算错误修复方案
## 问题分析
通过对代码的分析,我发现平均响应时间计算错误的根本原因是:
1. **统计数据持久化问题**:当服务器重启时,`loadStatsData` 函数直接覆盖 `s.stats` 对象,导致 `TotalResponseTime``Queries` 之间的关系可能被破坏
2. **异常响应时间累计**:在某些情况下,`responseTime` 可能被错误计算为非常大的值,导致 `TotalResponseTime` 异常增长
3. **计算逻辑不健壮**:平均响应时间计算没有考虑异常情况,如 `Queries` 为 0 或 `TotalResponseTime` 溢出
4. **统计数据一致性问题**:并发访问时可能导致统计数据不一致
## 修复方案
### 1. 修复 `loadStatsData` 函数
修改统计数据加载逻辑,确保 `TotalResponseTime``Queries` 之间的关系正确:
```go
// 恢复统计数据
s.statsMutex.Lock()
if statsData.Stats != nil {
// 只恢复有效数据,避免破坏统计关系
s.stats.Queries += statsData.Stats.Queries
s.stats.Blocked += statsData.Stats.Blocked
s.stats.Allowed += statsData.Stats.Allowed
s.stats.Errors += statsData.Stats.Errors
s.stats.TotalResponseTime += statsData.Stats.TotalResponseTime
s.stats.DNSSECQueries += statsData.Stats.DNSSECQueries
s.stats.DNSSECSuccess += statsData.Stats.DNSSECSuccess
s.stats.DNSSECFailed += statsData.Stats.DNSSECFailed
// 重新计算平均响应时间,确保一致性
if s.stats.Queries > 0 {
s.stats.AvgResponseTime = float64(s.stats.TotalResponseTime) / float64(s.stats.Queries)
}
// 合并查询类型统计
for k, v := range statsData.Stats.QueryTypes {
s.stats.QueryTypes[k] += v
}
// 合并来源IP统计
for ip := range statsData.Stats.SourceIPs {
s.stats.SourceIPs[ip] = true
}
// 确保使用当前配置中的EnableDNSSEC值
s.stats.DNSSECEnabled = s.config.EnableDNSSEC
}
s.statsMutex.Unlock()
```
### 2. 修复响应时间计算逻辑
`handleDNSRequest` 函数中,添加响应时间合理性检查:
```go
// 使用上游服务器的实际响应时间(转换为毫秒)
responseTime := int64(rtt.Milliseconds())
// 如果rtt为0查询失败则使用本地计算的时间
if responseTime == 0 {
responseTime = time.Since(startTime).Milliseconds()
}
// 添加合理性检查,避免异常大的响应时间影响统计
if responseTime > 60000 { // 超过60秒的响应时间视为异常
responseTime = 60000
}
```
### 3. 优化平均响应时间计算
修改 `updateStats` 函数,确保平均响应时间计算的健壮性:
```go
s.updateStats(func(stats *Stats) {
stats.TotalResponseTime += responseTime
// 添加防御性编程确保Queries大于0
if stats.Queries > 0 {
// 使用更精确的计算方式,避免浮点数精度问题
stats.AvgResponseTime = float64(stats.TotalResponseTime) / float64(stats.Queries)
// 限制平均响应时间的范围,避免显示异常大的值
if stats.AvgResponseTime > 60000 {
stats.AvgResponseTime = 60000
}
}
})
```
### 4. 添加统计数据重置机制
添加定期重置统计数据的功能,避免 `TotalResponseTime` 无限增长:
```go
// Start 启动DNS服务器
func (s *Server) Start() error {
// 现有代码...
// 启动统计数据定期重置功能每24小时
go func() {
ticker := time.NewTicker(24 * time.Hour)
defer ticker.Stop()
for {
select {
case <-ticker.C:
s.resetStats()
case <-s.ctx.Done():
return
}
}
}()
// 现有代码...
}
// resetStats 重置统计数据
func (s *Server) resetStats() {
s.statsMutex.Lock()
defer s.statsMutex.Unlock()
// 只重置累计值,保留配置相关值
s.stats.TotalResponseTime = 0
s.stats.AvgResponseTime = 0
s.stats.Queries = 0
s.stats.Blocked = 0
s.stats.Allowed = 0
s.stats.Errors = 0
s.stats.DNSSECQueries = 0
s.stats.DNSSECSuccess = 0
s.stats.DNSSECFailed = 0
s.stats.QueryTypes = make(map[string]int64)
s.stats.SourceIPs = make(map[string]bool)
logger.Info("统计数据已重置")
}
```
### 5. 修复 GetStats 函数
确保 `GetStats` 函数正确复制所有统计数据:
```go//
func (s *Server) GetStats() *Stats {
s.statsMutex.Lock()
defer s.statsMutex.Unlock()
// 创建完整的统计数据副本
statsCopy := &Stats{
Queries: s.stats.Queries,
Blocked: s.stats.Blocked,
Allowed: s.stats.Allowed,
Errors: s.stats.Errors,
LastQuery: s.stats.LastQuery,
AvgResponseTime: s.stats.AvgResponseTime,
TotalResponseTime: s.stats.TotalResponseTime,
QueryTypes: make(map[string]int64),
SourceIPs: make(map[string]bool),
CpuUsage: s.stats.CpuUsage,
DNSSECQueries: s.stats.DNSSECQueries,
DNSSECSuccess: s.stats.DNSSECSuccess,
DNSSECFailed: s.stats.DNSSECFailed,
DNSSECEnabled: s.stats.DNSSECEnabled,
}
// 复制查询类型统计
for k, v := range s.stats.QueryTypes {
statsCopy.QueryTypes[k] = v
}
// 复制来源IP统计
for ip := range s.stats.SourceIPs {
statsCopy.SourceIPs[ip] = true
}
return statsCopy
}
```
## 修复效果
1. **数据一致性**:修复后,`TotalResponseTime` 和 `Queries` 之间的关系将保持正确,避免因服务器重启导致的统计数据不一致
2. **异常值处理**:添加响应时间合理性检查,避免异常大的响应时间影响平均响应时间计算
3. **计算健壮性**:优化平均响应时间计算逻辑,添加防御性编程,确保计算结果合理
4. **统计数据管理**:添加定期重置统计数据的功能,避免 `TotalResponseTime` 无限增长导致的溢出问题
5. **并发安全**:确保所有统计数据操作都是线程安全的,避免并发访问导致的数据不一致
## 实现步骤
1. 修改 `loadStatsData` 函数,修复统计数据加载逻辑
2. 修改 `handleDNSRequest` 函数,添加响应时间合理性检查
3. 修改 `updateStats` 函数,优化平均响应时间计算
4. 添加 `resetStats` 函数,实现统计数据重置功能
5. 修改 `Start` 函数,启动定期重置统计数据的协程
6. 修复 `GetStats` 函数,确保正确复制所有统计数据
7. 测试修复效果,验证平均响应时间计算是否正确

View File

@@ -0,0 +1,46 @@
## GFWList管理页面实现计划
### 1. 修改 `index.html`
- 在侧边栏菜单(两个位置:桌面端和移动端)添加新的菜单项"GFWList管理"
- 创建新的页面内容区域 `#gfwlist-content`
- 添加配置选项:
- GFWList总开关checkbox
- GFWList解析目标IP输入框
- 通行网站开关组谷歌、YouTube、Facebook、X各checkbox
- 添加保存和重启服务按钮
### 2. 修改 `main.js`
- 在页面标题映射中添加 `'gfwlist': 'GFWList管理'`
-`contentSections` 数组中添加 `gfwlist-content`
- 添加hash为'gfwlist'时的页面初始化逻辑
### 3. 修改 `config.js`
- 添加GFWList页面初始化函数 `initGFWListPage()`
- 添加GFWList配置加载函数 `loadGFWListConfig()`
- 添加GFWList配置保存函数 `saveGFWListConfig()`
- 添加GFWList配置收集函数 `collectGFWListFormData()`
- 更新 `collectFormData()` 以包含新的GFWList配置字段
- 更新 `populateConfigForm()` 移除原有的GFWList配置已迁移到独立页面
### 4. 修改 `api.js`
- 添加GFWList专用的API方法如需要
### 配置数据结构
```json
{
"gfwlist": {
"enabled": true,
"targetIP": "127.0.0.1",
"allowGoogle": true,
"allowYouTube": true,
"allowFacebook": true,
"allowTwitter": true
}
}
```
### 实现顺序
1. 先修改HTML添加页面结构和菜单
2. 修改main.js添加导航支持
3. 修改config.js添加前端逻辑
4. 测试验证

View File

@@ -0,0 +1,39 @@
## 实现DNSSEC支持的计划
### 1. 分析当前代码
- 配置文件中已经包含了DNSSEC相关配置项`EnableDNSSEC``DNSSECValidation`
- DNS客户端resolver目前没有启用DNSSEC支持
- 需要修改代码以实现DNSSEC功能
### 2. 实现步骤
#### 步骤1修改DNS客户端配置
-`NewServer` 函数中修改DNS客户端配置添加 `DNSSEC: true` 以启用DNSSEC查询
- 确保客户端支持DNSSEC记录类型RRSIG, DNSKEY, DS等
#### 步骤2添加DNSSEC验证逻辑
-`forwardDNSRequestWithCache` 函数中检查上游服务器返回的响应是否包含DNSSEC签名
- 如果启用了DNSSEC验证验证签名的有效性
- 处理验证失败的情况,返回适当的错误响应
#### 步骤3确保DNS响应包含DNSSEC记录
- 当转发DNS响应时确保包含所有相关的DNSSEC记录
- 确保响应中的DNSSEC标志正确设置
#### 步骤4添加DNSSEC相关的日志记录
- 记录DNSSEC验证结果
- 记录DNSSEC相关的错误信息
### 3. 预期结果
- DNS服务器将支持DNSSEC查询
- 可以验证DNS记录的真实性和完整性
- 防止DNS投毒和劫持攻击
- 提供DNSSEC相关的配置选项
### 4. 文件修改
- `/root/dns/dns/server.go`修改DNS客户端配置和添加DNSSEC验证逻辑
### 5. 技术细节
- 使用miekg/dns库的内置DNSSEC支持
- 确保DNSSEC验证符合RFC标准
- 处理各种DNSSEC相关的错误情况

View File

@@ -0,0 +1,84 @@
## 实现计划
### 1. 配置更新
-`DNSConfig` 结构体中添加 `EnableDNSSEC` 布尔字段用于控制是否启用DNSSEC验证
- 在配置加载时设置默认值为 `true`
- 在默认配置JSON中添加DNSSEC相关配置项
### 2. DNSSEC核心功能实现
- **DO标志处理**识别并保留客户端请求中的DNSSEC OK (DO) 标志
- **记录转发**确保所有DNSSEC相关记录RRSIG, DNSKEY, DS, NSEC, NSEC3等被正确转发
- **签名验证**验证上游DNS服务器返回的DNSSEC签名有效性
- **AD标志设置**根据验证结果设置Authenticated Data (AD) 标志
### 3. 代码修改点
#### 3.1 配置文件 (`config/config.go`)
```go
// DNSConfig DNS配置
type DNSConfig struct {
Port int `json:"port"`
UpstreamDNS []string `json:"upstreamDNS"`
Timeout int `json:"timeout"`
StatsFile string `json:"statsFile"` // 统计数据持久化文件
SaveInterval int `json:"saveInterval"` // 数据保存间隔(秒)
EnableDNSSEC bool `json:"enableDNSSEC"` // 是否启用DNSSEC验证
}
```
#### 3.2 默认配置 (`main.go`)
在默认配置JSON中添加
```json
"enableDNSSEC": true
```
#### 3.3 DNS服务器初始化 (`dns/server.go`)
-`NewServer` 方法中为DNS客户端启用DNSSEC支持
- 初始化DNSSEC验证相关组件
#### 3.4 DNS请求处理 (`dns/server.go`)
- 修改 `handleDNSRequest` 方法保留客户端请求中的DO标志
- 修改 `forwardDNSRequest` 方法:
- 确保转发请求时包含DO标志
- 处理上游返回的DNSSEC记录
- 验证DNSSEC签名
- 根据验证结果设置AD标志
- 确保所有DNSSEC记录类型被正确处理
### 4. DNSSEC验证逻辑
- 使用miekg/dns库的内置验证功能
- 验证RRSIG记录与对应资源记录的匹配性
- 验证签名的有效性和过期时间
- 处理信任链验证
### 5. 测试验证
- 测试DNSSEC查询是否能正确返回RRSIG等记录
- 测试DNSSEC验证功能是否正常工作
- 测试在不同配置下的行为
- 测试各种DNSSEC记录类型的处理
## 预期效果
-`enableDNSSEC``true` 时:
- 服务器将验证上游DNS返回的DNSSEC记录
- 对于有效的DNSSEC记录服务器将在响应中设置AD标志
- 对于无效的DNSSEC记录服务器将记录错误并根据配置处理
- 服务器将正确转发所有DNSSEC相关记录
- 支持DNSKEY, DS, RRSIG, NSEC, NSEC3等DNSSEC记录类型
- 客户端可以通过设置DO标志来请求DNSSEC记录
## 安全增强
通过添加DNSSEC支持服务器将能够
- 防止DNS投毒攻击
- 确保DNS记录的完整性和真实性
- 为客户端提供经过验证的DNS响应
- 增强整体DNS服务的安全性
## 实现步骤
1. **修改配置结构**
2. **更新默认配置**
3. **修改DNS客户端设置**
4. **实现DNSSEC验证逻辑**
5. **测试和验证**

View File

@@ -0,0 +1,60 @@
## 实现计划优化DNSSEC查询逻辑
### 1. 需求分析
- 当配置文件中`enableDNSSEC=true`DNS服务器应优先返回包含DNSSEC记录的结果
- 如果没有DNSSEC结果应返回普通查询结果作为备选
- 保持现有代码结构和兼容性
### 2. 实现步骤
#### 步骤1修改`forwardDNSRequestWithCache`函数
- 在函数中添加备选响应变量用于存储非DNSSEC的成功响应
-`enableDNSSEC=true`遍历所有上游DNS服务器
- 对于每个上游,检查响应是否成功
- 如果响应成功且包含DNSSEC记录立即返回该响应
- 如果响应成功但不包含DNSSEC记录将其保存为备选响应
- 遍历完成后,如果有备选响应,返回该响应
- 如果没有成功响应,返回服务器失败错误
#### 步骤2添加DNSSEC记录检测逻辑
- 在响应处理中添加DNSSEC记录检测
- 检查响应的Answer、Ns和Extra部分是否包含RRSIG记录
- 使用该检测结果决定是否优先返回该响应
#### 步骤3优化日志记录
- 为DNSSEC优先返回的情况添加专门的日志记录
- 为备选响应返回的情况添加日志记录
### 3. 技术细节
#### 3.1 DNSSEC检测方法
- 检查响应中是否包含RRSIG资源记录签名记录
- 检查范围包括Answer、Ns和Extra部分
- 使用类型断言判断记录类型
#### 3.2 优先级逻辑
- 最高优先级成功且包含DNSSEC的响应
- 次高优先级成功但不包含DNSSEC的响应
- 最低优先级:失败响应
### 4. 预期效果
- 当启用DNSSEC时优先返回安全的DNSSEC结果
- 提高DNS查询的安全性
- 兼容现有配置和代码
- 提供详细的日志记录
### 5. 文件修改
- **文件**`/root/dns/dns/server.go`
- **函数**`forwardDNSRequestWithCache`
- **修改内容**添加DNSSEC优先逻辑和备选响应处理
### 6. 测试要点
- 验证启用DNSSEC时优先返回DNSSEC结果
- 验证无DNSSEC结果时返回普通结果
- 验证禁用DNSSEC时使用原有逻辑
- 验证日志记录正确
### 7. 实现时间线
- 代码修改20分钟
- 测试10分钟
- 总计30分钟

View File

@@ -0,0 +1,86 @@
# 优化DNS服务器parallel模式响应时间
## 问题分析
经过对代码的分析我发现parallel模式下响应时间过高的主要原因包括
1. **缺少超时机制**:当前实现会等待所有上游服务器响应,单个慢服务器会拖慢整个查询
2. **响应时间计算不合理**:使用所有响应的平均时间,而不是最快响应时间
3. **合并响应开销大**需要合并所有响应增加CPU和内存开销
4. **等待所有响应**:没有实现快速返回机制,即使收到第一个有效响应也会等待所有响应
5. **DNSSEC验证开销**每个响应都需要进行DNSSEC验证增加额外开销
## 优化方案
### 1. 添加超时机制
- 为每个上游服务器请求添加超时设置
- 超时时间可配置建议默认500ms
- 超时的请求不会影响整体响应时间
### 2. 实现快速返回机制
- 当收到第一个有效响应成功或NXDOMAIN立即返回给客户端
- 继续处理其他响应用于合并和缓存,但不影响当前查询的响应时间
- 优先返回带DNSSEC的响应
### 3. 优化响应时间计算
- 使用最快的响应时间作为查询的响应时间
- 保留平均响应时间用于统计,但不影响客户端感知的响应时间
### 4. 优化响应合并逻辑
- 只合并成功响应,忽略错误响应
- 合并时优先保留TTL较长的记录
- 减少不必要的内存分配和拷贝
### 5. 优化DNSSEC验证
- 只对需要返回的响应进行DNSSEC验证
- 缓存DNSSEC验证结果减少重复验证
### 6. 增加服务器健康检查
- 定期检查上游服务器的响应时间和可用性
- 只向健康的服务器发送请求
- 根据历史响应时间动态调整服务器权重
## 实现步骤
1. **修改forwardDNSRequestWithCache函数**
- 添加超时设置
- 实现快速返回逻辑
- 优化响应时间计算
2. **修改mergeResponses函数**
- 优化合并逻辑,减少开销
- 优先保留TTL较长的记录
3. **修改DNSSEC验证逻辑**
- 只对需要返回的响应进行验证
- 添加DNSSEC验证结果缓存
4. **添加服务器健康检查机制**
- 定期检查上游服务器
- 动态调整服务器列表
5. **添加配置选项**
- 超时时间配置
- 快速返回开关
- 健康检查配置
## 预期效果
- **响应时间显著降低**:客户端感知的响应时间将接近最快的上游服务器响应时间
- **资源利用率提高**:减少不必要的等待和计算
- **鲁棒性增强**:单个慢服务器不会影响整体性能
- **用户体验改善**更快的DNS解析速度
## 文件修改
- `/root/dns/dns/server.go`主要修改文件包含parallel模式的实现逻辑
- `/root/dns/config/config.go`:添加新的配置选项
- `/root/dns/dns/cache.go`如果需要添加DNSSEC验证结果缓存
## 测试计划
1. **性能测试**:比较优化前后的响应时间
2. **压力测试**:在高并发情况下测试性能
3. **可靠性测试**:测试单个服务器故障时的表现
4. **DNSSEC测试**确保DNSSEC验证仍然正常工作
5. **不同配置测试**:测试不同超时时间和服务器数量的影响

View File

@@ -0,0 +1,84 @@
# 优化设置界面实现计划
## 问题分析
当前设置界面存在配置项重复问题,需要进行优化,具体包括:
1. "远程规则URL"配置项在多个界面重复出现
2. "启用API"和"主机"选项不需要在当前界面显示
3. 需要确保保存功能正常工作写入config.json并触发服务器重新加载配置
## 优化方案
### 1. 修改HTML结构
- 移除"远程规则URL"配置项
- 移除"启用API"选项
- 移除"主机"选项
- 调整布局,确保界面美观合理
### 2. 更新JavaScript代码
- 修改`populateConfigForm`函数,移除对已删除配置项的处理
- 修改`collectFormData`函数,移除对已删除配置项的收集
- 确保保存功能能正确写入config.json文件
- 实现服务器重新加载配置的触发机制
- 提供明确的成功/失败反馈
### 3. 测试和验证
- 测试所有保留配置项的加载和保存功能
- 验证保存操作能正确写入config.json文件
- 验证服务器能重新加载配置
- 测试成功/失败反馈是否明确
## 具体实现步骤
1. **修改HTML结构**
- 编辑`index.html`文件,移除不需要的配置项
- 调整布局,确保界面美观合理
2. **更新JavaScript代码**
- 编辑`config.js`文件,修改`populateConfigForm`函数
- 修改`collectFormData`函数,移除对已删除配置项的处理
- 确保`handleSaveConfig`函数能正确保存配置
- 实现服务器重新加载配置的触发机制
3. **测试和验证**
- 测试配置项的加载功能
- 测试配置项的保存功能
- 验证config.json文件是否正确更新
- 验证服务器是否重新加载配置
- 测试成功/失败反馈是否明确
## 预期效果
- 设置界面布局合理,无重复配置项
- 所有保留配置项均可正常配置
- 保存功能能正确写入config.json文件
- 服务器能重新加载配置,使更改立即生效
- 保存操作有明确的成功/失败反馈
## 技术要点
- 使用HTML和JavaScript修改界面结构和功能
- 确保与服务器API的正确交互
- 实现良好的用户反馈机制
- 确保配置的正确保存和加载
## 实现时间
- 预计1-2小时完成所有修改和测试
## 风险评估
- 低风险:修改范围明确,不涉及核心功能
- 可回滚:所有修改均为前端修改,可通过恢复文件轻松回滚
## 依赖关系
- 依赖服务器API的正常工作
- 依赖config.json文件的读写权限
## 测试策略
- 手动测试所有配置项的加载和保存功能
- 验证config.json文件的更新
- 测试服务器配置的重新加载
- 测试成功/失败反馈
## 验收标准
- 设置界面布局合理,无重复配置项
- 所有保留配置项均可正常配置
- 保存功能能正确写入config.json文件
- 服务器能重新加载配置,使更改立即生效
- 保存操作有明确的成功/失败反馈

View File

@@ -0,0 +1,22 @@
## 问题分析
CPU使用率卡片在WebSocket实时更新时没有刷新数据原因是
1. `processRealTimeData`函数调用了`updateStatsCards(stats)`但该函数的CPU使用率更新逻辑可能没有被正确执行
2. `processRealTimeData`函数对其他卡片如平均响应时间、最常用查询类型、活跃IP数有单独的更新逻辑但缺少了CPU使用率卡片的更新逻辑
3. `loadDashboardData`函数中有完整的CPU使用率更新逻辑这就是为什么页面初始加载时CPU使用率能显示但后续WebSocket更新时不能显示的原因
## 修复方案
1. **在`processRealTimeData`函数中添加CPU使用率卡片的更新逻辑**:类似于`loadDashboardData`函数中的实现
2. **确保从`stats`对象中正确获取CPU使用率数据**支持从不同的数据结构中获取CPU使用率
3. **更新DOM元素**将获取到的CPU使用率数据更新到`cpu-usage``cpu-status`元素中
4. **添加状态判断**根据CPU使用率值设置不同的状态文本和样式
## 实现步骤
1. 打开`dashboard.js`文件
2. 找到`processRealTimeData`函数约第120行
3. 在函数末尾添加CPU使用率更新逻辑位于其他卡片更新逻辑之后
4. 确保从`stats`对象中正确获取CPU使用率数据
5. 更新`cpu-usage``cpu-status`元素的内容和样式
6. 测试修复是否生效
## 预期效果
修复后当WebSocket接收到实时数据更新时CPU使用率卡片会自动更新显示最新的CPU使用率和状态与其他统计卡片保持一致的实时更新效果。

View File

@@ -0,0 +1,22 @@
## 问题分析
CPU使用率卡片在WebSocket实时更新时没有刷新数据原因是
1. `updateStatsCards`函数中数组形式的数据结构处理部分第631-641行缺少CPU使用率的处理逻辑
2. 可能存在数据字段名不匹配的问题WebSocket服务器返回的CPU使用率数据可能使用了不同的字段名
3. `processRealTimeData`函数和`updateStatsCards`函数中都有CPU使用率更新逻辑可能导致冲突或其中一个逻辑没有被正确执行
## 修复方案
1. **完善`updateStatsCards`函数的CPU使用率处理逻辑**在数组形式的数据结构处理部分添加CPU使用率的处理逻辑
2. **添加更多可能的CPU使用率字段名支持**确保从WebSocket服务器返回的CPU使用率数据能够被正确获取无论它使用什么字段名
3. **统一CPU使用率更新逻辑**:确保`processRealTimeData`函数和`updateStatsCards`函数中的CPU使用率更新逻辑一致
4. **添加调试日志**:在关键位置添加调试日志,以便于排查问题
## 实现步骤
1. 打开`dashboard.js`文件
2. 找到`updateStatsCards`函数的数组形式数据结构处理部分第631-641行添加CPU使用率的处理逻辑
3.`updateStatsCards`函数的CPU使用率数据获取逻辑中添加更多可能的字段名支持
4. 统一`processRealTimeData`函数和`updateStatsCards`函数中的CPU使用率更新逻辑
5. 添加调试日志,以便于排查问题
6. 测试修复是否生效
## 预期效果
修复后当WebSocket接收到实时数据更新时CPU使用率卡片会自动更新显示最新的CPU使用率和状态与其他统计卡片保持一致的实时更新效果。

View File

@@ -0,0 +1,18 @@
## 问题分析
CPU使用率卡片数据不会跟随WebSocket自动更新的原因是`updateStatsCards`函数中缺少了CPU使用率的更新逻辑。该函数负责处理WebSocket实时数据并更新统计卡片但只更新了7个统计卡片遗漏了CPU使用率卡片。
## 修复方案
1. **修改`updateStatsCards`函数**:在`dashboard.js`文件中添加CPU使用率和状态的更新逻辑
2. **添加数据获取逻辑**从不同可能的数据结构中获取CPU使用率数据
3. **更新DOM元素**将获取到的CPU使用率数据更新到`cpu-usage``cpu-status`元素中
4. **添加状态判断**根据CPU使用率值设置不同的状态文本和样式
## 实现步骤
1. 打开`dashboard.js`文件
2. 找到`updateStatsCards`函数约第550行
3. 在函数末尾添加CPU使用率更新逻辑
4. 确保从`stats`对象中正确获取CPU使用率数据
5. 更新`cpu-usage``cpu-status`元素的内容和样式
## 预期效果
修复后当WebSocket接收到实时数据更新时CPU使用率卡片会自动更新显示最新的CPU使用率和状态与其他统计卡片保持一致的实时更新效果。

View File

@@ -0,0 +1,38 @@
## 问题分析
1. **配置正确**:配置文件中`enableDNSSEC`设置为`true`,但卡片显示"已禁用"
2. **代码问题**:在`dns/server.go``GetStats`函数中,返回的`Stats`结构体缺少了DNSSEC相关字段
3. **API行为**当API访问DNSSEC相关字段时由于没有从`GetStats`函数返回,它们的值都是默认值(`DNSSECEnabled`默认值为`false`
4. **前端显示**前端卡片从API获取`DNSSECEnabled`值,因此显示"已禁用"
## 解决方案
修改`dns/server.go`中的`GetStats`函数,确保返回的`Stats`副本包含所有DNSSEC相关字段包括`DNSSECEnabled``DNSSECQueries``DNSSECSuccess``DNSSECFailed`
## 修复步骤
1. 打开`/root/dns/dns/server.go`文件
2. 找到`GetStats`函数大约在第960行
3. 修改返回的`Stats`结构体添加缺失的DNSSEC相关字段
4. 确保所有DNSSEC字段都从原始`Stats`结构体复制到返回的副本中
## 预期结果
修复后API将正确返回DNSSEC启用状态前端卡片将显示"已启用",与配置文件中的设置一致。
## 代码修改点
```go
// 返回统计信息的副本
return &Stats{
Queries: s.stats.Queries,
Blocked: s.stats.Blocked,
Allowed: s.stats.Allowed,
Errors: s.stats.Errors,
LastQuery: s.stats.LastQuery,
AvgResponseTime: s.stats.AvgResponseTime,
TotalResponseTime: s.stats.TotalResponseTime,
QueryTypes: queryTypesCopy,
SourceIPs: sourceIPsCopy,
CpuUsage: s.stats.CpuUsage,
DNSSECQueries: s.stats.DNSSECQueries,
DNSSECSuccess: s.stats.DNSSECSuccess,
DNSSECFailed: s.stats.DNSSECFailed,
DNSSECEnabled: s.stats.DNSSECEnabled, // 这是关键字段,确保返回正确的启用状态
}
```

View File

@@ -0,0 +1,22 @@
## 问题分析
`/root/dns/dns/server.go`文件的`forwardDNSRequestWithCache`函数中,`dnssecSuccess`变量被声明和赋值,但没有被实际使用,导致编译错误:
```
dns/server.go:622:6: declared and not used: dnssecSuccess
```
## 代码检查
1. 变量在第622行声明`var dnssecSuccess bool = false`
2. 在第708行和第714行被赋值`dnssecSuccess = false``dnssecSuccess = true`
3. 但在整个函数中,该变量没有被任何条件判断或返回值使用
4. 实际使用的是`signatureValid`变量来表示DNSSEC验证结果
## 解决方案
删除未使用的`dnssecSuccess`变量,因为它的值与`signatureValid`完全相同,且没有被实际使用。
## 修复步骤
1. 删除第622行的`dnssecSuccess`变量声明
2. 删除第708行和第714行对`dnssecSuccess`变量的赋值
3. 保留`signatureValid`变量的使用因为它是实际用于判断DNSSEC验证结果的变量
## 预期结果
修复后编译器不再报错DNSSEC验证逻辑保持不变继续正常工作。

View File

@@ -0,0 +1,20 @@
### 问题分析
1. **收集验证记录集不完整**在DNSSEC验证过程中代码只从`response.Answer``response.Ns`中收集记录,而忽略了`response.Extra`中的记录导致某些DNSSEC记录没有被正确验证。
2. **验证失败处理不当**当DNSSEC签名验证失败时代码会直接丢弃该响应而不是返回包含DNSSEC记录的响应导致客户端无法获取DNSSEC记录。
### 修复方案
1. **修复记录集收集逻辑**在收集需要验证的记录集rrset确保从`response.Answer``response.Ns``response.Extra`中收集所有相关记录。
2. **改进验证失败处理**即使DNSSEC签名验证失败也要返回包含DNSSEC记录的响应同时设置正确的AD标志让客户端决定如何处理验证失败的情况。
3. **优化备选响应逻辑**确保在所有上游服务器都不返回DNSSEC记录时仍然能够正确处理和返回响应。
### 具体修改
1. 修改`forwardDNSRequestWithCache`函数中的记录集收集逻辑,添加对`response.Extra`的处理
2. 修改DNSSEC验证失败时的处理逻辑确保返回包含DNSSEC记录的响应
3. 优化备选响应的保存和返回逻辑确保DNSSEC记录能够被正确处理
### 测试计划
1. 编译修复后的代码
2. 启动DNS服务器并启用DNSSEC
3. 使用dig命令测试DNSSEC记录查询例如`dig +dnssec example.com`
4. 检查查询结果是否包含DNSSEC记录RRSIG、DNSKEY等
5. 检查日志中是否有DNSSEC验证相关的记录

View File

@@ -0,0 +1,182 @@
## 问题分析
通过深入分析代码,我找到了导致所有查询都显示同一个 NXDOMAIN 错误的根本原因:
**核心问题**`mergeResponses` 函数在合并多个 DNS 响应时,**没有正确处理 Rcode 字段**
**具体原因**
1. 当使用并行查询模式时DNS 服务器会向多个上游服务器发送请求
2. 函数使用第一个响应作为基础来合并其他响应
3. 它清空了 `Answer``Ns``Extra` 字段,但**保留了第一个响应的 Rcode**
4. 如果第一个响应返回 NXDOMAIN比如对于恶意域名 www.evilsnssdk.com那么**合并后的响应也会保持 NXDOMAIN 状态**,即使其他响应返回成功
5. 这导致所有查询都显示同一个 NXDOMAIN 错误
## 修复方案
### 修复 `mergeResponses` 函数
**关键修改点**
1. **重置 Rcode**:在合并响应前,将 Rcode 重置为成功状态
2. **处理 NXDOMAIN**:只有当所有响应都是 NXDOMAIN 时,才返回 NXDOMAIN
3. **优先使用成功响应**:如果有任何响应返回成功,就使用成功的 Rcode
### 修复步骤
1. **修改 `mergeResponses` 函数** (`/root/dns/dns/server.go:842-933`)
- 在合并记录前,将 `mergedResponse.Rcode` 设置为 `dns.RcodeSuccess`
- 添加变量 `allNXDOMAIN` 来跟踪是否所有响应都是 NXDOMAIN
- 遍历所有响应,检查是否有成功响应
- 如果所有响应都是 NXDOMAIN才将 `mergedResponse.Rcode` 设置为 `dns.RcodeNameError`
2. **优化合并逻辑**
- 确保优先使用成功响应中的记录
- 避免将 NXDOMAIN 响应的记录合并到成功响应中
- 保持响应的一致性Rcode 与记录内容匹配
## 修复代码
```go
// mergeResponses 合并多个DNS响应
func mergeResponses(responses []*dns.Msg) *dns.Msg {
if len(responses) == 0 {
return nil
}
// 如果只有一个响应,直接返回,避免不必要的合并操作
if len(responses) == 1 {
return responses[0].Copy()
}
// 使用第一个响应作为基础
mergedResponse := responses[0].Copy()
mergedResponse.Answer = []dns.RR{}
mergedResponse.Ns = []dns.RR{}
mergedResponse.Extra = []dns.RR{}
// 重置Rcode为成功除非所有响应都是NXDOMAIN
mergedResponse.Rcode = dns.RcodeSuccess
// 检查是否所有响应都是NXDOMAIN
allNXDOMAIN := true
// 收集所有成功响应的记录
for _, resp := range responses {
if resp == nil {
continue
}
// 如果有任何响应是成功的就不是allNXDOMAIN
if resp.Rcode == dns.RcodeSuccess {
allNXDOMAIN = false
}
}
// 如果所有响应都是NXDOMAIN设置合并响应为NXDOMAIN
if allNXDOMAIN {
mergedResponse.Rcode = dns.RcodeNameError
}
// 使用map存储唯一记录选择最长TTL
// 预分配map容量减少扩容开销
answerMap := make(map[recordKey]dns.RR, len(responses[0].Answer)*len(responses))
nsMap := make(map[recordKey]dns.RR, len(responses[0].Ns)*len(responses))
extraMap := make(map[recordKey]dns.RR, len(responses[0].Extra)*len(responses))
for _, resp := range responses {
if resp == nil {
continue
}
// 只合并与最终Rcode匹配的响应记录
if (mergedResponse.Rcode == dns.RcodeSuccess && resp.Rcode == dns.RcodeSuccess) ||
(mergedResponse.Rcode == dns.RcodeNameError && resp.Rcode == dns.RcodeNameError) {
// 合并Answer部分
for _, rr := range resp.Answer {
key := getRecordKey(rr)
if existing, exists := answerMap[key]; exists {
// 如果存在相同记录选择TTL更长的
if rr.Header().Ttl > existing.Header().Ttl {
answerMap[key] = rr
}
} else {
answerMap[key] = rr
}
}
// 合并Ns部分
for _, rr := range resp.Ns {
key := getRecordKey(rr)
if existing, exists := nsMap[key]; exists {
// 如果存在相同记录选择TTL更长的
if rr.Header().Ttl > existing.Header().Ttl {
nsMap[key] = rr
}
} else {
nsMap[key] = rr
}
}
// 合并Extra部分
for _, rr := range resp.Extra {
// 跳过OPT记录避免重复
if rr.Header().Rrtype == dns.TypeOPT {
continue
}
key := getRecordKey(rr)
if existing, exists := extraMap[key]; exists {
// 如果存在相同记录选择TTL更长的
if rr.Header().Ttl > existing.Header().Ttl {
extraMap[key] = rr
}
} else {
extraMap[key] = rr
}
}
}
}
// 预分配切片容量,减少扩容开销
mergedResponse.Answer = make([]dns.RR, 0, len(answerMap))
mergedResponse.Ns = make([]dns.RR, 0, len(nsMap))
mergedResponse.Extra = make([]dns.RR, 0, len(extraMap))
// 将map转换回切片
for _, rr := range answerMap {
mergedResponse.Answer = append(mergedResponse.Answer, rr)
}
for _, rr := range nsMap {
mergedResponse.Ns = append(mergedResponse.Ns, rr)
}
for _, rr := range extraMap {
mergedResponse.Extra = append(mergedResponse.Extra, rr)
}
return mergedResponse
}```
## 预期效果
修复后DNS服务器将能够
- 正确合并多个 DNS 响应
- 确保 Rcode 与实际记录内容匹配
- 只有当所有响应都是 NXDOMAIN 时才返回 NXDOMAIN
- 避免单个恶意域名影响所有查询结果
- 正确显示各个域名的查询结果
## 修复代码位置
- **核心修改文件**`/root/dns/dns/server.go`
- **关键函数**`mergeResponses`
- **修改内容**:修复响应合并逻辑,正确处理 Rcode 字段
## 测试方法
1. 使用 nslookup 测试不同域名
2. 检查是否每个域名都显示正确的查询结果
3. 验证 www.evilsnssdk.com 返回 NXDOMAIN而其他域名返回成功
4. 检查日志中是否还有大量错误信息
这个修复将彻底解决所有查询都显示同一个 NXDOMAIN 错误的问题!

View File

@@ -0,0 +1,18 @@
## 问题分析
当前实现中,详细图表(浮窗)的时间范围切换会影响到主页面的图表显示,这是因为它们共享了全局变量`currentTimeRange``isMixedView`。当用户在浮窗内切换时间范围时,这些全局变量会被修改,导致主页面的图表也随之改变。
## 解决方案
1. 为详细图表创建独立的变量,用于存储其时间范围和混合视图状态
2. 修改`initDetailedTimeRangeToggle`函数,使其使用这些独立的变量,而不是全局变量
3. 修改`drawDetailedDNSRequestsChart`函数,使用独立的变量来控制图表显示
4. 确保主图表默认显示混合视图
## 修复步骤
1.`dashboard.js`文件中添加详细图表专用的全局变量
2. 修改`initDetailedTimeRangeToggle`函数,使用详细图表专用变量
3. 修改`drawDetailedDNSRequestsChart`函数,使用详细图表专用变量
4. 确保主图表默认显示混合视图
5. 测试修复效果,确保浮窗内的时间范围切换不会影响主页面图表
## 预期效果
修复后DNS请求趋势图表默认显示混合内容视图不变当用户点击展开按钮查看详细数据时浮窗内的时间范围切换不会影响到主页面的图表内容提供更好的用户体验。

View File

@@ -0,0 +1,15 @@
## 问题分析
DNS请求趋势图表展开后不能随页面放大缩小自动调整大小。通过代码分析发现`window.addEventListener('resize')`事件监听器只处理了侧边栏的显示/隐藏,没有处理图表的调整大小。
## 解决方案
1. 修改`window.addEventListener('resize')`事件监听器,添加对所有图表(包括详细图表)的更新调用
2. 确保在模态框显示时,图表能够正确响应窗口大小变化
## 修复步骤
1. 打开`/root/dns/static/js/dashboard.js`文件
2. 找到`window.addEventListener('resize')`事件监听器
3. 修改该事件监听器,添加对`dnsRequestsChart``detailedDnsRequestsChart`的更新调用
4. 确保图表实例存在时才调用update方法
## 预期效果
修复后当用户展开DNS请求趋势图表并调整浏览器窗口大小时图表会自动调整大小以适应新的窗口尺寸。

View File

@@ -0,0 +1,21 @@
## 问题分析
展开图表超出了显示范围,没有按照展开浮窗大小显示内容。通过代码分析,发现以下问题:
1. 图表容器使用了固定高度 `h-[600px]`,这可能导致在某些屏幕尺寸下图表超出显示范围
2. 浮窗容器设置了 `max-h-[90vh]`,但图表容器的固定高度可能超过这个限制
3. 当图表初始化时,可能没有正确计算容器的实际可用空间
## 解决方案
1. 修改图表容器的高度设置,使其更灵活,能够适应不同屏幕尺寸
2. 确保图表容器的高度不超过浮窗的最大高度限制
3. 在图表显示时,确保正确计算容器大小并更新图表
## 修复步骤
1. 打开 `index.html` 文件,修改图表容器的高度设置
2. 将固定高度 `h-[600px]` 改为相对高度或最大高度
3. 确保图表容器的高度能够适应浮窗的可用空间
4.`drawDetailedDNSRequestsChart` 函数中,添加对图表容器大小的检查和调整
5. 确保在图表显示时,正确计算容器大小并更新图表
## 预期效果
修复后当用户展开DNS请求趋势图表时图表会根据浮窗的可用空间自动调整大小不会超出显示范围提供更好的用户体验。

View File

@@ -0,0 +1,4 @@
1. 检查updateTopData函数修复当API调用失败或返回错误时没有数据显示的问题
2. 确保在所有情况下updateTopDomainsTable函数都能被调用即使API调用失败
3. 为updateTopData函数添加错误处理确保在API调用失败时使用模拟数据
4. 测试修复后的代码确保TOP域名卡片能正确显示数据

View File

@@ -0,0 +1,32 @@
## 问题分析
经过分析TOP客户端数据加载失败的原因是**前端API调用路径与后端注册的路径不匹配**
1. **前端代码**:在 `static/js/api.js` 中,`getTopClients` 方法调用的是 `/top-clients` API端点
2. **后端代码**:在 `http/server.go`注册的API路径是 `/api/top-clients`
3. **结果**前端请求404错误导致TOP客户端数据加载失败
## 解决方案
修改前端API调用`/top-clients` 改为 `/api/top-clients`,确保与后端注册的路径匹配。
## 实现步骤
1. **修改 `static/js/api.js` 文件**
- 找到 `getTopClients` 方法
- 将API调用路径从 `/top-clients?t=` 改为 `/api/top-clients?t=`
2. **验证修复**
- 刷新页面检查TOP客户端数据是否能正常加载
- 查看浏览器控制台确认没有404错误
## 预期效果
- TOP客户端数据能够正常加载
- 不再显示"加载失败"错误信息
- 页面上显示真实的TOP客户端数据
## 代码修改
只需要修改一个文件:
- `static/js/api.js`:更新 `getTopClients` 方法的API路径

View File

@@ -0,0 +1,4 @@
1. 检查updateTopClientsTable函数添加对tableBody是否存在的检查
2. 改进模拟数据使用真实的IP地址和请求次数
3. 确保函数在任何情况下都能正确执行
4. 测试修复后的代码确保TOP客户端卡片能正确显示数据

View File

@@ -0,0 +1,95 @@
# 问题分析
1. **问题现象**:当用户在某个设置项页面刷新时,页面会自动回到仪表盘页面。
2. **问题根源**
-`dashboard.js` 文件中,`handleHashChange` 函数被定义在 `handlePageSwitch` 函数内部
- 当页面刷新时,`handleHashChange` 函数会在页面加载完成后立即执行
- 此时,`menuItems` 可能还没有被正确初始化,或者 `handleHashChange` 函数内部的 `menuItems` 引用的是旧的变量,导致它无法找到对应的菜单项
-`handleHashChange` 函数无法找到对应的菜单项时,它会执行 `window.location.hash = '#dashboard'`,将页面重定向到仪表盘页面
3. **具体问题**
- `handleHashChange` 函数在找不到对应的菜单项时,会立即重定向到仪表盘页面,而不是先尝试直接显示对应的内容
- 这导致用户在刷新页面时即使URL中包含正确的hash页面也会被重定向到仪表盘
# 修复方案
1. **修复 `handleHashChange` 函数**
- 修改 `handleHashChange` 函数,确保它在找不到对应的菜单项时,不会总是重定向到仪表盘页面
- 当无法找到对应的菜单项时,先尝试直接显示对应的内容
- 只有当对应的内容也不存在时,才重定向到仪表盘页面
2. **优化页面初始化流程**
- 确保 `handleHashChange` 函数在页面完全加载后才执行
- 确保 `menuItems` 变量在 `handleHashChange` 函数执行前已经被正确初始化
# 实现步骤
1. 修改 `dashboard.js` 文件中的 `handleHashChange` 函数:
- 当无法找到对应的菜单项时,先尝试直接显示对应的内容
- 只有当对应的内容也不存在时,才重定向到仪表盘页面
2. 测试修复后的功能:
- 启动DNS服务器
- 访问Web界面导航到某个设置项页面例如 `#config`
- 刷新页面
- 验证页面是否仍然显示在设置项页面,而不是自动回到仪表盘页面
# 预期结果
- 用户在某个设置项页面刷新时,页面会保持在当前页面,不会自动回到仪表盘页面
- 只有当URL中的hash无效时页面才会重定向到仪表盘页面
- 页面导航功能正常,用户可以通过点击菜单项切换页面
# 修复代码
```javascript
// 修改 dashboard.js 文件中的 handleHashChange 函数
function handleHashChange() {
let hash = window.location.hash;
// 如果没有hash默认设置为#dashboard
if (!hash) {
hash = '#dashboard';
window.location.hash = hash;
return;
}
const targetId = hash.substring(1);
// 查找对应的内容元素
const contentElement = document.getElementById(`${targetId}-content`);
// 如果找到了对应的内容元素,直接显示
if (contentElement) {
// 隐藏所有内容
document.querySelectorAll('[id$="-content"]').forEach(content => {
content.classList.add('hidden');
});
// 显示目标内容
contentElement.classList.remove('hidden');
// 查找对应的菜单项并更新活动状态
let targetMenuItem = null;
menuItems.forEach(item => {
if (item.getAttribute('href') === hash) {
targetMenuItem = item;
}
});
// 更新活动菜单项
menuItems.forEach(item => {
item.classList.remove('sidebar-item-active');
if (item.getAttribute('href') === hash) {
item.classList.add('sidebar-item-active');
// 更新页面标题
document.getElementById('page-title').textContent = item.querySelector('span').textContent;
}
});
} else {
// 如果没有找到对应的内容默认显示dashboard
window.location.hash = '#dashboard';
}
}
```

View File

@@ -0,0 +1,58 @@
## 实现计划
### 1. 配置文件修改
* **修改`/root/dns/config/config.go`**
*`DNSConfig`结构体中添加`PrefixDomain []string`字段用于支持search domain功能
*`LoadConfig`函数中添加`prefixDomain`的默认值处理
### 2. DNS请求处理逻辑修改
* **修改`/root/dns/dns/server.go`中的`forwardDNSRequestWithCache`函数**
* 强化domainSpecificDNS逻辑确保当域名匹配时只使用指定的DNS服务器
* 移除向DNSSEC专用服务器发送请求的逻辑当域名匹配domainSpecificDNS时
* 确保匹配域名的DNS查询结果不会被其他DNS服务器的响应覆盖
* **修改`/root/dns/dns/server.go`中的`handleDNSRequest`函数**
* 实现search domain功能当直接查询失败时尝试添加prefixDomain中指定的域名前缀
* 按照/etc/resolv.conf中的search domain逻辑处理查询请求
### 3. 配置文件示例更新
* **更新配置文件示例**
* 添加`prefixDomain`配置项示例
* 说明search domain功能的使用方法
### 4. 测试验证
* 测试domainSpecificDNS强制使用功能确保匹配的域名只使用指定的DNS服务器
* 测试search domain功能确保能够正确处理带前缀的域名查询
* 测试不同配置组合下的功能正确性
## 预期效果
1. 当域名匹配domainSpecificDNS配置时无论DNSSEC是否启用只使用指定的DNS服务器
2. 支持search domain功能能够自动尝试添加配置的域名前缀
3. 配置简单直观,与/etc/resolv.conf的search domain行兼容
## 实现要点
* 确保domainSpecificDNS配置的优先级最高
* 实现高效的search domain查询逻辑避免不必要的网络请求
* 保持代码的可读性和可维护性
* 确保与现有功能的兼容性

View File

@@ -0,0 +1,58 @@
## 问题分析
通过代码分析,我发现/api/top-clients端点数据无法持久化的原因有两个
1. **数据保存逻辑缺失**:在`saveStatsData`方法中,虽然`StatsData`结构体包含了`ClientStats`字段,但没有将`server.clientStats`赋值给`statsData.ClientStats`
2. **数据加载逻辑缺失**:在`loadStatsData`方法中,虽然`StatsData`结构体包含了`ClientStats`字段,但没有将`statsData.ClientStats`赋值给`server.clientStats`
3. **自动保存功能未启用**`startAutoSave`方法没有在`Server``Start`方法中被调用,导致数据不会定期保存
## 修复计划
1. **修改`saveStatsData`方法**:添加保存`ClientStats`数据的逻辑
2. **修改`loadStatsData`方法**:添加加载`ClientStats`数据的逻辑
3. **在`Server.Start`方法中调用`startAutoSave`**:确保数据定期保存
## 修复步骤
### 步骤1修改`saveStatsData`方法
`dns/server.go`文件中,修改`saveStatsData`方法,添加保存`ClientStats`数据的逻辑:
```go
// 复制客户端统计数据
s.clientStatsMutex.RLock()
statsData.ClientStats = make(map[string]*ClientStats)
for k, v := range s.clientStats {
statsData.ClientStats[k] = v
}
s.clientStatsMutex.RUnlock()
```
### 步骤2修改`loadStatsData`方法
`dns/server.go`文件中,修改`loadStatsData`方法,添加加载`ClientStats`数据的逻辑:
```go
s.clientStatsMutex.Lock()
if statsData.ClientStats != nil {
s.clientStats = statsData.ClientStats
}
s.clientStatsMutex.Unlock()
```
### 步骤3在`Server.Start`方法中调用`startAutoSave`
`dns/server.go`文件的`Start`方法中,添加调用`startAutoSave`的代码:
```go
// 启动自动保存功能
go s.startAutoSave()
```
## 预期效果
修复后,/api/top-clients端点的数据将
1. 在服务器启动时从文件加载
2. 定期自动保存到文件
3. 在服务器停止时最后保存一次
这样就能确保/api/top-clients端点的数据持久化不会因为服务器重启而丢失。

View File

@@ -0,0 +1,31 @@
### 问题分析
1. **语法错误**:文件中存在多处语法错误,包括:
- 第34行`type ClientStats uct` 应该是 `type ClientStats struct`
- 第36行`Count 64` 应该是 `Count int64`
- 第143行`/ DNSCache` 缺少一个星号,应该是 `// DNSCache`
- 多处缩进问题
- 函数内容被截断
2. **文件完整性问题**文件内容不完整handleDNSRequest函数被截断缺少后续的函数定义
### 修复方案
1. **修复语法错误**
- 修复ClientStats结构体定义
- 修复DNSCache注释和结构体定义
- 修复所有缩进问题
2. **恢复完整内容**
- 重新编写或恢复handleDNSRequest函数的完整内容
- 确保所有后续函数定义完整
### 具体修改
1. 修复第34行的ClientStats结构体定义
2. 修复第143行的DNSCache注释和结构体定义
3. 修复所有缩进问题
4. 恢复完整的handleDNSRequest函数
5. 恢复后续所有函数定义
### 测试计划
1. 编译修复后的代码
2. 启动DNS服务器并测试功能
3. 验证DNSSEC功能是否正常工作

View File

@@ -0,0 +1,20 @@
# 修复picsum.photos域名匹配问题
## 问题分析
当DNS查询picsum.photos时实际传递给`getDomainInfo()`函数的域名可能带有末尾点(如"picsum.photos."而domain-info.json中存储的是没有末尾点的域名如"picsum.photos")。在原始的`isDomainMatch()`函数中,直接比较两个域名,导致匹配失败。
## 解决方案
修改`isDomainMatch()`函数,在域名比较前对两个域名进行规范化处理,去除末尾的点,确保匹配准确性。
## 实施步骤
1. 修改`isDomainMatch()`函数,在域名比较前对`urlDomain``targetDomain`进行规范化处理,去除末尾的点
2. 确保无论是完整URL还是纯域名都能正确匹配
3. 测试修改后的代码确保picsum.photos域名能被正确匹配
## 修改内容
- 文件:`/root/dns/static/js/logs.js`
- 函数:`isDomainMatch()`
- 修改点:在域名比较前,去除`urlDomain``targetDomain`末尾的点
## 预期效果
修改后picsum.photos域名无论是否带有末尾点都能被正确匹配到domain-info.json中的条目。

View File

@@ -0,0 +1,4 @@
1. 检查updateRecentBlockedTable函数添加对tableBody是否存在的检查
2. 确保在移除recent-blocked-table元素后updateRecentBlockedTable函数不会导致错误
3. 确保后续的updateTopDomainsTable调用能够被正确执行
4. 测试修复后的代码确保TOP域名卡片能正确显示数据

View File

@@ -0,0 +1,90 @@
## 问题分析
通过代码分析我发现web屏蔽管理页面点击后一直显示处理中灰色遮罩的原因有两个
1. **JavaScript错误导致`hideLoading()`不被调用**
- `loadLocalRules()`函数尝试访问`document.getElementById('local-rules-count')`但该元素在HTML中不存在
- `loadRemoteRules()`函数尝试访问`document.getElementById('remote-rules-count')`但该元素在HTML中不存在
- `setupShieldEventListeners()`函数尝试访问`document.getElementById('view-local-rules-btn')``document.getElementById('view-remote-rules-btn')`但这些元素在HTML中不存在
- 这些JavaScript错误会导致函数执行中断从而使`hideLoading()`不被调用,加载遮罩一直显示
2. **竞态条件问题**
- `initShieldPage()`函数并行调用三个异步函数:`loadShieldStats()``loadLocalRules()``loadRemoteBlacklists()`
- 每个异步函数都会调用`showLoading()`,而`showLoading()`会先调用`hideLoading()`来移除现有加载状态,然后创建一个新的加载状态
- 这种并行调用可能导致竞态条件,使最后一个加载遮罩无法被正确销毁
## 修复计划
1. **修改`loadLocalRules()`函数**添加元素存在性检查避免JavaScript错误
2. **修改`loadRemoteRules()`函数**添加元素存在性检查避免JavaScript错误
3. **修改`setupShieldEventListeners()`函数**添加元素存在性检查避免JavaScript错误
4. **修改`initShieldPage()`函数**:确保只创建一个加载遮罩,并在所有异步函数完成后销毁它
## 修复步骤
### 步骤1修改`loadLocalRules()`函数
`shield.js`文件中,修改`loadLocalRules()`函数,添加元素存在性检查:
```javascript
// 更新本地规则数量显示
if (document.getElementById('local-rules-count')) {
document.getElementById('local-rules-count').textContent = data.localRulesCount || 0;
}
```
### 步骤2修改`loadRemoteRules()`函数
`shield.js`文件中,修改`loadRemoteRules()`函数,添加元素存在性检查:
```javascript
// 更新远程规则数量显示
if (document.getElementById('remote-rules-count')) {
document.getElementById('remote-rules-count').textContent = data.remoteRulesCount || 0;
}
```
### 步骤3修改`setupShieldEventListeners()`函数
`shield.js`文件中,修改`setupShieldEventListeners()`函数,添加元素存在性检查:
```javascript
// 添加切换查看本地规则和远程规则的事件监听
if (document.getElementById('view-local-rules-btn')) {
document.getElementById('view-local-rules-btn').addEventListener('click', loadLocalRules);
}
if (document.getElementById('view-remote-rules-btn')) {
document.getElementById('view-remote-rules-btn').addEventListener('click', loadRemoteRules);
}
```
### 步骤4修改`initShieldPage()`函数
`shield.js`文件中,修改`initShieldPage()`函数,确保只创建一个加载遮罩,并在所有异步函数完成后销毁它:
```javascript
// 初始化屏蔽管理页面
async function initShieldPage() {
showLoading('加载屏蔽管理数据...');
try {
// 并行加载所有数据
await Promise.all([
loadShieldStats(),
loadLocalRules(),
loadRemoteBlacklists()
]);
// 设置事件监听器
setupShieldEventListeners();
} finally {
hideLoading();
}
}
```
### 步骤5修改异步函数移除内部的`showLoading()`和`hideLoading()`调用
`shield.js`文件中,修改`loadShieldStats()``loadLocalRules()``loadRemoteBlacklists()`函数,移除内部的`showLoading()``hideLoading()`调用,只保留数据加载逻辑。
## 预期效果
修复后web屏蔽管理页面点击后
1. 只会显示一个加载遮罩
2. 不会出现JavaScript错误
3. 所有数据加载完成后,加载遮罩会被正确隐藏
4. 页面会正常显示屏蔽管理设置内容

View File

@@ -0,0 +1,37 @@
# 修复保存按钮错位问题
## 问题分析
远程黑名单管理部分的保存按钮错位,原因是:
- 添加黑名单表单使用了Grid布局`grid grid-cols-1 md:grid-cols-3 gap-4`
- 前两个子元素包含label和input高度较高
- 第三个子元素只有按钮和状态显示没有label高度较矮
- 导致按钮在垂直方向上与前两个输入框不对齐
## 解决方案
修改添加黑名单表单的HTML结构确保三个子元素在垂直方向上对齐
1. **为第三个子元素添加垂直对齐**
- 确保保存按钮容器与前两个输入框容器在垂直方向上对齐
- 可以选择顶部对齐或中间对齐,保持视觉一致性
2. **统一子元素结构**
- 为第三个子元素添加一个隐藏的label确保结构一致
- 或者调整Grid布局使第三个子元素的内容垂直居中
3. **调整容器样式**
- 修改保存按钮容器的样式,确保垂直对齐
- 可以使用`items-start``items-center`属性
## 实现步骤
1. 修改`add-blacklist-form`的HTML结构
- 为第三个子元素添加`items-start`类,使其与前两个子元素的顶部对齐
- 或者添加一个隐藏的label确保结构一致
2. 测试修改后的效果
- 确保保存按钮与前两个输入框在垂直方向上对齐
- 保持响应式布局,在不同屏幕尺寸下都能正常显示
## 预期效果
保存按钮将与前两个输入框在垂直方向上对齐,消除错位现象,提升表单的视觉一致性和用户体验。

View File

@@ -0,0 +1,56 @@
## 问题分析
域名信息显示为空,特别是对于`wx.qq.com`这样的域名,虽然在`domain-info.json`中已配置,但日志详情中显示为空。
### 可能的原因
1. **文件路径问题**`loadDomainInfoDatabase`函数使用`fetch('/domain-info/domains/domain-info.json')`加载文件,但服务器可能没有正确配置该路径,导致加载失败。
2. **代码逻辑问题**:虽然代码逻辑看起来正确,但可能存在一些边缘情况没有处理好。
3. **调试信息不足**:代码中缺少调试信息,难以定位具体问题。
## 解决方案
### 1. 添加调试日志
`loadDomainInfoDatabase``getDomainInfo`函数中添加调试日志,以便定位问题:
-`loadDomainInfoDatabase`函数中,添加日志记录文件加载状态和结果
-`getDomainInfo`函数中,添加日志记录域名匹配过程
-`isDomainMatch`函数中添加日志记录URL匹配细节
### 2. 检查并修复文件路径
确保`domain-info.json`文件能被正确访问:
- 检查服务器配置,确保`/domain-info/domains/domain-info.json`路径指向正确的文件
- 或者修改代码中的路径,使用绝对路径或正确的相对路径
### 3. 增强错误处理
`loadDomainInfoDatabase`函数中增强错误处理,提供更详细的错误信息:
- 记录完整的错误信息
- 在控制台显示友好的错误提示
- 考虑添加重试机制
### 4. 优化域名匹配逻辑
虽然代码逻辑看起来正确,但可以进一步优化:
- 确保所有URL都被正确处理无论是否包含协议
- 增强主域名提取逻辑,处理更多特殊情况
- 考虑添加缓存机制,提高匹配效率
## 实施步骤
1. 修改`loadDomainInfoDatabase`函数,添加调试日志和增强错误处理
2. 修改`getDomainInfo`函数,添加调试日志
3. 修改`isDomainMatch`函数,添加调试日志
4. 测试修复效果
5. 根据测试结果进一步优化
## 预期效果
修复后,域名信息将能正确显示在日志详情中,特别是对于`wx.qq.com`等已配置的域名。

View File

@@ -0,0 +1,134 @@
# 优化设置界面实现计划
## 问题分析
当前设置界面存在配置项重复问题,需要进行优化,具体包括:
1. "远程规则URL"配置项在多个界面重复出现
2. "启用API"和"主机"选项不需要在当前界面显示
3. 需要确保保存功能正常工作写入config.json并触发服务器重新加载配置
## 优化方案
### 1. 修改HTML结构
* 移除"远程规则URL"配置项
* 移除"启用API"选项
* 移除"主机"选项
* 调整布局,确保界面美观合理
### 2. 更新JavaScript代码
* 修改`populateConfigForm`函数,移除对已删除配置项的处理
* 修改`collectFormData`函数,移除对已删除配置项的收集
* 确保保存功能能正确写入config.json文件
* 实现服务器重新加载配置的触发机制
* 提供明确的成功/失败反馈
### 3. 测试和验证
* 测试所有保留配置项的加载和保存功能
* 验证保存操作能正确写入config.json文件
* 验证服务器能重新加载配置
* 测试成功/失败反馈是否明确
## 具体实现步骤
1. **修改HTML结构**
* 编辑`index.html`文件,移除不需要的配置项
* 调整布局,确保界面美观合理
2. **更新JavaScript代码**
* 编辑`config.js`文件,修改`populateConfigForm`函数
* 修改`collectFormData`函数,移除对已删除配置项的处理
* 确保`handleSaveConfig`函数能正确保存配置
* 实现服务器重新加载配置的触发机制
3. **测试和验证**
* 测试配置项的加载功能
* 测试配置项的保存功能
* 验证config.json文件是否正确更新
* 验证服务器是否重新加载配置
* 测试成功/失败反馈是否明确
## 预期效果
* 设置界面布局合理,无重复配置项
* 所有保留配置项均可正常配置
* 保存功能能正确写入config.json文件
* 服务器能重新加载配置,使更改立即生效
* 保存操作有明确的成功/失败反馈
## 技术要点
* 使用HTML和JavaScript修改界面结构和功能
* 确保与服务器API的正确交互
* 实现良好的用户反馈机制
* 确保配置的正确保存和加载
## 实现时间
* 预计1-2小时完成所有修改和测试
## 风险评估
* 低风险:修改范围明确,不涉及核心功能
* 可回滚:所有修改均为前端修改,可通过恢复文件轻松回滚
## 依赖关系
* 依赖服务器API的正常工作
* 依赖config.json文件的读写权限
## 测试策略
* 手动测试所有配置项的加载和保存功能
* 验证config.json文件的更新
* 测试服务器配置的重新加载
* 测试成功/失败反馈
## 验收标准
* 设置界面布局合理,无重复配置项
* 所有保留配置项均可正常配置
* 保存功能能正确写入config.json文件
* 服务器能重新加载配置,使更改立即生效
* 保存操作有明确的成功/失败反馈

View File

@@ -0,0 +1,33 @@
1. **修复未定义函数问题**:移除对 `containsRegexSpecialChars` 函数的调用,该函数在代码中未定义
2. **修改正则表达式处理逻辑**
* 对于 `/` 包裹的规则,直接将中间内容作为正则表达式模式
* 不再添加 `.*` 前缀和后缀,也不再使用 `regexp.QuoteMeta` 转义
* 确保正则表达式能正确匹配域名中的相关内容
3. **修改文件**
* `/root/dns/shield/manager.go`:更新 `parseRule` 函数中的正则表达式处理逻辑
**验证修复**
确保 `/ad.qq.com/` 规则能正确匹配 `ad.qq.com` 域名
确保 `/ad/` 规则能匹配包含 `ad` 的域名
* 确保正则表达式特殊字符能被正确处理
* **测试场景**
* 测试 `/ad.qq.com/` 规则匹配 `ad.qq.com`
* 测试 `/ad.qq.com/` 规则匹配 `sub.ad.qq.com`
* 测试 `/ad/` 规则匹配 `ad.example.com`
* 测试 `/ad/` 规则匹配 `example.ad.com`
* 测试 `/^ad/` 规则匹配 `ad.example.com` 但不匹配 `example.ad.com`

View File

@@ -0,0 +1,44 @@
1. **修复规则添加逻辑**
* 修改`blockDomain`函数,使用正确的规则格式(如 `||domain^`
* 修改`unblockDomain`函数,使用正确的放行规则格式(如 `@@||domain^`
* 确保规则经过预处理后再发送到API
2. **更新本地规则列表**
* 添加规则成功后,更新`rules``filteredRules`数组
* 调用`renderRulesList`函数重新渲染规则列表
* 更新规则数量统计
3. **确保规则同步**
* 验证规则是否正确添加到本地规则列表
* 确保日志页面和规则页面的数据一致性
4. **优化用户体验**
* 改进操作反馈,显示更详细的成功/失败信息
* 确保规则添加后立即在日志中反映状态变化
5. **测试功能**
* 测试拦截域名功能
* 测试放行域名功能
* 验证规则是否正确添加到本地规则列表
* 验证日志状态是否正确更新
**修改文件**
* `/root/dns/static/js/logs.js`:修复`blockDomain``unblockDomain`函数
* 确保与`/root/dns/static/js/modules/rules.js`的规则处理逻辑保持一致

View File

@@ -0,0 +1,56 @@
1. **确认apiRequest函数的使用**
* 检查logs.js中apiRequest函数的来源和调用方式
* 确保使用正确的API\_BASE\_URL和异步apiRequest函数
2. **修复API调用路径**
* 确保拦截和放行功能使用正确的API路径
* 验证与规则管理模块的API调用一致性
3. **改进规则格式**
* 确保拦截和放行规则使用正确的格式
* 与规则管理模块的规则处理逻辑保持一致
4. **添加详细的错误处理**
* 在apiRequest调用中添加详细的日志
* 改进错误处理,显示更详细的错误信息
* 添加调试信息,以便跟踪问题
5. **确保跨文件函数调用正确**
* 确保logs.js能正确访问apiRequest函数
* 验证全局变量和函数的可用性
6. **测试功能**
* 测试拦截域名功能
* 测试放行域名功能
* 验证规则是否正确添加到本地规则列表
* 验证日志状态是否正确更新
**修改文件**
* `/root/dns/static/js/logs.js`修复apiRequest函数调用和API路径
**预期效果**
* 拦截功能正常工作,规则正确添加到本地规则列表
* 放行功能正常工作,规则正确添加到本地规则列表
* 日志状态立即更新,显示正确的拦截/放行状态
* 显示详细的操作反馈和错误信息

View File

@@ -0,0 +1,67 @@
## 问题分析
从截图中可以看到,日志表格显示了"Invalid Date"、"undefined"等错误值这表明前端代码在解析API返回的JSON数据时出现了问题。
## 根本原因
1. 后端`QueryLog`结构体的JSON标签使用了小写字段名`json:"timestamp"``json:"clientIP"`等)
2. 前端代码使用了大写的字段名(如`log.Timestamp``log.ClientIP`等)来访问数据
3. 字段名大小写不匹配导致前端无法正确解析API返回的数据
## 修复方案
修改前端代码使用正确的小写字段名来访问API返回的数据与后端返回的JSON格式匹配。
## 具体修改点
1. **`updateLogsTable`函数**约435-621行
*`log.Timestamp`改为`log.timestamp`
*`log.ClientIP`改为`log.clientIP`
*`log.Domain`改为`log.domain`
*`log.QueryType`改为`log.queryType`
*`log.ResponseTime`改为`log.responseTime`
*`log.Result`改为`log.result`
*`log.BlockRule`改为`log.blockRule`
*`log.FromCache`改为`log.fromCache`
*`log.DNSSEC`改为`log.dnssec`
*`log.EDNS`改为`log.edns`
*`log.DNSServer`改为`log.dnsServer`
*`log.DNSSECServer`改为`log.dnssecServer`
*`log.ResponseCode`改为`log.responseCode`
2. **`showLogDetailModal`函数**约1450-1597行
* 同样修改所有字段名的大小写
3. **其他可能的访问点**
* 检查并修改任何其他访问日志数据的地方
## 修复原则
* 保持前端代码与后端API返回的JSON格式一致
* 遵循REST API的最佳实践使用小写字段名
* 确保所有日志数据访问点都得到修复
## 验证方法
1. 修复代码后,重新编译并运行服务器
2. 访问日志页面,检查日志数据是否正确显示
3. 测试不同类型的日志(允许、屏蔽、错误),确保都能正确显示
4. 测试日志详情模态框,确保所有字段都能正确显示

View File

@@ -0,0 +1,57 @@
## 问题分析
1. **端口被占用问题**
- 服务器重启时提示端口被占用,可能是因为之前的服务器进程没有完全关闭
- 从之前的ps aux命令输出中看到有一个dns-server进程在运行PID: 233272
- 这导致新的服务器进程无法绑定到相同的端口
2. **数据保存提示no such file or directory问题**
- 配置文件中statsFile和shield_stats.json的路径格式不一致有的带./,有的不带)
- 可能存在目录创建失败或权限问题
- 程序运行时的工作目录与预期不符
## 修复方案
1. **解决端口被占用问题**
- 在启动新服务器之前,确保所有旧的服务器进程都已关闭
- 可以通过kill命令手动关闭旧进程
- 或者在程序中添加自动检测和关闭旧进程的逻辑
2. **解决数据保存问题**
- 统一配置文件中的文件路径格式,确保所有路径都使用相对路径或绝对路径
- 确保createRequiredFiles函数能够正确创建所有必要的目录和文件
- 添加错误处理,确保在目录或文件创建失败时能够给出明确的错误信息
- 检查程序运行时的工作目录,确保路径解析正确
## 修复步骤
1. **关闭旧的服务器进程**
- 使用kill命令关闭旧的dns-server进程
- 验证旧进程是否已关闭
2. **统一配置文件中的文件路径格式**
- 修改配置文件,确保所有文件路径都使用一致的格式
- 例如,将所有路径改为相对路径,不带./前缀
3. **修改createRequiredFiles函数**
- 确保函数能够正确创建所有必要的目录和文件
- 添加更详细的错误处理和日志
- 确保函数能够处理不同格式的文件路径
4. **测试修复效果**
- 启动服务器,检查是否能够成功绑定到端口
- 检查数据文件是否能够正确保存
- 重启服务器,检查是否能够正常启动
## 预期效果
- 服务器能够成功启动,不会提示端口被占用
- 数据文件能够正确保存不会提示no such file or directory
- 服务器重启时能够正常启动,不会出现相同的问题
## 注意事项
- 确保在修改配置文件之前备份原始文件
- 确保程序有足够的权限创建和写入文件
- 确保在关闭旧进程之前,所有重要的数据都已保存
- 测试修复效果时,确保覆盖所有可能的情况

View File

@@ -0,0 +1,41 @@
# 问题分析
1. **问题现象**用户点击删除按钮删除本地规则时通过API发送数据到服务器但Web界面没有自动刷新本地规则列表。
2. **问题根源**
- 后端`RemoveRule`方法存在缺陷,当删除规则时没有正确更新所有相关映射
- 前端代码虽然调用了重新加载规则列表的函数,但由于后端数据不一致,导致刷新后列表没有变化
3. **具体问题**
-`shield/manager.go``RemoveRule`方法中,删除域名规则时只从`domainRules``domainExceptions`映射中删除了规则,但没有更新`domainRulesIsLocal``domainExceptionsIsLocal``domainRulesSource``domainExceptionsSource`映射
- 处理正则表达式规则时,使用了错误的比较方式(`re.pattern.String() != pattern`),而应该使用原始规则字符串进行比较
# 修复方案
1. **修复`RemoveRule`方法**
- 当删除域名规则时,同时更新所有相关映射
- 当删除排除规则时,同时更新所有相关映射
- 修复正则表达式规则的比较方式,使用原始规则字符串进行比较
2. **验证前端代码**
- 确认前端代码在删除规则后正确调用了重新加载规则列表的函数
- 验证前端代码处理API响应的逻辑是否正确
# 实现步骤
1. 修改`shield/manager.go`文件中的`RemoveRule`方法:
- 在删除域名规则时,添加删除`domainRulesIsLocal``domainRulesSource`映射的代码
- 在删除排除规则时,添加删除`domainExceptionsIsLocal``domainExceptionsSource`映射的代码
- 修复正则表达式规则的比较方式
2. 测试修复后的功能:
- 启动DNS服务器
- 访问Web界面添加几条本地规则
- 点击删除按钮删除其中一条规则
- 验证规则列表是否自动刷新,且删除的规则不再显示
# 预期结果
- 用户点击删除按钮后,规则被成功删除
- Web界面自动刷新删除的规则从列表中消失
- 本地规则文件被正确更新,删除的规则不再存在于文件中

View File

@@ -0,0 +1,51 @@
## 问题分析
通过代码分析,我发现本地规则管理删除规则功能失效的原因有两个:
1. **规则格式不匹配**
- 前端显示的规则带有修饰符,例如:`||example.com^`
- 服务器端实际存储的是裸域名,例如:`example.com`
- `RemoveRule` 函数在处理规则时,虽然尝试了多种格式变体,但没有正确处理前端发送的带有修饰符的规则
2. **本地规则标记未更新**
- `RemoveRule` 函数没有考虑 `m.domainRulesIsLocal``m.domainExceptionsIsLocal` 映射,这些映射用于标记哪些规则是本地规则
- 删除规则后,没有更新这些映射,导致规则删除不彻底
## 修复计划
1. **修改 `RemoveRule` 函数**
- 改进规则处理逻辑,确保能正确处理带有修饰符的规则
- 更新 `domainRulesIsLocal``domainExceptionsIsLocal` 映射,确保本地规则被正确删除
2. **修改 `GetLocalRules` 函数**
- 确保返回的规则格式与 `RemoveRule` 函数期望的格式一致
3. **添加调试日志**
- 在关键位置添加日志,便于调试和监控规则删除过程
## 修复步骤
### 步骤1修改 `RemoveRule` 函数
`shield/manager.go` 文件中,修改 `RemoveRule` 函数,改进规则处理逻辑:
1. 确保正确处理带有修饰符的规则
2. 更新 `domainRulesIsLocal``domainExceptionsIsLocal` 映射
3. 添加调试日志
### 步骤2测试修复效果
- 启动服务器
- 访问本地规则管理页面
- 添加一条本地规则
- 删除该规则
- 验证规则是否被正确删除,页面内容是否减少
## 预期效果
修复后,本地规则管理删除规则功能将正常工作:
- 点击删除按钮后,规则会被正确发送到服务器
- 服务器会正确处理带有修饰符的规则
- 本地规则标记会被正确更新
- 规则会被持久化保存
- 页面内容会立即减少
这样就能确保本地规则管理删除规则功能正常工作,提供良好的用户体验。

View File

@@ -0,0 +1,21 @@
1. **问题分析**
- 当添加自定义规则时,规则被添加到内存中并保存到文件
- 但由于DNS缓存的存在如果该域名的DNS响应已经被缓存那么在缓存过期之前DNS服务器会直接返回缓存的响应而不会重新检查规则
- 这就导致了添加规则后需要重启服务器才能生效的问题
2. **修复方案**
- 当添加或删除自定义规则时清空DNS缓存这样新的规则会立即生效
- 这样当客户端再次请求该域名时DNS服务器会重新检查规则而不是直接返回缓存的响应
3. **修复步骤**
- 修改HTTP API处理函数在添加或删除规则后清空DNS缓存
- 或者修改ShieldManager的AddRule和RemoveRule方法添加清空DNS缓存的逻辑
- 测试修复后的功能,确保添加规则后无需重启服务器即可生效
4. **预期结果**
- 添加自定义规则后,规则会立即生效,无需重启服务器
- 重启服务器后,之前添加的自定义规则仍然存在
5. **具体实现**
-`/root/dns/http/server.go`在添加或删除规则的API处理函数后调用DNS缓存的Clear方法
- 这样当添加或删除规则时DNS缓存会被清空新的规则会立即生效

Some files were not shown because too many files have changed in this diff Show More