V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
marquina
V2EX  ›  分享创造

用 Go 写了一个老少皆宜的 DNS 分流/转发器: TS-DNS

  •  1
     
  •   marquina · 2020-03-09 14:59:37 +08:00 · 2767 次点击
    这是一个创建于 1502 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Telescope DNS

    • 支持多 hosts 文件 + 手动指定 hosts
    • 支持按手动后缀匹配 /半智能污染检测 /GFWList 进行分组
    • DNS 查询支持 socks5 代理
    • 简单 DNS 记录缓存

    地址: https://github.com/wolf-joe/ts-dns 欢迎尝试~

    TODO:

    • GoReleaser
    • 智能 DNS 缓存
    • 自动添加 IPSET

    配置文件

    默认情况(配置文件读取失败)时使用如下配置:

    listen = ":53"
    
    [groups]
      [groups.clean]
      dns = ["119.29.29.29", "223.5.5.5", "114.114.114.114"]
    
      [groups.dirty]
      dns = ["208.67.222.222:5353", "176.103.130.130:5353"]
      suffix = ["google.com", "twimg.com", "quoracdn.net"]
    

    完整配置示例:

    listen = ":53"
    gfwlist = "gfwlist.txt"
    hosts_files = ["/etc/hosts"]
    
    [redis]
    host = "localhost:6379"
    password = ""
    db = 10
    
    [hosts]
    "example.com" = "8.8.8.8"
    
    [groups]
      [groups.clean]
      dns = ["119.29.29.29", "223.5.5.5", "114.114.114.114"]
    
      [groups.dirty]
      socks5 = "127.0.0.1:1080"
      dns = ["8.8.8.8", "1.1.1.1"]
      suffix = ["google.com", "twimg.com", "quoracdn.net"]
    
      [groups.work]
      dns = ["10.1.1.1"]
      suffix = ["company.com"]
    

    特别鸣谢: /t/649297 @suspended @XiaoxiaoPu

    第 1 条附言  ·  2020-03-09 17:02:47 +08:00
    配置了 goreleaser,现在可以直接在 github 的 release 界面直接下载二进制包了~
    第 2 条附言  ·  2020-03-11 14:33:35 +08:00
    v0.2.0 发布:
    * 自动添加 IPSet 记录
    * 智能 DNS 缓存
    * 动态加载 hosts
    * 强制使用 gfwlist 功能
    * release 包中添加最新 gfwlist.txt
    * full.toml 添加注释
    * 优化日志输出

    代码相关:
    * 优化代码结构
    * 部分模块添加单元测试
    第 3 条附言  ·  2020-03-12 17:26:48 +08:00
    v0.3.0 发布~
    * 支持 EDNS Client-Subnet 缓存
    * 移除污染检测模块
    * 取消自动重载 hosts 文件
    * 增强域名匹配规则 /GFWList 匹配

    代码相关
    * 模块化 N 个组件并添加相应单元测试

    v0.4.0 预告~
    加入 DNS over TCP/TLS/HTTPS 支持
    第 4 条附言  ·  2020-03-12 19:04:29 +08:00
    没错我又来了……v0.4.0 已发布
    * 增加支持 DNS over TCP/TLS/HTTPS

    现在功能应该比较完善了,再次欢迎大家尝试
    第 5 条附言  ·  2020-03-15 16:24:56 +08:00
    change log:
    v0.4.1:修复 DNS 缓存数据竞争 BUG
    v0.5.0:使用 CNIP 列表完善域名分组机制
    v0.5.1:支持 gfwlist 内关于 google 的正则
    v0.6.0:支持自动重载配置文件;修复 v0.5.0 出现的空指针 bug
    第 6 条附言  ·  2020-03-18 15:46:17 +08:00
    v0.7.0 更新:支持并发请求上游 DNS
    第 7 条附言  ·  2020-03-20 12:32:06 +08:00
    v0.8.0:支持 dns 缓存 ttl 倒计时;修复 dns 响应 ttl 覆盖 /hosts 自动重载 bug ;添加 mips 相关 release 并减少 release 包体积;
    第 8 条附言  ·  2020-03-28 17:45:54 +08:00
    v0.9.0:支持选择 ping 值最低 ipv4 地址
    第 9 条附言  ·  2020-04-05 18:09:10 +08:00
    v0.10.0:支持用 tcp ping 对 ipv4 进行测速;修复 ipv4 测速结果异常 bug ;支持对请求日志进行过滤。
    第 10 条附言  ·  2020-04-15 16:46:41 +08:00
    v0.11.0 发布,支持默认附带 ECS 信息转发 DNS 请求;可选是否以 base64 解码 gfwlist ;支持 debug 模式。
    75 条回复    2020-06-02 09:26:04 +08:00
    marquina
        1
    marquina  
    OP
       2020-03-09 15:11:08 +08:00
    GO 新手,持续开发中,欢迎试用、交流~
    1847bell
        2
    1847bell  
       2020-03-09 15:17:03 +08:00
    插眼看能活多久
    marquina
        3
    marquina  
    OP
       2020-03-09 15:20:13 +08:00
    @1847bell 没这么夸张吧,我鸣谢的那个帖子一周了也还在啊😂
    wysnylc
        4
    wysnylc  
       2020-03-09 16:12:19 +08:00
    建议一个新功能:同时请求多个 DNS,根据返回的 IP 进行 tcping,使用响应最快的 ip
    marquina
        5
    marquina  
    OP
       2020-03-09 17:08:58 +08:00
    @wysnylc 那最后是不是只会响应一个 ip ?
    mwylaoma
        6
    mwylaoma  
       2020-03-09 17:10:30 +08:00
    @marquina 刚刚用 go get 编译了,不错,在用,redis 如果不使用,应该没什么大问题吧
    sujin190
        7
    sujin190  
       2020-03-09 17:11:33 +08:00
    支持 edns 缓存不呐?试了好几个 dns 服务,对指定了 client ip 的 dns 缓存都有问题
    marquina
        8
    marquina  
    OP
       2020-03-09 17:13:36 +08:00
    @mwylaoma 现在可以直接下载二进制包了~如果不是经常重启的话不用 redis 也没关系
    mwylaoma
        9
    mwylaoma  
       2020-03-09 17:15:02 +08:00
    @marquina #8 好的,谢谢,建议把配置说明详细注释下,哈哈
    marquina
        10
    marquina  
    OP
       2020-03-09 17:28:31 +08:00
    @sujin190 不好意思,这个暂不支持😅
    wysnylc
        11
    wysnylc  
       2020-03-09 17:31:14 +08:00
    @marquina #5 如果你说的响应一个 IP 是指最终访问的 IP,那么是的因为这个 ip 是可访问并且最快的
    类似原理的有 SmartDNS DnsChooser(这个我在用),通过并发请求多个 DNS 来获取可用且最快的 IP
    可以解决部分 dns 污染且不会触犯任何"规定",因为本质上只是买票买了多张票选一个最快的其他的退票而已
    xenme
        12
    xenme  
       2020-03-09 17:38:54 +08:00   ❤️ 1
    chinadns-ng
    freedns-go

    目前再用 chinadns-ng,还没发现 DNS 还有其他更好的玩儿法。
    测速真没啥必要,国内不污染,没有太大的区别

    要是支持 ipset 联动的话,可能和去广告,分流等结合,项目前景更大点。虽然 dnsmasq 可以。
    marquina
        13
    marquina  
    OP
       2020-03-09 17:45:08 +08:00
    @mwylaoma 在配置文件里注释了一通,已提交至 github
    marquina
        14
    marquina  
    OP
       2020-03-09 17:51:18 +08:00
    @sujin190 12 楼提到了 chinadns-ng,这个项目的 github 主页写着支持 edns,你可以去看看~
    wzw
        15
    wzw  
       2020-03-09 18:07:05 +08:00 via iPhone
    今晚试试,支持
    marquina
        16
    marquina  
    OP
       2020-03-09 18:08:32 +08:00
    @xenme 人嘛,总要有点成就感才算活着,哪怕是虚假的成就感。
    xenme
        17
    xenme  
       2020-03-09 18:16:55 +08:00   ❤️ 1
    @marquina

    目前来看,chinadns-ng 的抗污染逻辑还是比较合理的。
    缺的几个功能:
    1. 没法支持类似 dnsmasq 针对特定域名指定 dns 的需求,只有国内和国外,没有比如局域网等特定域名,不过可以套 dnsmasq 解决
    2. 没法修改 ipset,也可以套 dnsmasq
    3. 没有 cache,也可以套 dnsmasq

    目前 dnsmasq 套 chinadns-ng 基本完美了。

    主要是没看到一些亮眼的或者独到的点,不过还是支持下
    miaomiao888
        18
    miaomiao888  
       2020-03-09 18:29:16 +08:00   ❤️ 1
    基于列表的还是麻烦,像 smartdns 那种就不错,真正做到开箱既用,不仅能加速还解决污染问题,只可惜它没有 win 版
    mwylaoma
        19
    mwylaoma  
       2020-03-09 18:30:18 +08:00
    @marquina #13
    sujin190
        20
    sujin190  
       2020-03-09 19:57:01 +08:00
    @marquina #14 之前测试过 freedns、smartdns、unbound,似乎转发请求时可以的,但是缓存管理都有问题,首次请求之后,我换个 ip 再请求还是刚才的,unbound 支持好一点,如果首次时带 ip 请求,缓存管理似乎就正常了,如果不是那么后面无论带啥 ip 请求都是第一次的结果,坑死。。
    marquina
        21
    marquina  
    OP
       2020-03-10 01:56:52 +08:00 via Android
    @miaomiao888 可以配置一个 suffix 为.的 group,匹配所有域名,然后再基于这个 group 实现和 smartdns 类似的 dns 并发+测速,哈哈
    kios
        22
    kios  
       2020-03-10 08:17:38 +08:00
    mark。正好也学习一下,哈哈
    suspended
        23
    suspended  
       2020-03-10 10:33:49 +08:00
    啊哈,既然派生自我的算法,还希望在 repo 里 credit 一下我的 repo 呢。^_^
    marquina
        24
    marquina  
    OP
       2020-03-10 10:35:54 +08:00
    @miaomiao888 看了一下,smartdns 解决污染问题的手段是设置 ip 黑名单和 ip 白名单……感觉有点绕了
    marquina
        25
    marquina  
    OP
       2020-03-10 11:10:59 +08:00
    @suspended 已更新 readme ~
    suspended
        26
    suspended  
       2020-03-10 11:18:05 +08:00
    @marquina 谢谢
    nogoodren
        27
    nogoodren  
       2020-03-10 11:50:00 +08:00
    本地系统的 dns 需要修改为 127.0.0.1 吗
    marquina
        28
    marquina  
    OP
       2020-03-10 12:45:11 +08:00
    @nogoodren 你的意思是让本机的 dns 请求由 ts-dns 负责解析?
    qsnow6
        29
    qsnow6  
       2020-03-10 13:13:34 +08:00
    @marquina #28 是的
    marquina
        30
    marquina  
    OP
       2020-03-10 13:46:11 +08:00
    @nogoodren @qsnow6 #27 那就需要设置
    nogoodren
        31
    nogoodren  
       2020-03-10 21:02:42 +08:00
    groups 参数里面,是不是不同的域名,使用不同的 dns 解析?
    marquina
        32
    marquina  
    OP
       2020-03-10 23:26:32 +08:00
    @nogoodren 对。核心思想是将域名划分为不同的 group,每个 group 可以独立指定上游 dns、匹配规则、代理、ipset。
    虽然一个 group 可以指定多个上游 dns,但目前还只是顺序请求,一般只会用到第一个 dns。
    marquina
        33
    marquina  
    OP
       2020-03-11 14:34:49 +08:00
    v0.2.0 发布,欢迎大家尝试、交流~
    marquina
        34
    marquina  
    OP
       2020-03-11 18:06:13 +08:00
    @sujin190 #20 测试了一下,可以做 edns client subnet 缓存的支持,预计会在 v0.3.0 添加该功能。不过我本身对 edns 不太熟,就算支持也只会是对 client subnet 特殊照顾~
    marquina
        35
    marquina  
    OP
       2020-03-11 18:42:25 +08:00
    @sujin190 我用 socks5 代理搭配 8.8.8.8 测试 EDNS Client-Subnet 通过,代码推到 github 上了,你也可以先自行编译。现在的缓存策略是 address 和 mask 有任何变动就重新请求。
    wzw
        36
    wzw  
       2020-03-12 09:00:14 +08:00   ❤️ 1
    @marquina #35 有些地方可以参考 https://github.com/shawn1m/overture 这个项目
    是否有考虑自动加一些 ***list_domain china_ip_list , 这样会更加 老少皆宜, 开箱即用
    marquina
        37
    marquina  
    OP
       2020-03-12 09:23:04 +08:00
    @wzw v0.2.0 的 release 包内添加了 gfwlist.txt 并强制开启 gfwlist 模式。不过目前还没有打算添加 china_ip_list 相关的功能~
    wzw
        38
    wzw  
       2020-03-12 09:31:12 +08:00
    @marquina #37 好用, 谢谢了. (主要看上 hosts 了)
    marquina
        39
    marquina  
    OP
       2020-03-12 17:31:17 +08:00
    @sujin190 #20 v0.3.0 已发布,支持 EDNS Client-Subnet 缓存,可直接下载二进制包~

    @wzw #38 v0.3.0 已发布,取消自动重载 hosts 文件。上一个版本 v0.2.0 每隔 10 秒会自动重载 hosts 文件,会在一定程度上影响性能,后来想想还是取消了(哈哈
    wzw
        40
    wzw  
       2020-03-12 17:52:00 +08:00
    @marquina #39 和 clashx 一样, 可以 reload config 就行, 提供这样的命令吗?
    marquina
        41
    marquina  
    OP
       2020-03-12 17:59:37 +08:00
    @wzw 为啥不直接重启进程呢:-D
    wzw
        42
    wzw  
       2020-03-15 15:53:51 +08:00
    @marquina #41 Macos launchd 难用... 还想问问你计划弄到 brew 不?

    v0.4.0 已发布
    * 增加支持 DNS over TCP/TLS/HTTPS

    丰富的差不多了,,, 可以用了
    marquina
        43
    marquina  
    OP
       2020-03-15 16:21:56 +08:00
    @wzw 刚发布了 v0.6.0,支持配置文件自动重载,在 64bit win/linux 上测试通过,mac 上应该也可以用。brew 之类的发布渠道目前没有支持的计划。
    ety001
        44
    ety001  
       2020-03-15 16:24:04 +08:00
    要不要考虑支持 namebase ?
    marquina
        45
    marquina  
    OP
       2020-03-15 16:27:34 +08:00
    @ety001 namebase 是什么东东……我看 wiki 上的说明好像和 dns 没啥关系
    nogoodren
        46
    nogoodren  
       2020-03-15 21:11:51 +08:00
    多 hosts 文件,应该如何设置
    marquina
        47
    marquina  
    OP
       2020-03-16 00:58:25 +08:00
    @nogoodren 在 toml 配置文件里添加相应记录,格式为:hosts_files = ["hosts1.txt", "hosts2.txt"]
    nogoodren
        48
    nogoodren  
       2020-03-16 11:44:00 +08:00
    ts-dns.full.toml 和 ts-dns.toml 两个配置文件,程序默认使用那一个啊?
    marquina
        49
    marquina  
    OP
       2020-03-16 12:34:05 +08:00
    @nogoodren 默认使用 ts-dns.toml,在 readme 里、执行./ts-dns -h 时都可以看到。
    nogoodren
        50
    nogoodren  
       2020-03-16 17:35:57 +08:00
    [groups.dirty]里面有 socks5、dot、doh 等几种方式,那么默认使用哪一个?还是一个不行换另外一个?
    ety001
        51
    ety001  
       2020-03-16 18:25:49 +08:00
    marquina
        52
    marquina  
    OP
       2020-03-16 20:16:13 +08:00
    @nogoodren #50 优先级分别为 dns、dot、doh,每次请求时会依次请求(故障转移) dns 列表。socks5 是代理请求 dns,和优先级无关。
    nogoodren
        53
    nogoodren  
       2020-03-16 20:18:06 +08:00
    @marquina 谢谢你的耐心解答
    nogoodren
        54
    nogoodren  
       2020-03-17 11:44:41 +08:00
    请问“DNS 查询支持 socks5 代理”这个功能怎么实现,我通过火狐浏览器的 socks5 代理测试失败。
    marquina
        55
    marquina  
    OP
       2020-03-17 13:06:00 +08:00
    @ety001 区块链 ptsd……这种战未来的项目还是观望观望
    marquina
        56
    marquina  
    OP
       2020-03-17 13:10:25 +08:00
    @nogoodren 我不知道火狐浏览器的测试是什么情况……ts-dns 在国内直接向 8.8.8.8 解析 google.com ,大概率会因为 dns 污染而得到错误结果,这时就可以找一个“干净”的 socks5 代理(比如本地运行的 fq 软件),让 ts-dns 通过这个 socks5 代理向 8.8.8.8 解析 google.com 来避免污染。
    marquina
        57
    marquina  
    OP
       2020-03-18 15:46:43 +08:00
    v0.7.0 发布~支持并发请求上游 DNS
    wzw
        58
    wzw  
       2020-03-31 07:27:35 +08:00
    @marquina #57 v0.9.0 大大的点赞, 很实用.
    marquina
        59
    marquina  
    OP
       2020-03-31 09:35:27 +08:00
    @wzw 参考 smartdns 的功能做的,听说对移动之类的宽带友好,但我用的是联通所以没啥感觉 xD
    wzw
        60
    wzw  
       2020-03-31 09:38:14 +08:00
    @marquina #59

    环境: MacOS 10.14.6
    错误: create ipset error: Ipset utility not found

    我也遇到这个问题
    marquina
        61
    marquina  
    OP
       2020-03-31 09:50:07 +08:00
    @wzw 某个 group 配置了 ipset,但系统里没有 ipset 命令,所以报错。这个功能还是比较小众的,不需要的可以注释掉相关配置
    derekwei
        62
    derekwei  
       2020-03-31 10:59:17 +08:00
    不知 Ping 是 ICMP 还是 TCP 的?
    marquina
        63
    marquina  
    OP
       2020-03-31 11:07:44 +08:00
    @derekwei 基于 ICMP
    derekwei
        64
    derekwei  
       2020-03-31 15:55:52 +08:00
    @marquina 有的服务器屏蔽了 ICMP,是否考虑加入用户自主选择 ICMP/TCP 的选项
    marquina
        65
    marquina  
    OP
       2020-03-31 16:34:38 +08:00
    @derekwei 后续会考虑添加,不过优先级不高
    marquina
        66
    marquina  
    OP
       2020-04-05 18:09:39 +08:00   ❤️ 1
    @derekwei v0.10.0 发布,支持用 tcp ping 对 ipv4 进行测速,还修复了之前的测速 bug 。
    marquina
        67
    marquina  
    OP
       2020-05-09 21:24:12 +08:00
    v0.11.0:支持默认附带 ECS 信息转发 DNS 请求;可选是否以 base64 解码 gfwlist ;支持 debug 模式。
    v0.12.0:支持从文件中读取 group 的匹配规则(#10);支持通配符 hosts(#8);修复 gfwlist 文件换行符 bug(#11)。
    v0.13.0:支持监听监听 TCP 端口 (#18);提升 ABPlus 规则兼容性 (||ads.example.com^)。
    v0.13.1:修复自 v0.11.0 以来的默认添加 ecs 相关 bug (#20);默认同时监听 TCP/UDP 端口 (#19)。
    Bunnyranch
        68
    Bunnyranch  
       2020-05-29 09:38:23 +08:00
    “ prefetch-domain ”域名预先获取功能 和“ serve-expired”过期缓存服务功能 有这两个应该就很完善了。
    那样我就不用 win10 装 WSL 跑 smartdns 了。。
    marquina
        69
    marquina  
    OP
       2020-05-29 17:36:31 +08:00
    @Bunnyranch prefetch-domain 功能挺好,serve-expired 就有待商榷了……chrome 和 firefox 都不关心 DNS 记录的 ttl,当 chrome 得到一个 ttl 为 0 的查询结果(已过期+开启 serve-expired ),chrome 还是会将这个结果缓存 1 分钟。
    Bunnyranch
        70
    Bunnyranch  
       2020-05-30 09:37:07 +08:00
    @marquina 而且 serve-expired 设置不当,有时候地址变的快的网页不能正常浏览。
    另外我说一点 ts-dns 试用的感觉,真没 smartDNS 丝滑。。 我打开网页前还是会顿一下,看着 chrome 左下角显示“正在解析主机”,时间长的时候能等一秒才开始加载网页,反复打开同一个网页好像就没这现象了,但是重启了电脑又来。(我打开了并发查询和 TCP 测速,以及缓存等基本功能)
    这个是因为没 prefetch 功能的原因么,之前使用 smartDNS 没这种体验。。 不过我的 WSL ubuntu 升级 20.04 之后有问题。。就索性都卸载了来用的 ts-dns...
    marquina
        71
    marquina  
    OP
       2020-05-30 19:01:47 +08:00
    @Bunnyranch 在启用响应 ip 测速( icmp 或 tcp )时,ts-dns 会等待所有上游 dns 的响应(或超时)。只要有一个上游 dns 的延迟很大(或者丢包超时),就会影响解析速度。我觉得如果不是硬性需求,ip 测速功能还是没有必要开启。
    比如我的北方联通家宽向 114.114.114.114 解析 baidu.com ,得到的两个 ip 的 ping 值均小于 10ms,测速只会拖慢解析速度( 10ms->100ms )。
    Bunnyranch
        72
    Bunnyranch  
       2020-05-31 11:01:27 +08:00
    @marquina 一些网站不在 dirty 组里面的,于是乎我只能在 clean 组里加上干净但是很慢的服务器,然后开并发和测速,应该是这个原因导致变慢。 不过。。还是用 smartDNS 的时候这样配置 解析速度也很快,反馈是为了让软件变得更棒,加油!
    marquina
        73
    marquina  
    OP
       2020-06-01 19:12:54 +08:00
    @Bunnyranch 不在 dirty 组……为啥不写 rules 呢?
    Bunnyranch
        74
    Bunnyranch  
       2020-06-02 09:13:55 +08:00
    @marquina 因为我笨笨。。。 而且我怕我一直说 smartDNS 好你会生气气
    另外我想过学学怎么写 rules,但比如搜索了某个关键词,点进去的网站,其实是随机的。只是写入特定规则,有时候还是会碰到被污染的情况(虽然这种情况比较少)。 从体验上来说,clean 组也配上一个干净的服务器,这样碰到打不开的网站,也不用怀疑到底是被污染了 还是不在规则内,比较万无一失(只不过这样 ts-dns 会慢一点)。。
    marquina
        75
    marquina  
    OP
       2020-06-02 09:26:04 +08:00
    @Bunnyranch 默认的 gfwlist+cnip 匹配模式已经足以应付绝大多数情况了,除非是特别冷门的网站……就目前的 ts-dns 处理逻辑来说,将干净的 dns 服务器加到 clean 组只会极大拉低使用体验。rules 配置的话,可以看看我在 ts-dns-full.toml 里写的简单说明,也可以看看 adblock plus 的过滤规则,觉得有兼容性问题也可以提 issue 。
    https://github.com/wolf-joe/ts-dns/blob/master/ts-dns-full.toml#L33
    https://adblockplus.org/filter-cheatsheet
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5230 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 55ms · UTC 07:08 · PVG 15:08 · LAX 00:08 · JFK 03:08
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.