├── dnsmasq-update-china-list ├── ns-blacklist.txt ├── LICENSE ├── cdn-testlist.txt ├── removed-cdn.txt ├── ns-whitelist.txt ├── install.sh ├── find_redundant.py ├── updater.py ├── google.china.conf ├── Makefile ├── README.md ├── apple.china.conf ├── bogus-nxdomain.china.conf └── verify.py /dnsmasq-update-china-list: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | case "$1" in 4 | 114) 5 | DNS=114.114.114.114 6 | ;; 7 | ali) 8 | DNS=223.5.5.5 9 | ;; 10 | baidu) 11 | DNS=180.76.76.76 12 | ;; 13 | cnnic) 14 | DNS=1.2.4.8 15 | ;; 16 | dnspod) 17 | DNS=119.29.29.29 18 | ;; 19 | google) 20 | DNS=8.8.8.8 21 | ;; 22 | *) 23 | DNS=$1 24 | esac 25 | 26 | sed -i "s|^\(server.*\)/[^/]*$|\1/$DNS|" /etc/dnsmasq.d/accelerated-domains.china.conf 27 | sed -i "s|^\(server.*\)/[^/]*$|\1/$DNS|" /etc/dnsmasq.d/google.china.conf 2>/dev/null 28 | sed -i "s|^\(server.*\)/[^/]*$|\1/$DNS|" /etc/dnsmasq.d/apple.china.conf 2>/dev/null 29 | -------------------------------------------------------------------------------- /ns-blacklist.txt: -------------------------------------------------------------------------------- 1 | status: NXDOMAIN 2 | .ns.cloudflare.com. 3 | .google.com. 4 | .akam.net. 5 | .domaincontrol.com. 6 | .dreamhost.com. 7 | .wordpress.com. 8 | .dynect.net. 9 | .linode.com. 10 | .dnsmadeeasy.com. 11 | .stabletransit.com. 12 | .qwest.net. 13 | .registrar-servers.com. 14 | .dnsimple.com. 15 | .namebrightdns.com. 16 | .he.net. 17 | .googledomains.com. 18 | .msft.net. 19 | .akadns.org. 20 | .apple.com. 21 | .msedge.net. 22 | .amazonaws.com. 23 | .easydns.org. 24 | .easydns.com. 25 | .easydns.net. 26 | .your-server.de. 27 | .yandex.net. 28 | .techsmith.com. 29 | .nsone.net. 30 | .fastly.net. 31 | .hosteurope.de. 32 | .hostmonster.com. 33 | .automattic.com. 34 | .sedoparking.com. 35 | .ztomy.com. 36 | .parklogic.com. 37 | .gandi.net. 38 | .worldnic.com. 39 | .ftchinese.com. 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright © 2013 Felix Yan 2 | This work is free. You can redistribute it and/or modify it under the 3 | terms of the Do What The Fuck You Want To Public License, Version 2, 4 | as published by Sam Hocevar. See below for more details. 5 | 6 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 7 | Version 2, December 2004 8 | 9 | Copyright (C) 2004 Sam Hocevar 10 | 11 | Everyone is permitted to copy and distribute verbatim or modified 12 | copies of this license document, and changing it is allowed as long 13 | as the name is changed. 14 | 15 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 16 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 17 | 18 | 0. You just DO WHAT THE FUCK YOU WANT TO. 19 | -------------------------------------------------------------------------------- /cdn-testlist.txt: -------------------------------------------------------------------------------- 1 | 265.com 2 | a1.cdn-hotels.com 3 | a1.phobos.apple.com 4 | ad.doubleclick.net 5 | app-cdn.2q10.com 6 | app-measurement.com 7 | cdn.globalsigncdn.com 8 | cdn.jsdelivr.net 9 | cnc.ef-cdn.com 10 | d-cache.microad-cn.com 11 | dnl-11.geo.kaspersky.com 12 | edge.yunjiasu.com 13 | gateway.nyaacat.com 14 | googleadservices.com 15 | googletagmanager.com 16 | issuecdn.baidupcs.com.wsdvs.com 17 | itunes-cdn.itunes-apple.com.akadns.net 18 | netease.ugcvideoss.ourdvs.com 19 | opthw.xdwscache.speedcdns.com 20 | pagead2.googlesyndication.com 21 | r1.res.office365.com 22 | r1.res.outlook.com 23 | recaptcha.net 24 | s.c.lnkd.licdn.com 25 | s0.2mdn.net 26 | t1.tiles.ditu.live.com 27 | tse1-mm.cn.bing.net 28 | v24.lscache2.c.android.clients.google.com 29 | v2ex.assets.uxengine.net 30 | v2ex.china.uxengine.net 31 | v2ex.com 32 | www.agora.io 33 | www.azure.cn.mschcdn.com 34 | www.camcard.com 35 | www.fund001.com 36 | www.google-analytics.com 37 | www.googleanalytics.com 38 | www.googletagservices.com 39 | www.gov.cn 40 | www.howbuy.com 41 | www.shandongair.com 42 | www.sunrtb.com 43 | www.yangfd.com 44 | www.youngfunding.co.uk 45 | -------------------------------------------------------------------------------- /removed-cdn.txt: -------------------------------------------------------------------------------- 1 | z0.muscache.com 2 | z1.muscache.com 3 | z2.muscache.com 4 | configure.ap.dell.com 5 | lh3.appinn.net 6 | cs-analytics.htcsense.com 7 | msg.xboxlive.com 8 | userstats.xboxlive.com 9 | tiles.xbox.com 10 | script.image-gmkt.com 11 | cn.coremetrics.com 12 | gstatic.loli.net 13 | ajax.loli.net 14 | fonts.loli.net 15 | cdn.loli.net 16 | cdnjs.loli.net 17 | gravatar.loli.net 18 | www.ikea.com 19 | c.s-microsoft.com 20 | www1-cdn.dell.com 21 | gfwsl.geforce.com 22 | eds.xboxlive.com 23 | international-gfe.download.nvidia.com 24 | cn.download.nvidia.com 25 | international.download.nvidia.com 26 | dlassets.xboxlive.com 27 | titlestorage.xboxlive.com 28 | download.gfe.nvidia.com 29 | images.nvidia.com 30 | www.nvidia.com 31 | settings.xboxlive.com 32 | marketplace-xb.xboxlive.com 33 | compass.xboxlive.com 34 | image.xboxlive.com 35 | compass-ssl.xboxlive.com 36 | dlassets-ssl.xboxlive.com 37 | speedtest.xboxlive.com 38 | catalog-cdn.xboxlive.com 39 | store-images.microsoft.com 40 | store-images.s-microsoft.com 41 | avatarread.xboxlive.com 42 | cn.debian.org 43 | download.xboxlive.com 44 | sina.com.hk 45 | hdn.xnimg.cn.cdngc.net 46 | sekong.cn.com 47 | avatar-ssl.xboxlive.com 48 | ec8.images-amazon.com 49 | images-cn-8.ssl-images-amazon.com 50 | cnupgrade.microsoft.com 51 | x-dash-public.rec.mp.microsoft.com 52 | mediaexp-programming.xboxlive.com 53 | editorial.xboxlive.com 54 | achievements.xboxlive.com 55 | avatarread-ssl.xboxlive.com 56 | images-eds-ssl.xboxlive.com 57 | comments.xboxlive.com 58 | profile.xboxlive.com 59 | emdl.ws.microsoft.com 60 | encoding.image-gmkt.com 61 | v2ex.com 62 | adfarm.mediaplex.com 63 | ad.mediaplex.com 64 | altfarm.mediaplex.com 65 | img.mediaplex.com 66 | img-cdn.mediaplex.com 67 | www.st.com 68 | account.samsung.com 69 | console-service-ssl.halo.xbox.com 70 | web-service-ssl.halo.xbox.com 71 | ec4.images-amazon.com 72 | g-ec4.images-amazon.com 73 | download.epicgames.com 74 | images-cn-4.ssl-images-amazon.com 75 | e.admob.com 76 | jsdelivr.net 77 | -------------------------------------------------------------------------------- /ns-whitelist.txt: -------------------------------------------------------------------------------- 1 | .iidns.com. 2 | .dnspod.com. 3 | .dnspod.net. 4 | .hichina.com. 5 | .xincache.com. 6 | .dnsv2.com. 7 | .dnsv3.com. 8 | .dnsv4.com. 9 | .dnsv5.com. 10 | .myhostadmin.net. 11 | .cnolnic.com. 12 | .cnolnic.net. 13 | .dns.com.cn. 14 | .cnmsn.net. 15 | .bizcn.com. 16 | .alidns.com. 17 | .aliyun.com. 18 | .bddns.cn. 19 | .360wzb.com. 20 | .dnsdun.com. 21 | .dnsdun.net. 22 | .chinanetsun-dns.com. 23 | .ffdns.net. 24 | .xundns.com. 25 | .jiasule.net. 26 | .ns.yunjiasu.com. 27 | .cdncenter.com. 28 | .anquanbao.com. 29 | .sina.com.cn. 30 | .72dns.com. 31 | .idc1.cn. 32 | .ezdnscenter.com. 33 | .01isp.com. 34 | .01isp.net. 35 | .enet.com.cn. 36 | .800hr.net.cn. 37 | .dns.net.cn. 38 | .okidc.com. 39 | .cdnhost.cn. 40 | .eznowdns.net. 41 | .ndns.cn. 42 | .dnsng.net. 43 | .wanmeilink.com. 44 | .22.cn. 45 | .zjdomain.com. 46 | .zol.com. 47 | .ce.net.cn. 48 | .4everdns.com. 49 | .east.net.cn. 50 | .zdnscloud.net.cn. 51 | .51.net. 52 | .cloudcdns.com. 53 | .pubyun.com. 54 | .qq.com. 55 | .cdeledu.com. 56 | .myhexin.com. 57 | .bidns.net. 58 | .inc365.com. 59 | .zdnscloud.com. 60 | .zdnscloud.info. 61 | .chinanetsun.com. 62 | .gzidc.com. 63 | .ns365.net. 64 | .51dns.com. 65 | .nease.net. 66 | .xrnet.cn. 67 | .cnkuai.cn. 68 | .cnkuai.com. 69 | .taobao.com. 70 | .aoyou365.com. 71 | .dnspai.com. 72 | .360safe.com. 73 | .qycn.net. 74 | .qycn.cn. 75 | .sinonets.cn. 76 | .sfn.cn. 77 | .yovole.com. 78 | .duowanns.com. 79 | .ucweb.com 80 | .jcloud.com 81 | .eedns.com 82 | .maff.com 83 | .szhot.com. 84 | .bigwww.com. 85 | ns1.oray.net. 86 | ns2.oray.net. 87 | .cdnudns.com 88 | .zhujiwu.com. 89 | .jjworld.net.cn. 90 | .dns-diy.com. 91 | .iidns.com. 92 | .dns.com. 93 | .youku.com. 94 | .zj01.com. 95 | .cdns.cn. 96 | .bdydns.cn. 97 | .baidu.com. 98 | .139135.com. 99 | .hwclouds.net. 100 | .hwclouds.com. 101 | .hwclouds.cn. 102 | .alibabadns.com. 103 | .iqiyi.com. 104 | .jdcloud.com. 105 | .jdcache.com. 106 | .jd.com. 107 | .sohu.com. 108 | .dns234.net. 109 | .awsdns-cn- 110 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | WORKDIR="$(mktemp -d)" 5 | SERVERS=(114.114.114.114 114.114.115.115 180.76.76.76) 6 | # Not using best possible CDN pop: 1.2.4.8 210.2.4.8 223.5.5.5 223.6.6.6 7 | # Dirty cache: 119.29.29.29 182.254.116.116 8 | 9 | CONF_WITH_SERVERS=(accelerated-domains.china google.china apple.china) 10 | CONF_SIMPLE=(bogus-nxdomain.china) 11 | 12 | echo "Downloading latest configurations..." 13 | git clone --depth=1 https://git.dev.tencent.com/felixonmars/dnsmasq-china-list.git "$WORKDIR" 14 | #git clone --depth=1 https://pagure.io/dnsmasq-china-list.git "$WORKDIR" 15 | #git clone --depth=1 https://github.com/felixonmars/dnsmasq-china-list.git "$WORKDIR" 16 | #git clone --depth=1 https://bitbucket.org/felixonmars/dnsmasq-china-list.git "$WORKDIR" 17 | #git clone --depth=1 https://gitee.com/felixonmars/dnsmasq-china-list.git "$WORKDIR" 18 | #git clone --depth=1 https://gitlab.com/felixonmars/dnsmasq-china-list.git "$WORKDIR" 19 | #git clone --depth=1 https://code.aliyun.com/felixonmars/dnsmasq-china-list.git "$WORKDIR" 20 | #git clone --depth=1 http://repo.or.cz/dnsmasq-china-list.git "$WORKDIR" 21 | 22 | echo "Removing old configurations..." 23 | for _conf in "${CONF_WITH_SERVERS[@]}" "${CONF_SIMPLE[@]}"; do 24 | rm -f /etc/dnsmasq.d/"$_conf"*.conf 25 | done 26 | 27 | echo "Installing new configurations..." 28 | for _conf in "${CONF_SIMPLE[@]}"; do 29 | cp "$WORKDIR/$_conf.conf" "/etc/dnsmasq.d/$_conf.conf" 30 | done 31 | 32 | for _server in "${SERVERS[@]}"; do 33 | for _conf in "${CONF_WITH_SERVERS[@]}"; do 34 | cp "$WORKDIR/$_conf.conf" "/etc/dnsmasq.d/$_conf.$_server.conf" 35 | done 36 | 37 | sed -i "s|^\(server.*\)/[^/]*$|\1/$_server|" /etc/dnsmasq.d/*."$_server".conf 38 | done 39 | 40 | echo "Restarting dnsmasq service..." 41 | if hash systemctl 2>/dev/null; then 42 | systemctl restart dnsmasq 43 | elif hash service 2>/dev/null; then 44 | service dnsmasq restart 45 | else 46 | echo "Now please restart dnsmasq since I don't know how to do it." 47 | fi 48 | 49 | echo "Cleaning up..." 50 | rm -r "$WORKDIR" 51 | -------------------------------------------------------------------------------- /find_redundant.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | ''' Find redundant items in accelerated-domains.china.conf. 4 | e.g. 'bar.foo.com' is redundant for 'foo.com'. 5 | ''' 6 | 7 | 8 | def load(conf_file): 9 | ''' Parse conf file & Prepare data structure 10 | Returns: [ ['abc', 'com'], 11 | ['bar', 'foo', 'com'], 12 | ... ] 13 | ''' 14 | 15 | results = [] 16 | with open(conf_file, 'r') as f: 17 | for line in f.readlines(): 18 | line = line.strip() 19 | if line == '' or line.startswith('#'): 20 | continue 21 | # A domain name is case-insensitive and 22 | # consists of several labels, separated by a full stop 23 | domain_name = line.split('/')[1] 24 | domain_name = domain_name.lower() 25 | domain_labels = domain_name.split('.') 26 | results.append(domain_labels) 27 | 28 | # Sort results by domain labels' length 29 | results.sort(key=len) 30 | return results 31 | 32 | 33 | def find(labelses): 34 | ''' Find redundant items by a tree of top-level domain label to sub-level. 35 | `tree` is like { 'com': { 'foo: { 'bar': LEAF }, 36 | 'abc': LEAF }, 37 | 'org': ... } 38 | ''' 39 | tree = {} 40 | LEAF = 1 41 | for labels in labelses: 42 | domain = '.'.join(labels) 43 | # Init root node as current node 44 | node = tree 45 | while len(labels) > 0: 46 | label = labels.pop() 47 | if label in node: 48 | # If child node is a LEAF node, 49 | # current domain must be an existed domain or a subdomain of an existed. 50 | if node[label] == LEAF: 51 | print(f"Redundant found: {domain} at {'.'.join(labels)}") 52 | break 53 | else: 54 | # Create a leaf node if current label is last one 55 | if len(labels) == 0: 56 | node[label] = LEAF 57 | # Create a branch node 58 | else: 59 | node[label] = {} 60 | # Iterate to child node 61 | node = node[label] 62 | 63 | if __name__ == '__main__': 64 | find(load('accelerated-domains.china.conf')) 65 | -------------------------------------------------------------------------------- /updater.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from __future__ import unicode_literals 3 | from argparse import ArgumentParser 4 | import sys 5 | 6 | if __name__ == "__main__": 7 | parser = ArgumentParser(description="dnsmasq-china-list updater") 8 | parser.add_argument( 9 | '-a', '--add', 10 | metavar="DOMAIN", 11 | nargs="+", 12 | help='Add one or more new domain(s) (implies -s)', 13 | ) 14 | parser.add_argument( 15 | '-d', '--delete', 16 | metavar="DOMAIN", 17 | nargs="+", 18 | help='Remove one or more old domain(s) (implies -s)', 19 | ) 20 | parser.add_argument( 21 | '-s', '--sort', 22 | action='store_true', 23 | default=True, 24 | help='Sort the list (default action)', 25 | ) 26 | parser.add_argument( 27 | '-f', '--file', 28 | nargs=1, 29 | default=["accelerated-domains.china.conf"], 30 | help="Specify the file to update (accelerated-domains.china.conf by default)", 31 | ) 32 | 33 | options = parser.parse_args() 34 | 35 | with open(options.file[0]) as f: 36 | lines = list(f) 37 | 38 | changed = False 39 | 40 | if options.add: 41 | options.sort = True 42 | 43 | for domain in options.add: 44 | new_line = "server=/%s/114.114.114.114\n" % domain 45 | if new_line in lines: 46 | print("Domain already exists: " + domain) 47 | else: 48 | print("New domain added: " + domain) 49 | lines.append(new_line) 50 | changed = True 51 | 52 | if options.delete: 53 | options.sort = True 54 | 55 | for domain in options.delete: 56 | target_line = "server=/%s/114.114.114.114\n" % domain 57 | if target_line not in lines: 58 | print("Failed to remove domain " + domain + ": not found.") 59 | else: 60 | print("Domain removed: " + domain) 61 | lines.remove(target_line) 62 | changed = True 63 | 64 | if (options.add or options.delete) and not changed: 65 | sys.exit(1) 66 | 67 | if options.sort: 68 | lines.sort(key=lambda x: x.lstrip("#")) 69 | 70 | with open(options.file[0], "w") as f: 71 | f.write(''.join(filter(lambda line: line.strip(), lines))) 72 | -------------------------------------------------------------------------------- /google.china.conf: -------------------------------------------------------------------------------- 1 | server=/265.com/114.114.114.114 2 | server=/2mdn.net/114.114.114.114 3 | server=/adservice.google.com/114.114.114.114 4 | server=/app-measurement.com/114.114.114.114 5 | server=/beacons.gcp.gvt2.com/114.114.114.114 6 | server=/beacons.gvt2.com/114.114.114.114 7 | server=/beacons3.gvt2.com/114.114.114.114 8 | server=/c.admob.com/114.114.114.114 9 | server=/c.android.clients.google.com/114.114.114.114 10 | server=/cache.pack.google.com/114.114.114.114 11 | server=/cdn.ampproject.org/114.114.114.114 12 | server=/checkin.gstatic.com/114.114.114.114 13 | server=/clickserve.dartsearch.net/114.114.114.114 14 | server=/clientservices.googleapis.com/114.114.114.114 15 | server=/connectivitycheck.gstatic.com/114.114.114.114 16 | server=/csi.gstatic.com/114.114.114.114 17 | server=/dl.google.com/114.114.114.114 18 | server=/dl.l.google.com/114.114.114.114 19 | server=/doubleclick.net/114.114.114.114 20 | server=/fonts.googleapis.com/114.114.114.114 21 | server=/fonts.gstatic.com/114.114.114.114 22 | server=/google-analytics.com/114.114.114.114 23 | server=/googleadservices.com/114.114.114.114 24 | server=/googleanalytics.com/114.114.114.114 25 | server=/googlesyndication.com/114.114.114.114 26 | server=/googletagmanager.com/114.114.114.114 27 | server=/googletagservices.com/114.114.114.114 28 | server=/gtm.oasisfeng.com/114.114.114.114 29 | server=/imasdk.googleapis.com/114.114.114.114 30 | server=/kh.google.com/114.114.114.114 31 | server=/khm.google.com/114.114.114.114 32 | server=/khm.googleapis.com/114.114.114.114 33 | server=/khm0.google.com/114.114.114.114 34 | server=/khm0.googleapis.com/114.114.114.114 35 | server=/khm1.google.com/114.114.114.114 36 | server=/khm1.googleapis.com/114.114.114.114 37 | server=/khm2.google.com/114.114.114.114 38 | server=/khm2.googleapis.com/114.114.114.114 39 | server=/khm3.google.com/114.114.114.114 40 | server=/khm3.googleapis.com/114.114.114.114 41 | server=/khmdb.google.com/114.114.114.114 42 | server=/khmdb.googleapis.com/114.114.114.114 43 | server=/media.admob.com/114.114.114.114 44 | server=/pagead-googlehosted.l.google.com/114.114.114.114 45 | server=/recaptcha.net/114.114.114.114 46 | server=/redirector.gvt1.com/114.114.114.114 47 | server=/safebrowsing-cache.google.com/114.114.114.114 48 | server=/safebrowsing.googleapis.com/114.114.114.114 49 | server=/ssl-google-analytics.l.google.com/114.114.114.114 50 | server=/ssl.gstatic.com/114.114.114.114 51 | server=/toolbarqueries.google.com/114.114.114.114 52 | server=/tools.google.com/114.114.114.114 53 | server=/tools.l.google.com/114.114.114.114 54 | server=/translate.googleapis.com/114.114.114.114 55 | server=/update.googleapis.com/114.114.114.114 56 | server=/www-googletagmanager.l.google.com/114.114.114.114 57 | server=/www.gstatic.com/114.114.114.114 58 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SERVER=114.114.114.114 2 | NEWLINE=UNIX 3 | 4 | raw: 5 | sed -e 's|^server=/\(.*\)/114.114.114.114$$|\1|' accelerated-domains.china.conf | egrep -v '^#' > accelerated-domains.china.raw.txt 6 | sed -e 's|^server=/\(.*\)/114.114.114.114$$|\1|' google.china.conf | egrep -v '^#' > google.china.raw.txt 7 | sed -e 's|^server=/\(.*\)/114.114.114.114$$|\1|' apple.china.conf | egrep -v '^#' > apple.china.raw.txt 8 | 9 | dnsmasq: raw 10 | sed -e 's|\(.*\)|server=/\1/$(SERVER)|' accelerated-domains.china.raw.txt > accelerated-domains.china.dnsmasq.conf 11 | sed -e 's|\(.*\)|server=/\1/$(SERVER)|' google.china.raw.txt > google.china.dnsmasq.conf 12 | sed -e 's|\(.*\)|server=/\1/$(SERVER)|' apple.china.raw.txt > apple.china.dnsmasq.conf 13 | 14 | unbound: raw 15 | sed -e 's|\(.*\)|forward-zone:\n name: "\1."\n forward-addr: $(SERVER)\n|' accelerated-domains.china.raw.txt > accelerated-domains.china.unbound.conf 16 | sed -e 's|\(.*\)|forward-zone:\n name: "\1."\n forward-addr: $(SERVER)\n|' google.china.raw.txt > google.china.unbound.conf 17 | sed -e 's|\(.*\)|forward-zone:\n name: "\1."\n forward-addr: $(SERVER)\n|' apple.china.raw.txt > apple.china.unbound.conf 18 | ifeq ($(NEWLINE),DOS) 19 | sed -i 's/\r*$$/\r/' accelerated-domains.china.unbound.conf google.china.unbound.conf apple.china.unbound.conf 20 | endif 21 | 22 | bind: raw 23 | sed -e 's|\(.*\)|zone "\1." {type forward; forwarders { $(SERVER); }; };|' accelerated-domains.china.raw.txt > accelerated-domains.china.bind.conf 24 | sed -e 's|\(.*\)|zone "\1." {type forward; forwarders { $(SERVER); }; };|' google.china.raw.txt > google.china.bind.conf 25 | sed -e 's|\(.*\)|zone "\1." {type forward; forwarders { $(SERVER); }; };|' apple.china.raw.txt > apple.china.bind.conf 26 | ifeq ($(NEWLINE),DOS) 27 | sed -i 's/\r*$$/\r/' accelerated-domains.china.bind.conf google.china.bind.conf apple.china.bind.conf 28 | endif 29 | 30 | dnscrypt-proxy: raw 31 | sed -e 's|\(.*\)|\1 $(SERVER)|' accelerated-domains.china.raw.txt google.china.raw.txt apple.china.raw.txt > dnscrypt-proxy-forwarding-rules.txt 32 | ifeq ($(NEWLINE),DOS) 33 | sed -i 's/\r*$$/\r/' dnscrypt-proxy-forwarding-rules.txt 34 | endif 35 | 36 | dnsforwarder6: raw 37 | { printf "protocol udp\nserver $(SERVER)\nparallel on \n"; cat accelerated-domains.china.raw.txt; } > accelerated-domains.china.dnsforwarder.conf 38 | { printf "protocol udp\nserver $(SERVER)\nparallel on \n"; cat google.china.raw.txt; } > google.china.dnsforwarder.conf 39 | { printf "protocol udp\nserver $(SERVER)\nparallel on \n"; cat apple.china.raw.txt; } > apple.china.dnsforwarder.conf 40 | ifeq ($(NEWLINE),DOS) 41 | sed -i 's/\r*$$/\r/' accelerated-domains.china.dnsforwarder.conf google.china.dnsforwarder.conf apple.china.dnsforwarder.conf 42 | endif 43 | 44 | clean: 45 | rm -f {accelerated-domains,google,apple}.china.{dnsmasq,unbound,bind}.conf {accelerated-domains,google,apple}.china.raw.txt dnscrypt-proxy-forwarding-rules.txt 46 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | dnsmasq-china-list 2 | ================== 3 | 4 | Chinese-specific configuration to improve your favorite DNS server. Best partner for chnroutes. 5 | 6 | - Improve resolve speed for Chinese domains. 7 | 8 | - Get the best CDN node near you whenever possible, but don't compromise foreign CDN results so you also get best CDN node for your VPN at the same time. 9 | 10 | - Block ISP ads on NXDOMAIN result (like 114so). 11 | 12 | Details 13 | ======= 14 | 15 | - `accelerated-domains.china.conf`: General domains to be accelerated. 16 | 17 | These domains have a better resolving speed and/or result when using a Chinese DNS server. 18 | 19 | To determine if a domain is eligible, one of the criteria below must be met: 20 | 21 | - The domain's NS server is located in China mainland. 22 | 23 | - The domain will resolve to an IP located in China mainland when using a Chinese DNS server, but _not_ always do when using a foreign DNS server (For example, CDN accelerated sites that have node in China). This however does _not_ include those having node _near_ China mainland, like in Japan, Hong Kong, Taiwan, etc. 24 | 25 | Please don't add subdomains if the top domain is already in the list. This includes all .cn domains which are already matched by the `/cn/` rule. 26 | 27 | - `google.china.conf`: Google domains to be accelerated. 28 | 29 | These domains are resolved to Google China servers when using a Chinese DNS. In most conditions this will yield better page load time for sites using Google's web services, e.g. Google Web Fonts and AdSense. 30 | 31 | Bear in mind that they are _not_ considered stable. **Use at your own risk**. 32 | 33 | - `apple.china.conf`: Apple domains to be accelerated. 34 | 35 | Some ISPs (often smaller ones) have problem accessing Apple's assets using their China mainland CDN servers. Please consider remove this file if that happens to you. See #156 for some more info. 36 | 37 | - `bogus-nxdomain.china.conf`: Known addresses that are hijacking NXDOMAIN results returned by DNS servers. 38 | 39 | Usage 40 | ===== 41 | 42 | Automatic Installation (recommended) 43 | ------------------------------------ 44 | 45 | 1. Fetch the installer from github (or a mirror): `wget https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/install.sh` 46 | 2. (Optional) Edit it to use your favorite DNS server and/or another mirror to download the list. 47 | 3. Run it as root: `sudo ./install.sh` 48 | 49 | You can save the installer and run it again to update the list regularly. 50 | 51 | Manual Installation 52 | ------------------- 53 | 54 | 1. Place accelerated-domains.china.conf, bogus-nxdomain.china.conf (and optionally google.china.conf, apple.china.conf) under /etc/dnsmasq.d/ (Create the folder if it does not exist). 55 | 2. Uncomment "conf-dir=/etc/dnsmasq.d" in /etc/dnsmasq.conf 56 | 3. (Optional) Place dnsmasq-update-china-list into /usr/bin/ 57 | 4. (Optional) Make custom DNS server configuration and/or other services' configuration. 58 | 59 | ```shell 60 | # change the default DNS server to 202.96.128.86 61 | make SERVER=202.96.128.86 dnsmasq 62 | # generate unbound's configuration 63 | make unbound 64 | # generate bind's configuration 65 | make bind 66 | # full example of generating dnscrypt-proxy forwarding rules for Windows 67 | make SERVER=101.6.6.6 NEWLINE=DOS dnscrypt-proxy 68 | ``` 69 | 70 | License 71 | ======= 72 | 73 | ``` 74 | Copyright © 2015 Felix Yan 75 | This work is free. You can redistribute it and/or modify it under the 76 | terms of the Do What The Fuck You Want To Public License, Version 2, 77 | as published by Sam Hocevar. See the LICENSE file for more details. 78 | ``` 79 | -------------------------------------------------------------------------------- /apple.china.conf: -------------------------------------------------------------------------------- 1 | server=/a1.mzstatic.com/114.114.114.114 2 | server=/a2.mzstatic.com/114.114.114.114 3 | server=/a3.mzstatic.com/114.114.114.114 4 | server=/a4.mzstatic.com/114.114.114.114 5 | server=/a5.mzstatic.com/114.114.114.114 6 | server=/adcdownload.apple.com/114.114.114.114 7 | server=/appldnld.apple.com/114.114.114.114 8 | server=/appldnld.g.aaplimg.com/114.114.114.114 9 | server=/apps.apple.com/114.114.114.114 10 | server=/apps.mzstatic.com/114.114.114.114 11 | server=/cdn-cn1.apple-mapkit.com/114.114.114.114 12 | server=/cdn-cn2.apple-mapkit.com/114.114.114.114 13 | server=/cdn-cn3.apple-mapkit.com/114.114.114.114 14 | server=/cdn-cn4.apple-mapkit.com/114.114.114.114 15 | server=/cdn.apple-mapkit.com/114.114.114.114 16 | server=/cdn1.apple-mapkit.com/114.114.114.114 17 | server=/cdn2.apple-mapkit.com/114.114.114.114 18 | server=/cdn3.apple-mapkit.com/114.114.114.114 19 | server=/cdn4.apple-mapkit.com/114.114.114.114 20 | server=/cds.apple.com/114.114.114.114 21 | server=/cl1.apple.com/114.114.114.114 22 | server=/cl2.apple.com.edgekey.net.globalredir.akadns.net/114.114.114.114 23 | server=/cl2.apple.com/114.114.114.114 24 | server=/cl3.apple.com/114.114.114.114 25 | server=/cl4-cn.apple.com/114.114.114.114 26 | server=/cl4.apple.com/114.114.114.114 27 | server=/cl5.apple.com/114.114.114.114 28 | server=/configuration.apple.com.akadns.net/114.114.114.114 29 | server=/configuration.apple.com/114.114.114.114 30 | server=/gs-loc.apple.com/114.114.114.114 31 | server=/gsp11-cn.ls.apple.com/114.114.114.114 32 | server=/gsp12-cn.ls.apple.com/114.114.114.114 33 | server=/gsp13-cn.ls.apple.com/114.114.114.114 34 | server=/gsp4-cn.ls.apple.com.edgekey.net.globalredir.akadns.net/114.114.114.114 35 | server=/gsp4-cn.ls.apple.com.edgekey.net/114.114.114.114 36 | server=/gsp4-cn.ls.apple.com/114.114.114.114 37 | server=/gsp5-cn.ls.apple.com/114.114.114.114 38 | server=/gspe19-cn.ls-apple.com.akadns.net/114.114.114.114 39 | server=/gspe19-cn.ls.apple.com/114.114.114.114 40 | server=/gspe21-ssl.ls.apple.com/114.114.114.114 41 | server=/gspe21.ls.apple.com/114.114.114.114 42 | server=/gspe35-ssl.ls.apple.com/114.114.114.114 43 | server=/icloud.cdn-apple.com/114.114.114.114 44 | server=/images.apple.com/114.114.114.114 45 | server=/init-p01md.apple.com/114.114.114.114 46 | server=/init-p01st.push.apple.com/114.114.114.114 47 | server=/init-s01st.push.apple.com/114.114.114.114 48 | server=/iosapps.itunes.g.aaplimg.com/114.114.114.114 49 | server=/iphone-ld.apple.com/114.114.114.114 50 | server=/is1-ssl.mzstatic.com/114.114.114.114 51 | server=/is1.mzstatic.com/114.114.114.114 52 | server=/is2-ssl.mzstatic.com/114.114.114.114 53 | server=/is2.mzstatic.com/114.114.114.114 54 | server=/is3-ssl.mzstatic.com/114.114.114.114 55 | server=/is3.mzstatic.com/114.114.114.114 56 | server=/is4-ssl.mzstatic.com/114.114.114.114 57 | server=/is4.mzstatic.com/114.114.114.114 58 | server=/is5-ssl.mzstatic.com/114.114.114.114 59 | server=/is5.mzstatic.com/114.114.114.114 60 | server=/itunes-apple.com.akadns.net/114.114.114.114 61 | server=/itunes.apple.com/114.114.114.114 62 | server=/itunesconnect.apple.com/114.114.114.114 63 | server=/mesu-cdn.apple.com.akadns.net/114.114.114.114 64 | server=/mesu-china.apple.com.akadns.net/114.114.114.114 65 | server=/mesu.apple.com/114.114.114.114 66 | server=/oscdn.apple.com/114.114.114.114 67 | server=/pancake.apple.com/114.114.114.114 68 | server=/phobos.apple.com/114.114.114.114 69 | server=/s.mzstatic.com/114.114.114.114 70 | server=/s1.mzstatic.com/114.114.114.114 71 | server=/s2.mzstatic.com/114.114.114.114 72 | server=/s3.mzstatic.com/114.114.114.114 73 | server=/s4.mzstatic.com/114.114.114.114 74 | server=/s5.mzstatic.com/114.114.114.114 75 | server=/store.apple.com/114.114.114.114 76 | server=/store.storeimages.cdn-apple.com/114.114.114.114 77 | server=/support.apple.com/114.114.114.114 78 | server=/swcdn.apple.com/114.114.114.114 79 | server=/swcdn.g.aaplimg.com/114.114.114.114 80 | server=/swdist.apple.com/114.114.114.114 81 | server=/swscan.apple.com/114.114.114.114 82 | server=/updates-http.cdn-apple.com.akadns.net/114.114.114.114 83 | server=/updates-http.cdn-apple.com/114.114.114.114 84 | server=/valid.apple.com/114.114.114.114 85 | server=/www.apple.com.edgekey.net/114.114.114.114 86 | server=/www.apple.com/114.114.114.114 87 | -------------------------------------------------------------------------------- /bogus-nxdomain.china.conf: -------------------------------------------------------------------------------- 1 | ## Public DNS 2 | 3 | # DNSPai 4 | bogus-nxdomain=123.125.81.12 5 | bogus-nxdomain=101.226.10.8 6 | 7 | # Level3 8 | bogus-nxdomain=198.105.254.11 9 | bogus-nxdomain=104.239.213.7 10 | 11 | 12 | ## China Telecom 13 | 14 | # Anhui Telecom 15 | bogus-nxdomain=61.191.206.4 16 | 17 | # Beijing Telecom 18 | bogus-nxdomain=218.30.64.194 19 | 20 | # Chengdu Telecom 21 | bogus-nxdomain=61.139.8.101 22 | bogus-nxdomain=61.139.8.102 23 | bogus-nxdomain=61.139.8.103 24 | bogus-nxdomain=61.139.8.104 25 | 26 | # Fujian Telecom 27 | bogus-nxdomain=42.123.125.237 28 | 29 | # Gansu Telecom 30 | bogus-nxdomain=202.100.68.117 31 | 32 | # Guangxi Telecom 33 | bogus-nxdomain=113.12.83.4 34 | bogus-nxdomain=113.12.83.5 35 | 36 | # Hainan Telecom 37 | bogus-nxdomain=202.100.220.54 38 | 39 | # Hangzhou Telecom 40 | bogus-nxdomain=60.191.124.236 41 | bogus-nxdomain=60.191.124.252 42 | 43 | # Hebei Telecom 44 | bogus-nxdomain=222.221.5.204 45 | 46 | # Hunan Telecom 47 | bogus-nxdomain=124.232.132.94 48 | 49 | # Jiangsu Telecom 50 | bogus-nxdomain=202.102.110.204 51 | 52 | # Jiangxi Telecom 53 | bogus-nxdomain=61.131.208.210 54 | bogus-nxdomain=61.131.208.211 55 | 56 | # Nanjing Telecom 57 | bogus-nxdomain=202.102.110.203 58 | bogus-nxdomain=202.102.110.205 59 | 60 | # Shandong Telecom 61 | bogus-nxdomain=219.146.13.36 62 | 63 | # Shanghai Telecom 64 | bogus-nxdomain=180.168.41.175 65 | bogus-nxdomain=180.153.103.224 66 | 67 | # Wuhan Telecom 68 | bogus-nxdomain=111.175.221.58 69 | bogus-nxdomain=61.183.1.186 70 | 71 | # Xi'an Telecom 72 | bogus-nxdomain=125.76.239.244 73 | bogus-nxdomain=125.76.239.245 74 | 75 | # Yunnan Telecom 76 | bogus-nxdomain=222.221.5.252 77 | bogus-nxdomain=222.221.5.253 78 | bogus-nxdomain=220.165.8.172 79 | bogus-nxdomain=220.165.8.174 80 | 81 | 82 | ## China Unicom 83 | 84 | # Anhui Unicom 85 | bogus-nxdomain=112.132.230.179 86 | 87 | # Beijing Unicom (bjdnserror1.wo.com.cn ~ bjdnserror5.wo.com.cn) 88 | bogus-nxdomain=202.106.199.34 89 | bogus-nxdomain=202.106.199.35 90 | bogus-nxdomain=202.106.199.36 91 | bogus-nxdomain=202.106.199.37 92 | bogus-nxdomain=202.106.199.38 93 | 94 | # Hebei Unicom (hbdnserror1.wo.com.cn ~ hbdnserror7.wo.com.cn) 95 | bogus-nxdomain=221.192.153.41 96 | bogus-nxdomain=221.192.153.42 97 | bogus-nxdomain=221.192.153.43 98 | bogus-nxdomain=221.192.153.44 99 | bogus-nxdomain=221.192.153.45 100 | bogus-nxdomain=221.192.153.46 101 | bogus-nxdomain=221.192.153.49 102 | 103 | # Heilongjiang Unicom (hljdnserror1.wo.com.cn ~ hljdnserror5.wo.com.cn) 104 | bogus-nxdomain=125.211.213.130 105 | bogus-nxdomain=125.211.213.131 106 | bogus-nxdomain=125.211.213.132 107 | bogus-nxdomain=125.211.213.133 108 | bogus-nxdomain=125.211.213.134 109 | 110 | # Henan Unicom (hndnserror1.wo.com.cn ~ hndnserror7.wo.com.cn) 111 | bogus-nxdomain=218.28.144.36 112 | bogus-nxdomain=218.28.144.37 113 | bogus-nxdomain=218.28.144.38 114 | bogus-nxdomain=218.28.144.39 115 | bogus-nxdomain=218.28.144.40 116 | bogus-nxdomain=218.28.144.41 117 | bogus-nxdomain=218.28.144.42 118 | 119 | # Jilin Unicom (jldnserror1.wo.com.cn ~ jldnserror5.wo.com.cn) 120 | bogus-nxdomain=202.98.24.121 121 | bogus-nxdomain=202.98.24.122 122 | bogus-nxdomain=202.98.24.123 123 | bogus-nxdomain=202.98.24.124 124 | bogus-nxdomain=202.98.24.125 125 | 126 | # Liaoning Unicom (lndnserror1.wo.com.cn ~ lndnserror7.wo.com.cn) 127 | bogus-nxdomain=60.19.29.21 128 | bogus-nxdomain=60.19.29.22 129 | bogus-nxdomain=60.19.29.23 130 | bogus-nxdomain=60.19.29.24 131 | bogus-nxdomain=60.19.29.25 132 | bogus-nxdomain=60.19.29.26 133 | bogus-nxdomain=60.19.29.27 134 | 135 | # Nanfang Unicom (nfdnserror1.wo.com.cn ~ nfdnserror17.wo.com.cn) 136 | bogus-nxdomain=220.250.64.18 137 | bogus-nxdomain=220.250.64.19 138 | bogus-nxdomain=220.250.64.20 139 | bogus-nxdomain=220.250.64.21 140 | bogus-nxdomain=220.250.64.22 141 | bogus-nxdomain=220.250.64.23 142 | bogus-nxdomain=220.250.64.24 143 | bogus-nxdomain=220.250.64.25 144 | bogus-nxdomain=220.250.64.26 145 | bogus-nxdomain=220.250.64.27 146 | bogus-nxdomain=220.250.64.28 147 | bogus-nxdomain=220.250.64.29 148 | bogus-nxdomain=220.250.64.30 149 | bogus-nxdomain=220.250.64.225 150 | bogus-nxdomain=220.250.64.226 151 | bogus-nxdomain=220.250.64.227 152 | bogus-nxdomain=220.250.64.228 153 | 154 | # Neimenggu Unicom (nmdnserror2.wo.com.cn ~ nmdnserror4.wo.com.cn) 155 | bogus-nxdomain=202.99.254.231 156 | bogus-nxdomain=202.99.254.232 157 | bogus-nxdomain=202.99.254.230 158 | 159 | # Shandong Unicom (sddnserror1.wo.com.cn ~ sddnserror9.wo.com.cn) 160 | bogus-nxdomain=123.129.254.11 161 | bogus-nxdomain=123.129.254.12 162 | bogus-nxdomain=123.129.254.13 163 | bogus-nxdomain=123.129.254.14 164 | bogus-nxdomain=123.129.254.15 165 | bogus-nxdomain=123.129.254.16 166 | bogus-nxdomain=123.129.254.17 167 | bogus-nxdomain=123.129.254.18 168 | bogus-nxdomain=123.129.254.19 169 | 170 | # Shanxi Unicom (sxdnserror1.wo.com.cn ~ sxdnserror6.wo.com.cn) 171 | bogus-nxdomain=221.204.244.36 172 | bogus-nxdomain=221.204.244.37 173 | bogus-nxdomain=221.204.244.38 174 | bogus-nxdomain=221.204.244.39 175 | bogus-nxdomain=221.204.244.40 176 | bogus-nxdomain=221.204.244.41 177 | 178 | # Tianjin Unicom (tjdnserror1.wo.com.cn ~ tjdnserror5.wo.com.cn) 179 | bogus-nxdomain=218.68.250.117 180 | bogus-nxdomain=218.68.250.118 181 | bogus-nxdomain=218.68.250.119 182 | bogus-nxdomain=218.68.250.120 183 | bogus-nxdomain=218.68.250.121 184 | 185 | 186 | ## China Mobile 187 | 188 | # Anhui Mobile 189 | bogus-nxdomain=120.209.138.64 190 | 191 | # Guangdong Mobile 192 | bogus-nxdomain=211.139.136.73 193 | bogus-nxdomain=221.179.46.190 194 | bogus-nxdomain=221.179.46.194 195 | 196 | # Jiangsu Mobile 197 | bogus-nxdomain=183.207.232.253 198 | 199 | # Jiangxi Mobile 200 | bogus-nxdomain=223.82.248.117 201 | 202 | # Qinghai Mobile 203 | bogus-nxdomain=211.138.74.132 204 | 205 | # Shaanxi Mobile 206 | bogus-nxdomain=211.137.130.101 207 | 208 | # Shanghai Mobile 209 | bogus-nxdomain=211.136.113.1 210 | 211 | # Shanxi Mobile 212 | bogus-nxdomain=211.138.102.198 213 | 214 | # Shandong Mobile 215 | bogus-nxdomain=120.192.83.163 216 | 217 | # Sichuan Mobile 218 | bogus-nxdomain=183.221.242.172 219 | bogus-nxdomain=183.221.250.11 220 | 221 | # Xizang Mobile 222 | bogus-nxdomain=111.11.208.2 223 | 224 | # Yunnan Mobile 225 | bogus-nxdomain=183.224.40.24 226 | 227 | 228 | ## China Tie Tong 229 | 230 | # Shandong TieTong 231 | bogus-nxdomain=211.98.70.226 232 | bogus-nxdomain=211.98.70.227 233 | bogus-nxdomain=211.98.71.195 234 | 235 | 236 | ## GWBN 237 | 238 | # Wuhan GWBN 239 | bogus-nxdomain=114.112.163.232 240 | bogus-nxdomain=114.112.163.254 241 | -------------------------------------------------------------------------------- /verify.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import dns.resolver, dns.rdataclass, dns.rdatatype, dns.name 4 | from termcolor import colored 5 | import random 6 | import ipaddress 7 | import tldextract 8 | from io import StringIO 9 | 10 | 11 | class ChnroutesNotAvailable(Exception): 12 | pass 13 | 14 | class NSNotAvailable(Exception): 15 | pass 16 | 17 | # OK 18 | class OK(Exception): 19 | pass 20 | 21 | class WhitelistMatched(OK): 22 | pass 23 | 24 | class CDNListVerified(OK): 25 | pass 26 | 27 | class NSVerified(OK): 28 | pass 29 | 30 | # Not OK 31 | class NotOK(Exception): 32 | pass 33 | 34 | class NXDOMAIN(NotOK): 35 | pass 36 | 37 | class BlacklistMatched(NotOK): 38 | pass 39 | 40 | class CDNListNotVerified(NotOK): 41 | pass 42 | 43 | class NSNotVerified(NotOK): 44 | pass 45 | 46 | 47 | class ChinaListVerify(object): 48 | whitelist_file = "ns-whitelist.txt" 49 | blacklist_file = "ns-blacklist.txt" 50 | cdnlist_file = "cdn-testlist.txt" 51 | chnroutes_file = "/usr/share/chnroutes2/chnroutes.txt" 52 | tld_ns = {} 53 | 54 | def __init__(self): 55 | self.whitelist = self.load_list(self.whitelist_file) 56 | self.blacklist = self.load_list(self.blacklist_file) 57 | self.cdnlist = self.load_list(self.cdnlist_file) 58 | 59 | try: 60 | self.chnroutes = self.load_list(self.chnroutes_file) 61 | except FileNotFoundError: 62 | print(colored("Failed to load chnroutes, CDN check disabled", "red")) 63 | self.chnroutes = None 64 | 65 | def load_list(self, filename): 66 | with open(filename) as f: 67 | return list([l.rstrip('\n') for l in f if l and not l.startswith("#")]) 68 | 69 | def test_cn_ip(self, domain, response=None): 70 | if self.chnroutes is None: 71 | raise ChnroutesNotAvailable 72 | 73 | answers = None 74 | if response: 75 | try: 76 | answers = response.find_rrset(response.additional, dns.name.from_text(domain), dns.rdataclass.IN, dns.rdatatype.A) 77 | except KeyError: 78 | pass 79 | 80 | if not answers: 81 | answers = dns.resolver.query(domain, 'A') 82 | 83 | for answer in answers: 84 | answer = answer.to_text() 85 | if any(ipaddress.IPv4Address(answer) in ipaddress.IPv4Network(n) for n in self.chnroutes): 86 | return True 87 | 88 | return False 89 | 90 | def resolve(self, domain, rdtype="A", server=None, authority=False): 91 | if not server: 92 | return dns.resolver.query(domain, rdtype) 93 | elif not authority: 94 | return dns.resolver.Resolver(filename=StringIO("nameserver " + server)).query(domain, rdtype) 95 | else: 96 | answer = dns.resolver.Resolver(filename=StringIO("nameserver " + server)).query(domain, rdtype, raise_on_no_answer=False) 97 | return answer.response 98 | 99 | def get_ns_for_tld(self, tld): 100 | if tld not in self.tld_ns: 101 | answers = self.resolve(tld + ".", "NS") 102 | ips = self.resolve(answers[0].to_text()) 103 | self.tld_ns[tld] = ips[0].to_text() 104 | 105 | return self.tld_ns[tld] 106 | 107 | def check_whitelist(self, nameservers): 108 | if any(i in " ".join(nameservers) for i in self.whitelist): 109 | raise WhitelistMatched 110 | 111 | def check_blacklist(self, nameservers): 112 | if any(i in " ".join(nameservers) for i in self.blacklist): 113 | raise BlacklistMatched 114 | 115 | def check_cdnlist(self, domain): 116 | if self.test_cn_ip(domain): 117 | raise CDNListVerified 118 | else: 119 | raise CDNListNotVerified 120 | 121 | def check_domain(self, domain, enable_cdnlist=True): 122 | nameservers = [] 123 | nxdomain = False 124 | try: 125 | response = self.resolve(domain + ".", 'NS', self.get_ns_for_tld(tldextract.extract(domain).suffix), authority=True) 126 | except dns.resolver.NXDOMAIN: 127 | nxdomain = True 128 | except: 129 | raise 130 | pass 131 | else: 132 | for rdata in response.authority[0]: 133 | nameserver = rdata.to_text() 134 | if tldextract.extract(nameserver).registered_domain: 135 | nameservers.append(nameserver) 136 | 137 | self.check_whitelist(nameservers) 138 | 139 | if enable_cdnlist: 140 | for testdomain in self.cdnlist: 141 | if testdomain == domain or testdomain.endswith("." + domain): 142 | try: 143 | self.check_cdnlist(testdomain) 144 | except dns.resolver.NXDOMAIN: 145 | raise NXDOMAIN 146 | 147 | # Assuming CDNList for non-TLDs 148 | if domain.count(".") > 1 and tldextract.extract(domain).registered_domain != domain: 149 | try: 150 | self.check_cdnlist(domain) 151 | except (dns.resolver.NoAnswer, dns.resolver.NXDOMAIN, dns.resolver.NoNameservers, dns.exception.Timeout): 152 | pass 153 | 154 | if nxdomain: 155 | # Double check due to false positives 156 | try: 157 | dns.resolver.query("www." + domain, 'A') 158 | except dns.resolver.NXDOMAIN: 159 | raise NXDOMAIN 160 | 161 | self.check_blacklist(nameservers) 162 | 163 | for nameserver in nameservers: 164 | try: 165 | if self.test_cn_ip(nameserver, response): 166 | raise NSVerified 167 | except (dns.resolver.NoAnswer, dns.resolver.NXDOMAIN, dns.resolver.NoNameservers, dns.exception.Timeout): 168 | pass 169 | 170 | if nameservers: 171 | raise NSNotVerified 172 | else: 173 | raise NSNotAvailable 174 | 175 | def check_domain_quiet(self, domain, **kwargs): 176 | try: 177 | self.check_domain(domain, **kwargs) 178 | except OK: 179 | return True 180 | except NotOK: 181 | return False 182 | except: 183 | return None 184 | else: 185 | return None 186 | 187 | def check_domain_verbose(self, domain, show_green=False, **kwargs): 188 | try: 189 | try: 190 | self.check_domain(domain, **kwargs) 191 | except NXDOMAIN: 192 | print(colored("NXDOMAIN found in (cdnlist or) domain: " + domain, "white", "on_red")) 193 | raise 194 | except WhitelistMatched: 195 | if show_green: 196 | print(colored("NS Whitelist matched for domain: " + domain, "green")) 197 | raise 198 | except CDNListVerified: 199 | if show_green: 200 | print(colored("CDNList matched and verified for domain: " + domain, "green")) 201 | raise 202 | except CDNListNotVerified: 203 | print(colored("CDNList matched but failed to verify for domain: " + domain, "red")) 204 | raise 205 | except BlacklistMatched: 206 | print(colored("NS Blacklist matched for domain: " + domain, "red")) 207 | raise 208 | except NSVerified: 209 | if show_green: 210 | print(colored("NS verified for domain: " + domain, "green")) 211 | raise 212 | except NSNotVerified: 213 | print(colored("NS failed to verify for domain: " + domain, "red")) 214 | raise 215 | except ChnroutesNotAvailable: 216 | print("Additional Check disabled due to missing chnroutes. domain:", domain) 217 | raise 218 | except NSNotAvailable: 219 | print("Failed to get correct name server for domain:", domain) 220 | raise 221 | else: 222 | raise NotImplementedError 223 | except OK: 224 | return True 225 | except NotOK: 226 | return False 227 | except: 228 | return None 229 | else: 230 | return None 231 | 232 | def check_domain_list(self, domain_list, sample=30, show_green=False): 233 | domains = self.load_list(domain_list) 234 | if sample: 235 | domains = random.sample(domains, sample) 236 | else: 237 | random.shuffle(domains) 238 | for domain in domains: 239 | self.check_domain_verbose(domain, show_green=show_green) 240 | 241 | 242 | if __name__ == "__main__": 243 | import argparse 244 | description = 'A simple verify library for dnsmasq-china-list' 245 | parser = argparse.ArgumentParser(description=description) 246 | parser.add_argument('-f', '--file', nargs='?', default="accelerated-domains.china.raw.txt", 247 | help='File to examine') 248 | parser.add_argument('-s', '--sample', nargs='?', default=0, 249 | help='Verify only a limited sample. Pass 0 to example all entries.') 250 | parser.add_argument('-v', '--verbose', action="store_true", 251 | help='Show green results.') 252 | parser.add_argument('-d', '--domain', nargs='?', 253 | help='Verify a domain instead of checking a list. Will ignore the other options.') 254 | 255 | config = parser.parse_args() 256 | v = ChinaListVerify() 257 | 258 | if config.domain: 259 | v.check_domain_verbose(config.domain, show_green=config.verbose) 260 | else: 261 | v.check_domain_list(config.file, show_green=config.verbose, sample=int(config.sample)) 262 | --------------------------------------------------------------------------------