openwrt-dns/dnscrypt_to_smartdns.py
2025-04-20 03:22:12 +08:00

102 lines
2.4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import logging
import subprocess
from urllib.request import urlopen
from dnscrypt import parse, DNSoverHTTPS
SMARTDNS_GFW_CONF_FILE = '/etc/smartdns/conf.d/gfw-server.conf'
# https://github.com/DNSCrypt/dnscrypt-resolvers
PUBLIC_RESOLVER_URL_LIST = [
"https://download.dnscrypt.info/resolvers-list/v3/public-resolvers.md",
"https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/public-resolvers.md"
"https://dnsr.evilvibes.com/v3/public-resolvers.md"
]
def get_public_resolver_md() -> str:
for url in PUBLIC_RESOLVER_URL_LIST:
try:
logging.info('request {url}'.format(url=url))
with urlopen(url, timeout=15) as responsee:
return responsee.read().decode('utf-8')
except:
pass
raise IOError("can't download public-resolvers.md")
def get_stamps():
resolver_md: str = get_public_resolver_md()
lines = resolver_md.splitlines()
stamps = list(
map(
parse,
filter(lambda x: x.startswith('sdns://'), lines)
)
)
return stamps
def get_not_china_doh_list():
stamps = get_stamps()
def is_match(s) -> bool:
if isinstance(s, DNSoverHTTPS) is False:
return False
if s.nofilter is False:
return False
if s.dnssec is False:
return False
return True
return list(filter(
is_match,
stamps
))
def get_smartdns_config():
stamps = get_not_china_doh_list()
lines = set(map(
lambda x: 'server-https https://' + x.hostname + x.path + ' -group GFW -exclude-default-group',
stamps
))
return '\n'.join(lines)
def write_smartdns_config():
conf_txt = get_smartdns_config()
with open(SMARTDNS_GFW_CONF_FILE, 'w') as f:
f.write(conf_txt)
def reload_openwrt_smartdns():
subprocess.run(["/etc/init.d/smartdns", "reload"])
def reload_pc_smartdns():
subprocess.run(["systemctl", "restart", "smartdns.service"])
def run_openwrt():
write_smartdns_config()
reload_openwrt_smartdns()
def run_pc():
write_smartdns_config()
reload_pc_smartdns()
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("where", choices=["openwrt", "pc"], help="运行环境openwrt 或 pc")
args = parser.parse_args()
if args.where == "openwrt":
run_openwrt()
elif args.where == "pc":
run_pc()