V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
lbp0200
V2EX  ›  DNS

基于 4 个 8 撸了一个 CDN 友好的 DNS

  •  
  •   lbp0200 · 2017-01-24 18:32:41 +08:00 · 14913 次点击
    这是一个创建于 2861 天前的主题,其中的信息可能已经有所发展或是发生改变。

    https://github.com/lbp0200/PRCDNS

    1. 只支持 TCP ,防止二级运营商搞事
    2. CDN 友好, img.alicdn.com 返回大陆地址

    拿 opendns 做测试对比

    dig @23.106.151.177 +tcp -p 3535 google.com.hk #PRCDNS
    dig @208.67.222.222 +tcp -p 443 google.com.hk #opendns
    
    dig @23.106.151.177 +tcp -p 3535 img.alicdn.com #PRCDNS
    dig @208.67.222.222 +tcp -p 443 img.alicdn.com #opendns
    

    测试 IP 仅供测试, DDoS 留情

    75 条回复    2018-02-26 18:01:20 +08:00
    firefox12
        1
    firefox12  
       2017-01-25 00:21:45 +08:00 via iPhone
    cdn 友好的原理是什么?比如一个北京 ip 访问解析一个 www.sina.com 如何知道改返回一个国内 ip 给它?还是回一个北美 ip
    lbp0200
        2
    lbp0200  
    OP
       2017-01-25 08:30:18 +08:00 via Android
    @firefox12 IP 交给 Google , Google 就给了正确答案,我也不知道 Google 如何做到的。
    wql
        3
    wql  
       2017-01-25 12:23:53 +08:00 via Android
    @lbp0200 edns subnet
    估计是在全球各地的 Google 服务器上面查找本地 dns 得来的
    lbp0200
        4
    lbp0200  
    OP
       2017-01-25 12:50:25 +08:00 via Android
    @wql 应该是
    hzw
        5
    hzw  
       2017-01-25 16:22:29 +08:00 via iPhone
    家里用一个老的笔电跑了 ubuntu ,现在开的 dnsmasq ,楼主这个可以么?或者换成 pdnsd 后装楼主这个?
    lbp0200
        6
    lbp0200  
    OP
       2017-01-25 17:48:35 +08:00
    @hzw 用 pdnsd ,支持TCP上游查询, dnsmasq 貌似不行
    firefox12
        7
    firefox12  
       2017-01-25 23:54:39 +08:00 via iPhone
    原理上说不通啊,标准 dns request 里面并没有客户端的 ip 啊 所以你用标准的 dns 去请求 他返回的是这台转发 dns 请求服务器这个区域的对应 ip 我们知道这是不对的。
    lbp0200
        8
    lbp0200  
    OP
       2017-01-26 08:20:09 +08:00 via Android
    @firefox12 TCP 总会知道请求者的 IP 的,拿着请求者的 IP 提交给 Google 的 http 接口,就会得到正确的解析结果,将结果包装成标准的 dns 格式返回。
    q397064399
        9
    q397064399  
       2017-01-26 14:10:54 +08:00
    @lbp0200 #6
    pdnsd 好像无法设置上游查询的端口
    csvw
        10
    csvw  
       2017-01-26 14:12:53 +08:00
    @lbp0200 据我了解,只有域名支持 edns subnet 的, google 才可能给出正确的 ip ,而国内支持 edns subnet 的域名应该没有很多,所以大概率还是没法替代国内的 dns
    q397064399
        11
    q397064399  
       2017-01-26 14:14:35 +08:00
    dig @120.77.159.44 +tcp -p 5353 google.com.hk

    测试下,,没什么卵用 主要是不晓得 设置 pdnsd 把这个转成 udp 53
    tangzho
        12
    tangzho  
       2017-01-26 20:00:26 +08:00 via Android
    pdnsd 和 unbound 都可以非标和强制 tcp 上游,
    tangzho
        13
    tangzho  
       2017-01-26 20:05:12 +08:00 via Android
    dnsmasq 支持非标端口,支持 tcp 但不能强制 tcp
    bazingaterry
        14
    bazingaterry  
       2017-01-26 23:06:32 +08:00
    q0000x
        15
    q0000x  
       2017-01-27 01:02:39 +08:00
    @lbp0200 确实不错,可否协助部署?
    lbp0200
        16
    lbp0200  
    OP
       2017-01-27 14:02:18 +08:00 via Android
    @q0000x 可以
    q0000x
        17
    q0000x  
       2017-01-27 15:38:20 +08:00
    @lbp0200 有 QQ 或者微信么,我想把这个项目部署到 openwrt 上试试
    lbp0200
        18
    lbp0200  
    OP
       2017-01-27 18:44:36 +08:00
    q0000x
        20
    q0000x  
       2017-01-28 00:13:37 +08:00
    @lbp0200 我现在就是用 pdnsd+prcdns ,怕你哪天 ip 换了或者关了😄
    lbp0200
        21
    lbp0200  
    OP
       2017-01-28 10:00:58 +08:00
    @q0000x 一年内不会关, prcdns 需要 Python3.5 ,我也不清楚如何安装到 openwrt 上。文档我一点点写吧。
    lbp0200
        22
    lbp0200  
    OP
       2017-01-28 10:41:45 +08:00
    @q0000x 可以将 114 作为备用,
    server {
    label = "prcdns"; //设置 PRCDNS 作为上游服务器
    ip = 23.106.151.177;
    timeout = 10;
    port = 3535;
    }
    server {
    label = "114dns"; //备用 114DNS 作为上游服务器
    ip = 114.114.114.114,114.114.115.115;
    timeout = 10;
    port = 53;
    }
    q0000x
        23
    q0000x  
       2017-01-28 17:03:14 +08:00
    @lbp0200 我先试试把 py 撸到 openwrt 上,如果可以再联系继续
    q0000x
        24
    q0000x  
       2017-01-28 17:41:11 +08:00
    @lbp0200 py3.4 行不行?
    lbp0200
        25
    lbp0200  
    OP
       2017-01-28 21:22:50 +08:00
    @q0000x 不行
    q0000x
        26
    q0000x  
       2017-01-29 01:57:59 +08:00
    @lbp0200 3.6 不知道行不行,看到你 setup 里写了 3.6 路由上已经把 3.6 的 py 撸好运行后提示

    我是吧 setup.py 、 setup.config 下载到路由上执行

    root@OpenWrt:~# /tmp/setup.py
    /tmp/setup.py: line 2: A setuptools based setup module.
    : not found
    /tmp/setup.py: line 5: from: not found
    /tmp/setup.py: line 6: from: not found
    /tmp/setup.py: line 8: from: not found
    /tmp/setup.py: line 10: syntax error: unexpected "("
    lbp0200
        27
    lbp0200  
    OP
       2017-01-29 09:45:01 +08:00 via Android
    @q0000x 3.6 没问题,看错误信息,可能是因为缺少 pip
    q0000x
        28
    q0000x  
       2017-01-29 11:28:06 +08:00
    @lbp0200 python3-pip 已经安装过了, python3-setuptools 这个也有
    lbp0200
        29
    lbp0200  
    OP
       2017-01-29 16:38:31 +08:00
    @q0000x 我也不知道了,你可以尝试修改代码
    q0000x
        30
    q0000x  
       2017-01-29 21:53:54 +08:00
    @lbp0200 问题是我不会 py...
    q0000x
        31
    q0000x  
       2017-01-30 01:22:43 +08:00
    @lbp0200 能撸个 3.4 的吗,我这个 openwrt 上只有 3.4 的能正常运行, 3.6 那个估计是不兼容
    maojy1989
        32
    maojy1989  
       2017-02-07 12:01:03 +08:00
    遇到一个很尴尬的问题,我在 centos7 上安装 Python3.5.1 然后 pip install PRCDNS 当我用 yum 安装 Supervisor 的时候遇到问题了 Supervisor 启动不起来
    pkg_resources.DistributionNotFound: The 'supervisor==3.1.3' distribution was not found and is required by the application

    搜了很久也没找到怎么解决这个问题了,然后想试试用 pip install Supervisor 得到以下结果

    ollecting supervisor
    Downloading supervisor-3.3.1.tar.gz (415kB)
    100% |████████████████████████████████| 419kB 2.4MB/s
    Complete output from command python setup.py egg_info:
    Supervisor requires Python 2.4 or later but does not work on any version of Python 3. You are using version 3.5.1 (default, Feb 7 2017, 03:41:19)
    [GCC 4.8.5 20150623 (Red Hat 4.8.5-11)]. Please install using a supported version.

    ----------------------------------------
    Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-qadut3c0/supervisor/

    好像是 supervisor 不支持 python3 这就很尴尬了,怎么搞?
    maojy1989
        33
    maojy1989  
       2017-02-07 13:07:12 +08:00
    已经解决了,果然把默认 python 换成 3.5 不是个好主意 好多地方要把 #!/usr/bin/python 换成 #!/usr/bin/python2.7
    mike163
        34
    mike163  
       2017-02-09 13:56:17 +08:00
    不能支持 udp 吗?这样可以用 dnsmasq 直接访问了
    lbp0200
        35
    lbp0200  
    OP
       2017-02-09 14:43:52 +08:00
    @mike163 不支持
    q0000x
        36
    q0000x  
       2017-02-11 09:28:39 +08:00
    @lbp0200 话说我在你的博客上怎么找不到你的微信

    python3 PRCDNS
    python3: can't open file 'PRCDNS': [Errno 2] No such file or directory

    pip3 install PRCDNS
    Requirement already satisfied: PRCDNS in /opt/python-3.6.0/lib/python3.6/site-packages
    Requirement already satisfied: asyncio in /opt/python-3.6.0/lib/python3.6/site-packages (from PRCDNS)
    Requirement already satisfied: aiohttp in /opt/python-3.6.0/lib/python3.6/site-packages (from PRCDNS)
    Requirement already satisfied: aiodns in /opt/python-3.6.0/lib/python3.6/site-packages (from PRCDNS)
    Requirement already satisfied: cchardet in /opt/python-3.6.0/lib/python3.6/site-packages (from PRCDNS)
    Requirement already satisfied: dnslib in /opt/python-3.6.0/lib/python3.6/site-packages (from PRCDNS)
    Requirement already satisfied: argparse in /opt/python-3.6.0/lib/python3.6/site-packages (from PRCDNS)
    Requirement already satisfied: IPy in /opt/python-3.6.0/lib/python3.6/site-packages (from PRCDNS)
    Requirement already satisfied: chardet in /opt/python-3.6.0/lib/python3.6/site-packages (from aiohttp->PRCDNS)
    Requirement already satisfied: multidict>=2.1.4 in /opt/python-3.6.0/lib/python3.6/site-packages (from aiohttp->PRCDNS)
    Requirement already satisfied: async_timeout>=1.1.0 in /opt/python-3.6.0/lib/python3.6/site-packages (from aiohttp->PRCDNS)
    Requirement already satisfied: yarl>=0.8.1 in /opt/python-3.6.0/lib/python3.6/site-packages (from aiohttp->PRCDNS)
    Requirement already satisfied: pycares>=1.0.0 in /opt/python-3.6.0/lib/python3.6/site-packages (from aiodns->PRCDNS)

    直接 PRCDNS 的话就是一个光标一直在闪,不能进行任何操作了
    q0000x
        37
    q0000x  
       2017-02-11 09:29:40 +08:00
    @lbp0200 debian7 x64
    lbp0200
        38
    lbp0200  
    OP
       2017-02-11 11:18:50 +08:00 via Android
    @q0000x 对,这样程序就运行起来了,可以测试下,需要一直运行的话,搭配 supervisor
    q0000x
        39
    q0000x  
       2017-02-11 12:46:18 +08:00
    @lbp0200 晕,没有任何提示我还以为挂了,又重新安装环境坐等你回复呢
    q0000x
        40
    q0000x  
       2017-02-11 13:28:08 +08:00
    @lbp0200 通常情况下不关机重启不用 supervisor 也没关系吧?
    lbp0200
        41
    lbp0200  
    OP
       2017-02-11 17:16:42 +08:00 via Android
    @q0000x 也可以放到后台运行
    q0000x
        42
    q0000x  
       2017-02-11 19:45:35 +08:00
    @lbp0200 如何操作?
    q0000x
        43
    q0000x  
       2017-02-11 20:47:26 +08:00
    @lbp0200 搞定了
    matsuz
        44
    matsuz  
       2017-02-12 09:06:57 +08:00 via Android
    这个如果放在本地路由器上的话应该是没办法做到 CDN 友好的吧。

    Google Public DNS 是通过用户的 ip 来实现 cdn 友好的,如果部署在本地的话,你的 ip 是一个内网 ip , google 是没法对一个内网 ip 进行 cdn 优化的。

    我也写过一个这种程序,不过是用 Java 写的。依我之见,必须得找个 vps 部署到服务器上。
    lbp0200
        45
    lbp0200  
    OP
       2017-02-12 10:03:36 +08:00
    @matsuz 先通过 http://ipinfo.io/的接口拿到本地公网 ip ,然后把本地公网 IP 作为参数传给 Google 的 DNS 接口,所以部署在本地是可以的。
    matsuz
        46
    matsuz  
       2017-02-12 10:15:49 +08:00 via Android
    @lbp0200 如果是这样的话倒是可以
    q0000x
        47
    q0000x  
       2017-02-13 15:24:55 +08:00
    @lbp0200 默认是把访问 IP 当作参数给传递了吗?今天发现有些解析不对,会解到它网的 IP ,本网 DNS 解析正常
    lbp0200
        48
    lbp0200  
    OP
       2017-02-13 17:19:16 +08:00
    @q0000x https://dns.google.com/resolve?name=域名&edns_client_subnet=你的公网 ip/24
    访问 Google 的接口,直接看 Google 给的结果。
    我在使用中发现 china.com 的解析有问题,所以在 pdnsd 里,添加 114 做补充,不过无所谓了,我不看中华网。
    titanium98118
        49
    titanium98118  
       2017-02-14 13:20:52 +08:00
    在 PRCDNS 可以手动指定一个 EDNS IP 吗?
    lbp0200
        50
    lbp0200  
    OP
       2017-02-15 13:09:52 +08:00 via Android
    没有这个功能
    lbp0200
        51
    lbp0200  
    OP
       2017-02-15 13:10:11 +08:00 via Android
    @titanium98118 没有这个功能
    HalloCQ
        52
    HalloCQ  
       2017-02-17 18:01:11 +08:00
    [root@localhost ~]# python PRCDNS
    python: can't open file 'PRCDNS': [Errno 2] No such file or directory
    怎么回事啊?
    q0000x
        53
    q0000x  
       2017-02-18 12:33:22 +08:00 via iPhone
    @HalloCQ 直接 PRCDNS &就可以了
    HalloCQ
        54
    HalloCQ  
       2017-02-18 22:27:54 +08:00
    [root@localhost ~]# PRCDNS &
    [1] 15402
    [root@localhost ~]# -bash: PRCDNS: command not found

    [1]+ Exit 127 PRCDNS
    [root@localhost ~]# PRCDNS
    -bash: PRCDNS: command not found

    @q0000x
    HalloCQ
        55
    HalloCQ  
       2017-02-18 22:29:32 +08:00
    @q0000x
    [root@localhost ~]# pip install PRCDNS
    Requirement already satisfied: PRCDNS in /usr/local/python3/lib/python3.5/site-packages
    Requirement already satisfied: asyncio in /usr/local/python3/lib/python3.5/site-packages (from PRCDNS)
    Requirement already satisfied: aiohttp in /usr/local/python3/lib/python3.5/site-packages (from PRCDNS)
    Requirement already satisfied: aiodns in /usr/local/python3/lib/python3.5/site-packages (from PRCDNS)
    Requirement already satisfied: cchardet in /usr/local/python3/lib/python3.5/site-packages (from PRCDNS)
    Requirement already satisfied: dnslib in /usr/local/python3/lib/python3.5/site-packages (from PRCDNS)
    Requirement already satisfied: argparse in /usr/local/python3/lib/python3.5/site-packages (from PRCDNS)
    Requirement already satisfied: IPy in /usr/local/python3/lib/python3.5/site-packages (from PRCDNS)
    Requirement already satisfied: yarl<0.10,>=0.9.8 in /usr/local/python3/lib/python3.5/site-packages (from aiohttp->PRCDNS)
    Requirement already satisfied: multidict>=2.1.4 in /usr/local/python3/lib/python3.5/site-packages (from aiohttp->PRCDNS)
    Requirement already satisfied: async-timeout>=1.1.0 in /usr/local/python3/lib/python3.5/site-packages (from aiohttp->PRCDNS)
    Requirement already satisfied: chardet in /usr/local/python3/lib/python3.5/site-packages (from aiohttp->PRCDNS)
    Requirement already satisfied: pycares>=1.0.0 in /usr/local/python3/lib/python3.5/site-packages (from aiodns->PRCDNS)
    [root@localhost ~]# PRCDNS
    -bash: PRCDNS: command not found
    q0000x
        56
    q0000x  
       2017-02-19 00:01:59 +08:00
    @HalloCQ 系统默认的 python 是 2.7 的,你要给换成 3.5 以上的版本
    q0000x
        57
    q0000x  
       2017-02-19 00:03:28 +08:00
    @lbp0200 突然发现一个问题, fast.com 测速的时候会报错,你开着 vps 然后上 fast.com 试试看
    HalloCQ
        58
    HalloCQ  
       2017-02-19 08:28:17 +08:00
    可以了
    lbp0200
        59
    lbp0200  
    OP
       2017-02-20 14:25:30 +08:00
    @q0000x 结果看起来貌似是对的

    dig @23.106.151.177 +tcp -p 3535 fast.com

    ; <<>> DiG 9.10.3-P4-Ubuntu <<>> @23.106.151.177 +tcp -p 3535 fast.com
    ; (1 server found)
    ;; global options: +cmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 50980
    ;; flags: qr aa rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

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

    ;; ANSWER SECTION:
    fast.com. 19 IN A 23.48.253.70

    ;; Query time: 398 msec
    ;; SERVER: 23.106.151.177#3535(23.106.151.177)
    ;; WHEN: Mon Feb 20 14:24:47 CST 2017
    ;; MSG SIZE rcvd: 42
    HalloCQ
        60
    HalloCQ  
       2017-02-23 23:09:41 +08:00
    @lbp0200 centos 怎么安装 polipo 啊?
    lbp0200
        61
    lbp0200  
    OP
       2017-02-23 23:22:12 +08:00 via Android
    @HalloCQ yum install polipo
    q0000x
        62
    q0000x  
       2017-02-24 00:25:13 +08:00
    lbp0200
        63
    lbp0200  
    OP
       2017-02-24 09:34:30 +08:00
    @q0000x 我试了一下,一会儿有结果,一会儿没有,估计是 pplive.cn 的权威 DNS 服务器不稳定或者 Google 到它权威 DNS 服务器的网络不稳定。
    对于国内的域名偶尔会发现问题,我建议用 114 做备用上游服务器。
    HalloCQ
        64
    HalloCQ  
       2017-02-24 11:09:25 +08:00
    @lbp0200 yum install polipo
    HalloCQ
        65
    HalloCQ  
       2017-02-24 11:10:18 +08:00
    @lbp0200 这个代码在我的 centos 上好像是找不到包,不知道是不是源的问题
    HalloCQ
        66
    HalloCQ  
       2017-02-24 11:12:38 +08:00
    @lbp0200
    Loaded plugins: fastestmirror
    base | 3.6 kB 00:00
    extras | 3.4 kB 00:00
    updates | 3.4 kB 00:00
    extras/7/x86_64/primary_db | 122 kB 00:00
    Loading mirror speeds from cached hostfile
    * base: mirror.supremebytes.com
    * extras: mirror.supremebytes.com
    * updates: mirror.supremebytes.com
    No package polipo available.
    Error: Nothing to do
    q0000x
        67
    q0000x  
       2017-02-24 14:49:04 +08:00
    @lbp0200 应该是 pdnsd 上 edns 那个参数的影响,我把那个 OFF 掉还算正常,不能用 114 做备用,会被抢答掉
    q0000x
        68
    q0000x  
       2017-02-24 14:49:33 +08:00
    @lbp0200 除非用 chinadns 来配合
    lbp0200
        69
    lbp0200  
    OP
       2017-02-24 17:48:18 +08:00
    @q0000x
    Pdnsd 的配置里面加上个参数, 114 就不会抢答了
    global {
    par_queries=1; 一定要加,否则会同时查询 114 , 114 会抢答查询结果
    }
    lbp0200
        70
    lbp0200  
    OP
       2017-02-24 18:17:51 +08:00
    @q0000x 另,我更新的代码,不能查到正确的结果,直接关闭连接,交给其他 DNS 查询。
    HalloCQ
        71
    HalloCQ  
       2017-02-24 21:14:45 +08:00
    我把 s-s 和 prcdns 部署到同一台服务器上,然后在路由器开启 s-s 和 pdnsd
    如果 ss 和 pdnsd 都是用我服务器的 ip 的话就不能用,非要一个不是我服务器 ip 才行
    这是怎么回事?
    HalloCQ
        72
    HalloCQ  
       2017-02-24 21:22:19 +08:00
    不对,发现问题了。是开 gfw 模式才这样, ip 模式可以用
    q0000x
        73
    q0000x  
       2017-02-25 00:33:41 +08:00
    @lbp0200 也对,忘记了 pdnsd 的那个参数
    q0000x
        74
    q0000x  
       2018-02-26 16:27:13 +08:00   ❤️ 1
    @lbp0200 proxy_client.py 代码要更新了
    async def fetch(session, url, proxy=None):
    with aiohttp.Timeout(10):

    aiohttp.Timeout(10):这个在某些版本比较新的 centos 和 debian 上不被支持,要 import async_timeout 使用 async_timeout.timeout(10):代替

    详情参考: https://pypi.python.org/pypi/aiohttp
    lbp0200
        75
    lbp0200  
    OP
       2018-02-26 18:01:20 +08:00
    @q0000x 最近心思不在写代码上,你 fork 或者 push 吧
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5576 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 07:59 · PVG 15:59 · LAX 23:59 · JFK 02:59
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.