V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
这是一个专门讨论 idea 的地方。

每个人的时间,资源是有限的,有的时候你或许能够想到很多 idea,但是由于现实的限制,却并不是所有的 idea 都能够成为现实。

那这个时候,不妨可以把那些 idea 分享出来,启发别人。
heiher
V2EX  ›  奇思妙想

DNS 污染防御:转发 DNS 查询为 TCP 传输

  •  
  •   heiher · 2014-10-09 08:58:27 +08:00 · 17461 次点击
    这是一个创建于 3486 天前的主题,其中的信息可能已经有所发展或是发生改变。
    转发 UDP 协议的 DNS 查询至 TCP 协议传输,目前可以有效的抵御某些组织的 DNS 污染,此方案用于 Linux 平台。

    下载、编译 DNS Forwarder
    git clone git://github.com/heiher/hev-dns-forwarder
    cd hev-dns-forwarder
    make

    运行 DNS Forwarder
    bin/hev-dns-forwarder 0.0.0.0 5300 8.8.8.8
    # 0.0.0.0 : 本地监听地址
    # 5300 : 本地监听端口
    # 8.8.8.8 : 上游 DNS 服务器

    本地全局启用
    用于本地主机,透明转发所有的本机 DNS 查询
    sudo iptables -t nat -A OUTPUT -m udp -p udp --dport 53 -j REDIRECT --to-port 5300
    或直接设置本地的 DNS 服务器为 127.0.0.1,并将 Forwarder 的本地监听端口修改为 53。

    网关全局启用
    用于网关服务器,透明转发所有网关服务的主机的 DNS 查询
    sudo iptables -t nat -A PREROUTING -m udp -p udp --dport 53 -j REDIRECT --to-port 5300
    第 1 条附言  ·  2014-10-09 11:13:23 +08:00
    己证实转为 TCP 传输不是完全没问题的,对于特定域名的查询,GFW会 reset tcp connection。

    这个转发器原本是打算用于经过 Socks5 代理(仅实现 CONNECT)的,在测试中通过 8.8.8.8 查询 twitter.com 可以得到正确的解析,我就误认为不会被污染。
    17 条回复    2017-09-12 15:35:12 +08:00
    austinchou0126
        1
    austinchou0126  
       2014-10-09 09:18:53 +08:00
    too old
    顺便说下现在墙照样可以污染DNS的TCP请求了
    ➜ ~ dig +tcp facebook.com @114.114.114.114

    ; <<>> DiG 9.8.3-P1 <<>> +tcp facebook.com @114.114.114.114
    ;; global options: +cmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64163
    ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

    ;; QUESTION SECTION:
    ;facebook.com. IN A

    ;; ANSWER SECTION:
    facebook.com. 28883 IN A 59.24.3.173

    ;; Query time: 59 msec
    ;; SERVER: 114.114.114.114#53(114.114.114.114)
    ;; WHEN: Thu Oct 9 09:18:37 2014
    ;; MSG SIZE rcvd: 46
    heiher
        2
    heiher  
    OP
       2014-10-09 09:24:57 +08:00
    @austinchou0126 污染不是发生在你发起的这次查询上,而是 114.114.114.114 向上游查询的时候被污染的,所以请使用国外的 DNS 服务器试试。
    austinchou0126
        3
    austinchou0126  
       2014-10-09 09:30:36 +08:00   ❤️ 1
    sdysj
        4
    sdysj  
       2014-10-09 09:34:49 +08:00
    你奥特了,现在都用 chinadns 了。
    zix
        5
    zix  
       2014-10-09 09:35:20 +08:00
    Building src/hev-dns-forwarder.c ... In file included from src/hev-dns-forwarder.c:20:0:
    src/hev-dns-forwarder.h:13:21: 致命错误: hev-lib.h:没有那个文件或目录
    编译中断。
    make: *** [build/hev-dns-forwarder.o] 错误 1

    好像是依赖你另一个repo(hev-lib)里的东西吧……是不是该写个readme说明一下。
    itsjoke
        6
    itsjoke  
       2014-10-09 09:42:23 +08:00
    分地区的吧,四川电信实测用TCP查询未被污染
    heiher
        7
    heiher  
    OP
       2014-10-09 09:44:09 +08:00
    @austinchou0126 还真是不行了,不过这个转发器我是打算用来过 Socks5 代理的,只是测试的时候发现 TCP 查询竟然还能用用。
    heiher
        8
    heiher  
    OP
       2014-10-09 09:44:41 +08:00
    @zix 忘记了,等发现的时候已经不能编辑了。。。;)
    fghzpqm
        9
    fghzpqm  
       2014-10-09 09:49:04 +08:00
    很久以前我也用 golang 写过一个。

    https://gist.github.com/mrluanma/3722792

    安装:

    go get gist.github.com/37227.git

    使用:

    ```
    $ go-dnsproxy -h
    Usage of go-dnsproxy:
    -local=":53": local listen address
    -quiet=false: suppress output
    -remote="8.8.4.4:53": remote dns address
    ```
    chijiao
        10
    chijiao  
       2014-10-09 09:54:54 +08:00
    自己搭建一个DNS在国外,开放非53 UDP.然后在本地用dnsmasq 转发一下即可.不用TCP这么麻烦
    zhujinliang
        11
    zhujinliang  
       2014-10-09 10:38:36 +08:00
    尝试 clone hev-lib,及 make hev-lib,仍然出现错误:

    Linking build/hev-dns-forwarder.o build/hev-dns-session.o build/hev-main.o to bin/hev-dns-forwarder ... ../hev-lib/bin/libhev-lib.so: undefined reference to `clock_gettime'
    collect2: ld returned 1 exit status
    heiher
        12
    heiher  
    OP
       2014-10-09 11:03:10 +08:00   ❤️ 1
    @zhujinliang cd hev-lib; make static, 对于 clock_gettime 问题,对于某些平台需要修改一下 hev-dns-forwarder 的 makefile 中的 ldflags, 增加个 -lrt。
    yyysuo
        13
    yyysuo  
       2014-10-09 11:19:21 +08:00
    用了半年了,感觉不错。当然IP被封也没有用,就是缩小一下网络的延迟。
    treo
        14
    treo  
       2014-10-09 11:25:57 +08:00
    这属于一两年前的思路了,有了chinadns,这些都可以undeploy了
    zhujinliang
        15
    zhujinliang  
       2014-10-09 11:26:10 +08:00
    @heiher 编译成功了

    我是 linux amd64 平台
    1. git clone hev-dns-forwarder 及 hev-lib ,将两个项目放在同一目录下
    2. 进入 hev-lib, make static
    3. 进入 hev-dns-forwarder ,修改Makefile ,在 LDFLAGS 一行最后面加上 -lrt
    4. make,应该就没有错误了,之后就可以在bin目录下找到了

    可以配合 shadowsocks 用,我买的服务不支持 udp 转发,这样搞成 tcp 就可以走 shadowsocks 了
    heiher
        16
    heiher  
    OP
       2014-10-09 11:30:33 +08:00
    @zhujinliang 你的思路和我的一样的,只不过我不用 ShadowSocks,我有自己的 Socks5 兼容的代理(是混淆流量传输的),刚实现了一个 tproxy 用于配合 Iptables 做全局代理,这个 dns forwarder 就是将 DNS 查询过代理的。

    hev-socks5-tproxy (https://github.com/heiher/hev-socks5-tproxy),这是个 Socks5 协议兼容的客户端,配合 Linux iptables 的 REDIRECT target 使用。
    heiher
        17
    heiher  
    OP
       2017-09-12 15:35:12 +08:00
    先将 UDP 的 DNS 查询转成 TCP 再命中透明代理封装成 socks5 太周折了,现在在 hev-socks5-tproxy 中直接实现了 UDP DNS 服务,扩展了 socks5 的命令,所以只能配合 hev-socks5-server 使用。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1012 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 22:06 · PVG 06:06 · LAX 15:06 · JFK 18:06
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.