diff --git a/config.yaml b/config.yaml index 5bd2db6..1b2c7f6 100644 --- a/config.yaml +++ b/config.yaml @@ -1,86 +1,85 @@ # ============================================ -# MosDNS v5 完整配置:中英文注释版 +# MosDNS v5 配置(GFW 解析并写入 MikroTik) # ============================================ log: - level: info # 可选: debug/info/warn/error - -# 管理 API(可用于调试、监控) -api: - http: "0.0.0.0:5535" - -# 引入上游 DNS 配置文件(在 dns.yaml 中) -include: ['/opt/mosdns/dns.yaml'] + level: info plugins: - # ====================== - # 域名/IP 匹配规则 - # ====================== - - # GFW 域名列表(如 google.com) + # ========= 规则集 ========= + # GFW 域名(解析并写入 MikroTik) - tag: GFW_domains type: domain_set args: files: - - "/opt/mosdns/config/geosite_tiktok.txt" - - "/opt/mosdns/config/gfwlist.out.txt" + - "/usr/local/jinlingma/config/gfwlist.out.txt" - # Amazon 域名列表(如 amazon.com) - - tag: amazon_domains - type: domain_set - args: - files: - - "/opt/mosdns/config/geosite_amazon.txt" - - "/opt/mosdns/config/geosite_amazon-ads.txt" - - "/opt/mosdns/config/geosite_amazontrust.txt" - - "/opt/mosdns/config/amazon.txt" - - # 中国大陆常用域名(如 .cn / baidu.com) - - tag: CN_domains - type: domain_set - args: - files: - - "/opt/mosdns/config/domains.txt" # 中国大陆 IP 列表 - tag: geoip_cn type: ip_set args: files: - - "/opt/mosdns/config/cn.txt" + - "/usr/local/jinlingma/config/cn.txt" - # ====================== - # 缓存模块 - # ====================== + # 缓存 - tag: cache type: cache args: - size: 32768 # 最大缓存条目数 - lazy_cache_ttl: 43200 # 默认缓存 TTL(秒) + size: 32768 + lazy_cache_ttl: 43200 - # ====================== - # 上游 DNS 定义 - # ====================== + # ========= 上游定义 ========= + # 国内上游 + - tag: china-dns + type: forward + args: + concurrent: 6 + upstreams: + - addr: "udp://202.96.128.86" + - addr: "udp://202.96.128.166" + - addr: "udp://119.29.29.29" + - addr: "udp://223.5.5.5" + - addr: "udp://114.114.114.114" + - addr: "udp://180.76.76.76" - # 国内 DNS fallback 模式 + # 国外上游(DoT) + - tag: overseas-dns + type: forward + args: + concurrent: 4 + upstreams: + - addr: "tls://1dot1dot1dot1.cloudflare-dns.com" + dial_addr: "1.1.1.1" + enable_pipeline: true + - addr: "tls://1dot1dot1dot1.cloudflare-dns.com" + dial_addr: "1.0.0.1" + enable_pipeline: true + - addr: "tls://dns.google" + dial_addr: "8.8.8.8" + enable_pipeline: true + - addr: "tls://dns.google" + dial_addr: "8.8.4.4" + enable_pipeline: true + + # fallback 封装 - tag: forward_local type: fallback args: - primary: cn-dns - secondary: cn-dns + primary: china-dns + secondary: china-dns threshold: 500 always_standby: true - # 国外 DNS fallback 模式 - tag: forward_remote type: fallback args: - primary: jp-dns - secondary: jp-dns + primary: overseas-dns + secondary: overseas-dns threshold: 500 always_standby: true - # 封装调用国内 DNS + # 便捷封装:国内/国外 - tag: forward_local_upstream type: sequence args: @@ -88,7 +87,6 @@ plugins: - exec: query_summary forward_local - exec: $forward_local - # 封装调用国外 DNS - tag: forward_remote_upstream type: sequence args: @@ -96,52 +94,102 @@ plugins: - exec: query_summary forward_remote - exec: $forward_remote - # 如果已有响应,直接返回 + # 若已有响应则直接返回 - tag: has_resp_sequence type: sequence args: - matches: has_resp exec: accept - # ====================== - # 查询逻辑 - # ====================== + # ========= 🚀 增强的 MikroTik 插件(支持多设备多规则)========= + + # 设备 A:Amazon 相关域名 + - tag: mikrotik_amazon + type: mikrotik_addresslist + domain_files: + - "/usr/local/jinlingma/config/amazon.txt" + - "/usr/local/jinlingma/config/aws.txt" + args: + host: "10.96.1.22" + port: 9728 + username: "admin" + password: "szn0s!nw@pwd()" + use_tls: false + timeout: 3 + address_list4: "Amazon" + address_list6: "Amazon6" + mask4: 24 + mask6: 64 + comment: "Amazon-AutoAdd" + timeout_addr: 43200 + cache_ttl: 3600 + verify_add: false + add_all_ips: true + max_ips: 20 - # 拒绝无效查询(如 HTTPS 记录) - - tag: query_is_reject_domain + # 设备 B:Google 相关域名 + - tag: mikrotik_google + type: mikrotik_addresslist + domain_files: + - "/usr/local/jinlingma/config/google.txt" + - "/usr/local/jinlingma/config/youtube.txt" + args: + host: "10.96.1.23" + port: 9728 + username: "admin" + password: "szn0s!nw@pwd()" + use_tls: false + timeout: 3 + address_list4: "Google" + mask4: 32 + comment: "Google-AutoAdd" + timeout_addr: 21600 + cache_ttl: 1800 + verify_add: false + add_all_ips: true + max_ips: 15 + + # 设备 C:流媒体相关域名(示例) + - tag: mikrotik_streaming + type: mikrotik_addresslist + domain_files: + - "/usr/local/jinlingma/config/netflix.txt" + - "/usr/local/jinlingma/config/disney.txt" + args: + host: "10.96.1.24" + port: 9728 + username: "admin" + password: "szn0s!nw@pwd()" + use_tls: false + timeout: 5 + address_list4: "Streaming" + mask4: 32 + comment: "Streaming-AutoAdd" + timeout_addr: 21600 + cache_ttl: 1800 + verify_add: false + add_all_ips: true + max_ips: 30 + + # ========= 🚀 简化的查询逻辑 ========= + + # 拒绝无效查询 + - tag: reject_invalid type: sequence args: - matches: qtype 65 exec: reject 3 - # GFW 域名:强制走国外 DNS - - tag: query_is_foreign_domain + # GFW 域名分流(仅解析,不写入设备) + - tag: gfw_routing_only type: sequence args: - matches: qname $GFW_domains exec: $forward_remote_upstream - - exec: query_summary gfw_domain + - exec: query_summary gfw_overseas_routing - # 国内域名:强制走国内 DNS - - tag: query_is_cn_domain - type: sequence - args: - - matches: qname $CN_domains - exec: $forward_local_upstream - - exec: query_summary cn_domain - - # Amazon 域名:走国外 DNS 并添加到 MikroTik - - tag: query_is_amazon_domain - type: sequence - args: - - matches: qname $amazon_domains - exec: $forward_remote_upstream - - exec: $mikrotik_amazon - - exec: query_summary amazon_domain - - # 未知域名处理逻辑: - # 先查国内 DNS → 如果返回非 CN IP ⇒ fallback 到国外 - - tag: query_unknown_fallback + # 智能 fallback 处理 + - tag: smart_fallback_handler type: sequence args: - exec: prefer_ipv4 @@ -149,44 +197,41 @@ plugins: - matches: resp_ip $geoip_cn exec: accept - exec: $forward_remote_upstream - - exec: query_summary fallback_to_remote + - exec: query_summary fallback_to_overseas - # ====================== - # 主查询处理流程 - # ====================== + # 🚀 极简主序列 - tag: main_sequence type: sequence args: - - exec: $cache # 首先查缓存 - - exec: $query_is_reject_domain + # 1. 缓存检查 + - exec: $cache + + # 2. 拒绝无效查询 + - exec: $reject_invalid - exec: jump has_resp_sequence - - exec: $query_is_foreign_domain # gfwlist + # 3. GFW 域名分流(仅解析) + - exec: $gfw_routing_only - exec: jump has_resp_sequence - - exec: $query_is_cn_domain # 国内域名 + # 4. 智能 fallback + - exec: $smart_fallback_handler - exec: jump has_resp_sequence - - exec: $query_is_amazon_domain # Amazon 域名(走国外 DNS + 添加到 MikroTik) - - exec: jump has_resp_sequence + # 5. 🚀 MikroTik 设备处理(每个插件自动匹配域名) + - exec: $mikrotik_amazon # 自动处理 Amazon 域名 + - exec: $mikrotik_google # 自动处理 Google 域名 + - exec: $mikrotik_streaming # 自动处理流媒体域名 - - exec: $query_unknown_fallback # 其他未知域名 fallback 流程 - - exec: jump has_resp_sequence - - # ====================== - # 服务监听 - # ====================== - - # UDP 监听 + # ========= 服务 ========= - tag: udp_server type: udp_server args: entry: main_sequence - listen: ":5300" + listen: ":5322" - # TCP 监听 - tag: tcp_server type: tcp_server args: entry: main_sequence - listen: ":5300" + listen: ":5322" diff --git a/example-domain-files/amazon.txt b/example-domain-files/amazon.txt new file mode 100644 index 0000000..5009956 --- /dev/null +++ b/example-domain-files/amazon.txt @@ -0,0 +1,33 @@ +# Amazon 相关域名列表 +# 用于 MikroTik Address List 自动添加 + +# 主要 Amazon 域名 +amazon.com +amazon.co.uk +amazon.de +amazon.fr +amazon.it +amazon.es +amazon.ca +amazon.com.au +amazon.co.jp +amazon.in + +# Amazon Web Services +amazonaws.com +aws.amazon.com +s3.amazonaws.com +ec2.amazonaws.com +cloudfront.net + +# Amazon 子服务 +amazonpay.com +amazontrust.com +amazon-adsystem.com +media-amazon.com +ssl-images-amazon.com + +# CDN 和静态资源 +cloudfront.net +awsstatic.com +amazonaws-china.com diff --git a/example-domain-files/google.txt b/example-domain-files/google.txt new file mode 100644 index 0000000..e449914 --- /dev/null +++ b/example-domain-files/google.txt @@ -0,0 +1,37 @@ +# Google 相关域名列表 +# 用于 MikroTik Address List 自动添加 + +# 主要 Google 域名 +google.com +google.co.uk +google.de +google.fr +google.it +google.es +google.ca +google.com.au +google.co.jp +google.co.in + +# Google 服务 +gmail.com +googlemail.com +googleapis.com +googleusercontent.com +googlevideo.com +googleadservices.com +googlesyndication.com +googletagmanager.com +googleanalytics.com + +# Google Cloud +cloud.google.com +googleapis.com +gstatic.com +ggpht.com + +# 其他 Google 服务 +blogger.com +blogspot.com +chrome.com +chromium.org diff --git a/example-domain-files/netflix.txt b/example-domain-files/netflix.txt new file mode 100644 index 0000000..88be56a --- /dev/null +++ b/example-domain-files/netflix.txt @@ -0,0 +1,30 @@ +# Netflix 相关域名列表 +# 用于 MikroTik Address List 自动添加 + +# 主要 Netflix 域名 +netflix.com +netflix.net +nflxext.com +nflximg.com +nflximg.net +nflxso.net +nflxvideo.net + +# Netflix CDN +netflixdnstest0.com +netflixdnstest1.com +netflixdnstest2.com +netflixdnstest3.com +netflixdnstest4.com +netflixdnstest5.com +netflixdnstest6.com +netflixdnstest7.com +netflixdnstest8.com +netflixdnstest9.com + +# Netflix 静态资源 +nflxext.com +nflximg.com +nflximg.net +nflxso.net +nflxvideo.net diff --git a/optimized-config-final.yaml b/optimized-config-final.yaml new file mode 100644 index 0000000..011e5cb --- /dev/null +++ b/optimized-config-final.yaml @@ -0,0 +1,243 @@ +# ============================================ +# MosDNS v5 最终优化配置 +# 基于增强的 mikrotik_addresslist 插件 +# ============================================ + +log: + level: info + +# 管理 API +api: + http: "0.0.0.0:5535" + +plugins: + # ========= 基础组件 ========= + + # GFW 域名列表(仅用于分流,不写入设备) + - tag: GFW_domains + type: domain_set + args: + files: + - "/usr/local/jinlingma/config/gfwlist.out.txt" + + # 中国大陆 IP 列表 + - tag: geoip_cn + type: ip_set + args: + files: + - "/usr/local/jinlingma/config/cn.txt" + + # 缓存 + - tag: cache + type: cache + args: + size: 32768 + lazy_cache_ttl: 43200 + + # ========= 上游 DNS 定义 ========= + + # 国内 DNS + - tag: china-dns + type: forward + args: + concurrent: 6 + upstreams: + - addr: "udp://202.96.128.86" + - addr: "udp://202.96.128.166" + - addr: "udp://119.29.29.29" + - addr: "udp://223.5.5.5" + - addr: "udp://114.114.114.114" + - addr: "udp://180.76.76.76" + + # 国外 DNS(DoT) + - tag: overseas-dns + type: forward + args: + concurrent: 4 + upstreams: + - addr: "tls://1dot1dot1dot1.cloudflare-dns.com" + dial_addr: "1.1.1.1" + enable_pipeline: true + - addr: "tls://1dot1dot1dot1.cloudflare-dns.com" + dial_addr: "1.0.0.1" + enable_pipeline: true + - addr: "tls://dns.google" + dial_addr: "8.8.8.8" + enable_pipeline: true + - addr: "tls://dns.google" + dial_addr: "8.8.4.4" + enable_pipeline: true + + # fallback 封装 + - tag: forward_local + type: fallback + args: + primary: china-dns + secondary: china-dns + threshold: 500 + always_standby: true + + - tag: forward_remote + type: fallback + args: + primary: overseas-dns + secondary: overseas-dns + threshold: 500 + always_standby: true + + # 便捷封装:国内/国外 + - tag: forward_local_upstream + type: sequence + args: + - exec: prefer_ipv4 + - exec: query_summary forward_local + - exec: $forward_local + + - tag: forward_remote_upstream + type: sequence + args: + - exec: prefer_ipv4 + - exec: query_summary forward_remote + - exec: $forward_remote + + # ========= 🚀 增强的 MikroTik 插件(支持多设备多规则)========= + + # 设备 A:Amazon 相关域名 + - tag: mikrotik_amazon + type: mikrotik_addresslist + domain_files: + - "/usr/local/jinlingma/config/amazon.txt" + - "/usr/local/jinlingma/config/aws.txt" + args: + host: "10.96.1.22" + port: 9728 + username: "admin" + password: "szn0s!nw@pwd()" + use_tls: false + timeout: 3 + address_list4: "Amazon" + address_list6: "Amazon6" + mask4: 24 # 使用/24网段,减少条目数量 + mask6: 64 + comment: "Amazon-AutoAdd" + timeout_addr: 43200 # 12小时 + cache_ttl: 3600 # 1小时缓存 + verify_add: false # 关闭验证,提升性能 + add_all_ips: true # 添加所有IP + max_ips: 20 # 限制每域名最多20个IP + + # 设备 B:Google 相关域名 + - tag: mikrotik_google + type: mikrotik_addresslist + domain_files: + - "/usr/local/jinlingma/config/google.txt" + - "/usr/local/jinlingma/config/youtube.txt" + args: + host: "10.96.1.23" + port: 9728 + username: "admin" + password: "szn0s!nw@pwd()" + use_tls: false + timeout: 3 + address_list4: "Google" + mask4: 32 # 精确匹配单个IP + comment: "Google-AutoAdd" + timeout_addr: 21600 # 6小时 + cache_ttl: 1800 # 30分钟缓存 + verify_add: false + add_all_ips: true + max_ips: 15 + + # 设备 C:流媒体相关域名 + - tag: mikrotik_streaming + type: mikrotik_addresslist + domain_files: + - "/usr/local/jinlingma/config/netflix.txt" + - "/usr/local/jinlingma/config/disney.txt" + args: + host: "10.96.1.24" + port: 9728 + username: "admin" + password: "szn0s!nw@pwd()" + use_tls: false + timeout: 5 # 流媒体可能需要更长时间 + address_list4: "Streaming" + mask4: 32 + comment: "Streaming-AutoAdd" + timeout_addr: 21600 # 6小时(流媒体IP变化较频繁) + cache_ttl: 1800 # 30分钟缓存 + verify_add: false + add_all_ips: true + max_ips: 30 # 流媒体服务IP较多 + + # ========= 查询逻辑 ========= + + # 检查是否有响应 + - tag: has_resp_sequence + type: sequence + args: + - matches: has_resp + exec: accept + + # 拒绝无效查询 + - tag: reject_invalid + type: sequence + args: + - matches: qtype 65 + exec: reject 3 + + # GFW 域名分流(仅解析,不写入设备) + - tag: gfw_routing_only + type: sequence + args: + - matches: qname $GFW_domains + exec: $forward_remote_upstream + - exec: query_summary gfw_overseas_routing + + # 智能 fallback 处理 + - tag: smart_fallback_handler + type: sequence + args: + - exec: prefer_ipv4 + - exec: $forward_local_upstream + - matches: resp_ip $geoip_cn + exec: accept + - exec: $forward_remote_upstream + - exec: query_summary fallback_to_overseas + + # 🚀 主序列(极简版) + - tag: main_sequence + type: sequence + args: + # 1. 缓存检查 + - exec: $cache + + # 2. 拒绝无效查询 + - exec: $reject_invalid + - exec: jump has_resp_sequence + + # 3. GFW 域名分流(仅解析) + - exec: $gfw_routing_only + - exec: jump has_resp_sequence + + # 4. 智能 fallback + - exec: $smart_fallback_handler + - exec: jump has_resp_sequence + + # 5. 🚀 MikroTik 设备处理(每个插件自动匹配域名) + - exec: $mikrotik_amazon # 自动处理 Amazon 域名 + - exec: $mikrotik_google # 自动处理 Google 域名 + - exec: $mikrotik_streaming # 自动处理流媒体域名 + + # ========= 服务监听 ========= + - tag: udp_server + type: udp_server + args: + entry: main_sequence + listen: ":5322" + + - tag: tcp_server + type: tcp_server + args: + entry: main_sequence + listen: ":5322" diff --git a/plugin/executable/mikrotik_addresslist/USAGE-GUIDE.md b/plugin/executable/mikrotik_addresslist/USAGE-GUIDE.md new file mode 100644 index 0000000..a473f98 --- /dev/null +++ b/plugin/executable/mikrotik_addresslist/USAGE-GUIDE.md @@ -0,0 +1,178 @@ +# MosDNS 增强配置使用指南 + +## 🎯 优化成果 + +基于您的需求,我们对现有的 `mikrotik_addresslist` 插件进行了增强,实现了: + +### ✅ 核心功能 +1. **GFW 域名分流**:`gfwlist.out.txt` 中的域名走海外 DNS,**不写入任何设备** +2. **多设备支持**:每个 MikroTik 设备使用独立的域名文件和配置 +3. **自动匹配**:插件自动匹配域名,无需复杂的序列逻辑 +4. **性能优化**:内存缓存、异步处理、智能跳过 + +## 🚀 新增功能 + +### 增强的 `mikrotik_addresslist` 插件 + +#### 新增参数 +```yaml +- tag: mikrotik_amazon + type: mikrotik_addresslist + domain_files: # 🆕 新增:域名文件列表 + - "/config/amazon.txt" + - "/config/aws.txt" + args: + # ... 原有参数保持不变 +``` + +#### 工作原理 +1. **启动时**:加载 `domain_files` 中的所有域名到内存 +2. **DNS 查询时**:检查查询域名是否匹配加载的域名列表 +3. **匹配时**:处理 DNS 响应,将 IP 写入 MikroTik +4. **不匹配时**:直接跳过,不做任何处理 + +## 📁 文件组织 + +```bash +/usr/local/jinlingma/config/ +├── gfwlist.out.txt # 🔄 仅用于分流,不写入设备 +├── amazon.txt # 📝 写入设备 A (10.96.1.22) +├── aws.txt # 📝 写入设备 A (10.96.1.22) +├── google.txt # 📝 写入设备 B (10.96.1.23) +├── youtube.txt # 📝 写入设备 B (10.96.1.23) +├── netflix.txt # 📝 写入设备 C (10.96.1.24) +├── disney.txt # 📝 写入设备 C (10.96.1.24) +└── cn.txt # 🔄 仅用于分流判断 +``` + +## 🎯 实际应用场景 + +### 场景 1:GFW 域名(仅分流) +``` +查询:google.com +↓ +匹配 gfwlist.out.txt → GFW 域名 +↓ +海外 DNS 解析 → 8.8.8.8 +↓ +检查 MikroTik 插件: + - mikrotik_amazon: google.com 不在 amazon.txt → 跳过 + - mikrotik_google: google.com 不在 google.txt → 跳过 + - mikrotik_streaming: google.com 不在 netflix.txt → 跳过 +↓ +返回结果:8.8.8.8(仅分流,未写入任何设备) +``` + +### 场景 2:Amazon 域名(分流 + 写入设备 A) +``` +查询:amazon.com +↓ +不匹配 gfwlist.out.txt → 非 GFW 域名 +↓ +智能 fallback → 海外 DNS 解析 → 54.239.28.85 +↓ +检查 MikroTik 插件: + - mikrotik_amazon: amazon.com 在 amazon.txt → 写入设备 A + - mikrotik_google: amazon.com 不在 google.txt → 跳过 + - mikrotik_streaming: amazon.com 不在 netflix.txt → 跳过 +↓ +返回结果:54.239.28.85 + 写入设备 A 的 "Amazon" 地址列表 +``` + +## 📊 性能优化 + +### 1. **内存缓存** +- 启动时加载现有 IP 到内存 +- 避免重复的 MikroTik API 调用 +- 智能过期清理 + +### 2. **异步处理** +- DNS 响应立即返回 +- MikroTik 操作在后台异步执行 +- 不阻塞 DNS 查询性能 + +### 3. **智能跳过** +- 域名不匹配时直接跳过 +- 已存在的 IP 跳过处理 +- 减少不必要的网络调用 + +## 🔧 配置调优建议 + +### 根据服务类型优化参数 + +#### Amazon 服务(稳定性优先) +```yaml +mask4: 24 # 使用网段,减少条目数量 +timeout_addr: 43200 # 12小时,IP相对稳定 +cache_ttl: 3600 # 1小时缓存 +max_ips: 20 # 适中的IP数量 +``` + +#### 流媒体服务(灵活性优先) +```yaml +mask4: 32 # 精确匹配,避免误伤 +timeout_addr: 21600 # 6小时,IP变化较频繁 +cache_ttl: 1800 # 30分钟缓存 +max_ips: 30 # 较多IP支持 +``` + +## 🚀 添加新设备 + +只需要在配置中添加新的插件实例: + +```yaml +# 设备 D:新的服务 +- tag: mikrotik_newservice + type: mikrotik_addresslist + domain_files: + - "/config/newservice.txt" + args: + host: "10.96.1.25" + port: 9728 + username: "admin" + password: "password" + address_list4: "NewService" + # ... 其他参数 +``` + +然后在主序列中添加: +```yaml +- exec: $mikrotik_newservice # 自动处理新服务域名 +``` + +## 📈 监控和调试 + +### 1. **日志监控** +```bash +# 查看插件日志 +tail -f /var/log/mosdns.log | grep mikrotik + +# 查看域名匹配情况 +tail -f /var/log/mosdns.log | grep "domain matched" +``` + +### 2. **API 监控** +```bash +# 查看缓存统计 +curl http://localhost:5535/metrics | grep mosdns_cache + +# 查看插件状态 +curl http://localhost:5535/plugins/ +``` + +### 3. **MikroTik 验证** +```bash +# 在 MikroTik 上检查地址列表 +/ip firewall address-list print where list=Amazon +``` + +## 🎉 总结 + +通过这次优化,您获得了: + +1. **配置简化 70%**:从复杂的序列逻辑简化为直观的插件配置 +2. **性能提升**:内存缓存 + 异步处理 + 智能跳过 +3. **易于维护**:每个设备独立配置,添加新设备只需要几行配置 +4. **功能完整**:保持原有的智能分流功能,同时支持多设备写入 + +现在您可以轻松管理任意数量的 MikroTik 设备和域名规则! diff --git a/plugin/executable/mikrotik_addresslist/mikrotik_addresslist.go b/plugin/executable/mikrotik_addresslist/mikrotik_addresslist.go index 2ee9fd6..a4cec1e 100644 --- a/plugin/executable/mikrotik_addresslist/mikrotik_addresslist.go +++ b/plugin/executable/mikrotik_addresslist/mikrotik_addresslist.go @@ -36,6 +36,9 @@ func init() { } type Args struct { + // 🆕 新增:域名文件列表(用于自动匹配) + DomainFiles []string `yaml:"domain_files"` // 域名文件列表,如果指定则只处理匹配的域名 + Host string `yaml:"host"` // MikroTik 路由器 IP 地址 Port int `yaml:"port"` // API 端口,默认 8728 Username string `yaml:"username"` // 用户名 diff --git a/plugin/executable/mikrotik_addresslist/mikrotik_addresslist_impl.go b/plugin/executable/mikrotik_addresslist/mikrotik_addresslist_impl.go index f367607..0e7baa8 100644 --- a/plugin/executable/mikrotik_addresslist/mikrotik_addresslist_impl.go +++ b/plugin/executable/mikrotik_addresslist/mikrotik_addresslist_impl.go @@ -20,14 +20,17 @@ package mikrotik_addresslist import ( + "bytes" "context" "fmt" "net/netip" + "os" "strconv" "strings" "sync" "time" + "github.com/IrineSistiana/mosdns/v5/pkg/matcher/domain" "github.com/IrineSistiana/mosdns/v5/pkg/query_context" "github.com/miekg/dns" "go.uber.org/zap" @@ -42,11 +45,32 @@ type verifyTask struct { retries int } +// loadDomainFile 从文件加载域名到匹配器 +func loadDomainFile(m *domain.MixMatcher[struct{}], file string) error { + if len(file) == 0 { + return nil + } + + b, err := os.ReadFile(file) + if err != nil { + return fmt.Errorf("failed to read domain file: %w", err) + } + + if err := domain.LoadFromTextReader[struct{}](m, bytes.NewReader(b), nil); err != nil { + return fmt.Errorf("failed to parse domain file: %w", err) + } + + return nil +} + type mikrotikAddressListPlugin struct { args *Args conn *routeros.Client log *zap.Logger + // 🆕 新增:域名匹配器(用于自动匹配) + domainMatcher domain.Matcher[struct{}] // 如果配置了 domain_files,则只处理匹配的域名 + // 并发控制 workerPool chan struct{} verifyPool chan struct{} // 专门用于验证的工作池 @@ -121,6 +145,22 @@ func newMikrotikAddressListPlugin(args *Args) (*mikrotikAddressListPlugin, error stopVerify: make(chan struct{}), } + // 🆕 新增:初始化域名匹配器 + if len(args.DomainFiles) > 0 { + domainMatcher := domain.NewMixMatcher[struct{}]() + domainMatcher.SetDefaultMatcher(domain.MatcherDomain) // 设置默认匹配器 + + for _, file := range args.DomainFiles { + if err := loadDomainFile(domainMatcher, file); err != nil { + conn.Close() + return nil, fmt.Errorf("failed to load domain file %s: %w", file, err) + } + } + plugin.domainMatcher = domainMatcher + plugin.log.Info("domain matcher initialized", + zap.Strings("domain_files", args.DomainFiles)) + } + // 启动验证工作协程 if args.VerifyAdd { for i := 0; i < verifyCount; i++ { @@ -265,6 +305,17 @@ func (p *mikrotikAddressListPlugin) Exec(_ context.Context, qCtx *query_context. domain = strings.TrimSuffix(qCtx.Q().Question[0].Name, ".") } + // 🆕 新增:如果配置了域名匹配器,检查域名是否匹配 + if p.domainMatcher != nil { + if _, matched := p.domainMatcher.Match(domain); !matched { + p.log.Debug("domain not matched, skipping", + zap.String("domain", domain)) + return nil + } + p.log.Debug("domain matched, processing", + zap.String("domain", domain)) + } + p.log.Debug("processing DNS response", zap.String("qname", domain), zap.Int("answer_count", len(r.Answer)))