diff --git a/code/default/launcher/config.py b/code/default/launcher/config.py index 473f9b2ca2..4d4472f64d 100644 --- a/code/default/launcher/config.py +++ b/code/default/launcher/config.py @@ -33,6 +33,7 @@ config.set_var("no_mess_system", 0) config.set_var("auto_start", 0) config.set_var("popup_webui", 1) +config.set_var("webui_auth", {}) config.set_var("gae_show_detail", 0) config.set_var("show_compat_suggest", 1) diff --git a/code/default/launcher/web_control.py b/code/default/launcher/web_control.py index 927a907b3c..71c549f730 100644 --- a/code/default/launcher/web_control.py +++ b/code/default/launcher/web_control.py @@ -10,8 +10,7 @@ import json import cgi import traceback -import zipfile -import operator +import base64 try: from urllib.parse import urlparse, urlencode, parse_qs @@ -176,7 +175,7 @@ def do_POST(self): xlog.info('%s "%s %s HTTP/1.1" 404 -', self.address_string(), self.command, self.path) def do_GET(self): - # self.headers = utils.to_str(self.headers) + self.headers = utils.to_str(self.headers) self.path = utils.to_str(self.path) refer = self.headers.get('Referer') @@ -193,6 +192,28 @@ def do_GET(self): xlog.warn('%s %s %s haking', self.address_string(), self.command, self.path) return + if config.webui_auth: + auth = self.headers.get("Authorization") + if not auth or not auth.startswith("Basic "): + return self.send_response(content="", headers={ + "WWW-Authenticate": 'Basic realm="Access to admin"' + }, status=401) + + try: + user_pass = base64.b64decode(auth[6:]) + user_pass = utils.to_str(user_pass) + user, password = user_pass.split(":")[0:2] + except Exception as e: + xlog.warn("decode auth fail:%r", e) + return self.send_response(content="", headers={ + "WWW-Authenticate": 'Basic realm="Access to admin"' + }, status=401) + + if config.webui_auth.get(user) != password: + return self.send_response(content="", headers={ + "WWW-Authenticate": 'Basic realm="Access to admin"' + }, status=401) + url_path = urlparse(self.path).path if url_path == '/': return self.req_index_handler() @@ -764,9 +785,10 @@ def req_get_installed_app(self): return self.send_response("text/html", content) def set_proxy_applist(self): + self.postvars = utils.to_str(self.postvars) xlog.debug("set_proxy_applist %r", self.postvars) - config.proxy_by_app = int(self.postvars.get(b'proxy_by_app') == [b"true"]) - config.enabled_app_list = utils.to_str(self.postvars.get(b"enabled_app_list[]", [])) + config.proxy_by_app = int(self.postvars.get('proxy_by_app') == "true") + config.enabled_app_list = self.postvars.get("enabled_app_list[]", []) xlog.debug("set_proxy_applist proxy_by_app:%s", config.proxy_by_app) xlog.debug("set_proxy_applist enabled_app_list:%s", config.enabled_app_list) config.save() diff --git a/code/default/smart_router/local/cn_ipv4_range.txt b/code/default/smart_router/local/cn_ipv4_range.txt index 0dfd53992e..0d138dc314 100644 --- a/code/default/smart_router/local/cn_ipv4_range.txt +++ b/code/default/smart_router/local/cn_ipv4_range.txt @@ -145,6 +145,8 @@ 36.37.48.0 4096 36.40.0.0 524288 36.48.0.0 131072 +36.50.226.0 512 +36.50.254.0 512 36.51.0.0 65536 36.56.0.0 524288 36.96.0.0 2097152 @@ -267,7 +269,9 @@ 43.136.0.0 524288 43.144.0.0 524288 43.176.0.0 1048576 -43.192.0.0 262144 +43.192.0.0 131072 +43.194.0.0 65536 +43.195.0.0 65536 43.196.0.0 131072 43.224.12.0 1024 43.224.24.0 1024 @@ -935,6 +939,7 @@ 43.250.168.0 1024 43.250.172.0 1024 43.250.176.0 1024 +43.250.180.0 512 43.250.200.0 1024 43.250.212.0 1024 43.250.216.0 1024 @@ -2017,7 +2022,7 @@ 103.11.168.0 1024 103.11.180.0 1024 103.12.32.0 1024 -103.12.68.0 1024 +103.12.68.0 512 103.12.92.0 1024 103.12.98.0 512 103.12.136.0 1024 @@ -2075,6 +2080,8 @@ 103.20.128.0 1024 103.20.160.0 1024 103.20.248.0 1024 +103.21.98.0 512 +103.21.102.0 512 103.21.112.0 1024 103.21.116.0 1024 103.21.136.0 1024 @@ -2507,6 +2514,7 @@ 103.40.88.0 1024 103.40.100.0 1024 103.40.158.0 512 +103.40.174.0 512 103.40.192.0 1024 103.40.212.0 1024 103.40.220.0 1024 @@ -3004,6 +3012,7 @@ 103.67.0.0 1024 103.67.4.0 1024 103.67.8.0 1024 +103.67.52.0 512 103.67.100.0 1024 103.67.104.0 1024 103.67.108.0 1024 @@ -3119,6 +3128,7 @@ 103.74.156.0 1024 103.74.204.0 1024 103.74.232.0 1024 +103.75.82.0 512 103.75.88.0 1024 103.75.92.0 1024 103.75.104.0 1024 @@ -3167,7 +3177,6 @@ 103.79.68.0 1024 103.79.80.0 1024 103.79.84.0 1024 -103.79.120.0 1024 103.79.136.0 1024 103.79.188.0 1024 103.79.192.0 1024 @@ -3281,7 +3290,6 @@ 103.88.72.0 1024 103.88.96.0 1024 103.88.164.0 1024 -103.88.176.0 1024 103.88.212.0 1024 103.89.28.0 1024 103.89.96.0 1024 @@ -3350,7 +3358,6 @@ 103.92.88.0 1024 103.92.108.0 1024 103.92.124.0 1024 -103.92.128.0 256 103.92.132.0 1024 103.92.156.0 1024 103.92.164.0 1024 @@ -3405,7 +3412,6 @@ 103.95.252.0 1024 103.96.0.0 1024 103.96.8.0 1024 -103.96.80.0 1024 103.96.124.0 1024 103.96.136.0 1024 103.96.140.0 256 @@ -3429,10 +3435,7 @@ 103.96.224.0 512 103.97.8.0 1024 103.97.12.0 1024 -103.97.16.0 1024 -103.97.20.0 1024 -103.97.24.0 1024 -103.97.28.0 1024 +103.97.16.0 4096 103.97.32.0 1024 103.97.36.0 1024 103.97.40.0 1024 @@ -3538,13 +3541,10 @@ 103.103.200.0 1024 103.103.204.0 1024 103.103.220.0 1024 -103.103.224.0 1024 -103.103.228.0 1024 +103.103.224.0 2048 103.103.232.0 1024 -103.103.248.0 1024 -103.103.252.0 1024 -103.104.0.0 1024 -103.104.4.0 1024 +103.103.248.0 2048 +103.104.0.0 2048 103.104.36.0 1024 103.104.40.0 1024 103.104.64.0 1024 @@ -3600,7 +3600,6 @@ 103.108.160.0 1024 103.108.164.0 1024 103.108.184.0 512 -103.108.188.0 512 103.108.192.0 1024 103.108.196.0 1024 103.108.208.0 1024 @@ -3612,7 +3611,6 @@ 103.109.88.0 1024 103.109.106.0 512 103.109.248.0 1024 -103.110.80.0 512 103.110.92.0 1024 103.110.116.0 1024 103.110.132.0 1024 @@ -3666,7 +3664,6 @@ 103.115.92.0 1024 103.115.120.0 1024 103.115.148.0 1024 -103.115.204.0 512 103.115.248.0 1024 103.116.40.0 1024 103.116.64.0 1024 @@ -3689,7 +3686,6 @@ 103.117.136.0 1024 103.117.188.0 1024 103.117.220.0 1024 -103.118.36.0 1024 103.118.52.0 1024 103.118.56.0 1024 103.118.60.0 1024 @@ -3714,7 +3710,6 @@ 103.119.12.0 1024 103.119.16.0 1024 103.119.28.0 1024 -103.119.44.0 1024 103.119.104.0 1024 103.119.115.0 256 103.119.156.0 1024 @@ -4041,6 +4036,7 @@ 103.158.0.0 512 103.158.8.0 512 103.158.16.0 512 +103.158.74.0 512 103.158.190.0 512 103.158.200.0 512 103.158.224.0 512 @@ -4087,7 +4083,6 @@ 103.166.84.0 512 103.166.138.0 512 103.166.242.0 512 -103.166.246.0 512 103.167.0.0 512 103.167.36.0 512 103.167.100.0 512 @@ -4476,10 +4471,9 @@ 103.210.216.0 1024 103.211.44.0 1024 103.211.96.0 1024 -103.211.100.0 1024 103.211.156.0 1024 103.211.164.0 1024 -103.211.192.0 1024 +103.211.194.0 512 103.211.220.0 1024 103.211.224.0 1024 103.211.248.0 1024 @@ -4562,6 +4556,7 @@ 103.216.108.0 1024 103.216.136.0 1024 103.216.152.0 1024 +103.216.156.0 512 103.216.224.0 1024 103.216.228.0 1024 103.216.240.0 1024 @@ -4613,6 +4608,7 @@ 103.218.84.0 1024 103.218.88.0 1024 103.218.92.0 1024 +103.218.178.0 512 103.218.192.0 1024 103.218.196.0 1024 103.218.200.0 1024 @@ -4969,6 +4965,7 @@ 103.236.88.0 1024 103.236.92.0 1024 103.236.96.0 1024 +103.236.116.0 512 103.236.120.0 1024 103.236.184.0 1024 103.236.220.0 1024 @@ -5071,7 +5068,6 @@ 103.241.184.0 1024 103.241.188.0 1024 103.241.220.0 1024 -103.242.12.0 1024 103.242.64.0 1024 103.242.128.0 1024 103.242.132.0 1024 @@ -5086,6 +5082,7 @@ 103.243.136.0 1024 103.243.252.0 1024 103.244.16.0 1024 +103.244.26.0 512 103.244.58.0 512 103.244.60.0 1024 103.244.64.0 1024 @@ -5099,6 +5096,7 @@ 103.244.232.0 1024 103.244.252.0 1024 103.245.23.0 256 +103.245.24.0 512 103.245.52.0 1024 103.245.60.0 1024 103.245.80.0 1024 @@ -5195,6 +5193,7 @@ 103.255.140.0 1024 103.255.184.0 1024 103.255.200.0 1024 +103.255.208.0 512 103.255.212.0 1024 103.255.228.0 1024 106.0.0.0 256 @@ -5362,6 +5361,8 @@ 113.130.112.0 2048 113.132.0.0 262144 113.136.0.0 524288 +113.192.40.0 512 +113.192.56.0 512 113.194.0.0 131072 113.197.100.0 1024 113.200.0.0 131072 @@ -5516,7 +5517,6 @@ 116.204.0.0 32768 116.204.132.0 1024 116.204.216.0 1024 -116.204.232.0 1024 116.205.0.0 65536 116.207.0.0 65536 116.208.0.0 262144 @@ -5925,6 +5925,7 @@ 123.100.0.0 8192 123.101.0.0 65536 123.103.0.0 32768 +123.108.88.0 512 123.108.128.0 4096 123.108.208.0 4096 123.112.0.0 1048576 @@ -6209,6 +6210,20 @@ 153.118.0.0 131072 154.8.128.0 32768 157.0.0.0 65536 +157.10.34.0 512 +157.10.36.0 512 +157.10.112.0 512 +157.10.118.0 512 +157.10.130.0 512 +157.10.218.0 512 +157.10.220.0 512 +157.10.246.0 512 +157.15.74.0 512 +157.15.94.0 512 +157.15.100.0 512 +157.15.102.0 512 +157.15.104.0 512 +157.15.200.0 512 157.18.0.0 65536 157.61.0.0 65536 157.119.8.0 1024 @@ -6257,7 +6272,6 @@ 160.202.244.0 1024 160.202.248.0 1024 160.202.252.0 1024 -160.238.64.0 1024 161.120.0.0 65536 161.189.0.0 65536 161.207.0.0 65536 @@ -6295,7 +6309,6 @@ 163.53.168.0 1024 163.53.172.0 1024 163.53.188.0 1024 -163.53.220.0 1024 163.53.240.0 1024 163.125.0.0 65536 163.142.0.0 65536 @@ -6536,7 +6549,6 @@ 202.12.2.0 256 202.12.17.0 256 202.12.18.0 256 -202.12.19.0 256 202.12.72.0 256 202.12.84.0 512 202.12.96.0 256 @@ -6629,7 +6641,6 @@ 202.38.134.0 256 202.38.135.0 256 202.38.136.0 512 -202.38.138.0 256 202.38.140.0 512 202.38.142.0 512 202.38.146.0 512 @@ -6639,11 +6650,9 @@ 202.38.154.0 512 202.38.156.0 256 202.38.158.0 512 -202.38.160.0 512 202.38.164.0 1024 202.38.168.0 512 202.38.170.0 256 -202.38.171.0 256 202.38.176.0 512 202.38.184.0 2048 202.38.192.0 16384 @@ -6824,9 +6833,7 @@ 202.90.224.0 2048 202.90.232.0 2048 202.91.0.0 1024 -202.91.36.0 1024 202.91.96.0 4096 -202.91.128.0 1024 202.91.176.0 4096 202.91.224.0 8192 202.92.8.0 2048 @@ -7016,7 +7023,6 @@ 202.122.64.0 8192 202.122.112.0 2048 202.122.120.0 2048 -202.122.128.0 256 202.122.132.0 256 202.123.96.0 4096 202.123.116.0 1024 @@ -7044,7 +7050,6 @@ 202.127.194.0 512 202.127.196.0 1024 202.127.200.0 2048 -202.127.208.0 256 202.127.212.0 1024 202.127.216.0 2048 202.127.224.0 8192 @@ -7082,6 +7087,7 @@ 202.143.104.0 1024 202.144.196.0 1024 202.146.160.0 4096 +202.146.184.0 512 202.146.186.0 256 202.146.188.0 1024 202.146.196.0 1024 @@ -8014,7 +8020,6 @@ 203.89.133.0 256 203.89.136.0 1024 203.89.144.0 256 -203.90.0.0 1024 203.90.8.0 1024 203.90.12.0 1024 203.90.128.0 8192 @@ -8184,8 +8189,6 @@ 203.207.200.0 2048 203.207.208.0 4096 203.207.224.0 8192 -203.208.0.0 4096 -203.208.16.0 1024 203.208.32.0 8192 203.209.224.0 8192 203.212.0.0 4096 @@ -8279,6 +8282,8 @@ 210.79.64.0 16384 210.79.224.0 8192 210.82.0.0 131072 +210.87.72.0 512 +210.87.114.0 512 210.87.128.0 4096 210.87.144.0 4096 210.87.160.0 8192 @@ -8632,7 +8637,6 @@ 223.116.0.0 131072 223.120.128.0 32768 223.121.128.0 32768 -223.122.128.0 32768 223.123.128.0 32768 223.124.0.0 262144 223.128.0.0 131072 @@ -8647,7 +8651,8 @@ 223.212.0.0 131072 223.214.0.0 131072 223.220.0.0 131072 -223.223.176.0 4096 +223.223.176.0 2048 +223.223.184.0 2048 223.223.192.0 4096 223.240.0.0 524288 223.248.0.0 262144 diff --git a/code/default/smart_router/local/dns_query.py b/code/default/smart_router/local/dns_query.py index 26256e7d6e..c2645f722d 100644 --- a/code/default/smart_router/local/dns_query.py +++ b/code/default/smart_router/local/dns_query.py @@ -179,13 +179,24 @@ def get_local_dns_server(self): xlog.warn("load /etc/resolv.conf fail:%r", e) if not iplist: - iplist = [ - b"1.1.1.1", - b"8.8.8.8", - b"9.9.9.9", - b"208.67.222.222", - b"168.126.63.2" - ] + if g.config.country_code == "CN": + iplist = [ + b"114.114.114.114", + b"114.114.115.115", + b"119.29.29.29", + b"182.254.118.118", + b"223.5.5.5", + b"223.6.6.6", + b"180.76.76.76" + ] + else: + iplist = [ + b"1.1.1.1", + b"8.8.8.8", + b"9.9.9.9", + b"208.67.222.222", + b"168.126.63.2" + ] out_list = [] for ip in iplist: @@ -258,7 +269,24 @@ def send_request(self, id, server_ip, domain, dns_type): except Exception as e: xlog.warn("send_request except:%r", e) + def query_by_system(self, domain, dns_type): + ips = [] + try: + t0 = time.time() + ip = socket.gethostbyname(domain) + t1 = time.time() + ips.append(ip) + + xlog.debug("query_by_system, %s %d cost:%f, return:%s", domain, dns_type, t1 - t0, ips) + except Exception as e: + xlog.warn("query_by_system %s %d e:%r", domain, dns_type, e) + + return ips + def query(self, domain, dns_type=1, timeout=3): + if sys.platform == "ios": + return self.query_by_system(domain, dns_type) + t0 = time.time() end_time = t0 + timeout while True: @@ -453,7 +481,8 @@ class DnsOverHttpsQuery(object): def __init__(self, timeout=6): self.protocol = "DoH" self.timeout = timeout - self.server = "https://1.1.1.1/dns-query" + self.cn_servers = ["https://1.12.12.12/dns-query", "https://223.5.5.5/dns-query"] + self.other_servers = ["https://1.1.1.1/dns-query"] self.connection_timeout = 60 self.connections = [] @@ -477,6 +506,13 @@ def get_connection(self): else: return simple_http_client.Client(timeout=self.timeout) + @property + def server(self): + if g.config.country_code == "CN": + return random.choice(self.cn_servers) + else: + return random.choice(self.other_servers) + def query_json(self, domain, dns_type=1): try: t0 = time.time() diff --git a/code/default/smart_router/local/gfwlist.py b/code/default/smart_router/local/gfwlist.py index 667693d8ed..b1fbe097cc 100644 --- a/code/default/smart_router/local/gfwlist.py +++ b/code/default/smart_router/local/gfwlist.py @@ -5,6 +5,9 @@ import os import sys import base64 +import re +import socket +import struct try: from urllib.request import urlopen except ImportError: @@ -27,9 +30,52 @@ data_path = os.path.join(env_info.data_path, "smart_router") +class IpMask(object): + def __init__(self, ip_masks): + self.masks = self.generate_masks(ip_masks) + + def makeMask(self, n): + # return a mask of n bits as a long integer + return (2 << int(n) - 1) - 1 + + def dottedQuadToNum(self, ip): + # convert decimal dotted quad string to long integer + try: + i = socket.inet_aton(ip) + except Exception as e: + xlog.exception("inet_aton e:%r", e) + + return struct.unpack('I', i)[0] + + def networkMask(self, ip, bits): + # Convert a network address to a long integer + return self.dottedQuadToNum(ip) & self.makeMask(bits) + + def generate_masks(self, ip_masks): + masks = [] + for ip_mask in ip_masks: + ip, m = ip_mask.split("/") + mask = self.networkMask(ip, m) + masks.append(mask) + + return tuple(masks) + + def check_ip(self, ip): + address = self.dottedQuadToNum(ip) + for mask in self.masks: + if address & mask == mask: + return True + + return False + + class GfwList(object): def __init__(self): - self.gfw_black_list = utils.to_bytes(self.load("gfw_black_list.txt")) + # self.gfw_black_list = utils.to_bytes(self.load("gfw_black_list.txt")) + # https://johnshall.github.io/Shadowrocket-ADBlock-Rules-Forever/sr_top500_banlist.conf + self.gfw_black_list, ip_masks, keywords = self.load_banlist("sr_top500_banlist.conf") + self.keyword_re = re.compile("|".join(keywords)) + self.black_subnets = IpMask(ip_masks) self.gfw_white_list = utils.to_bytes(self.load("gfw_white_list.txt")) self.speedtest_whitelist = utils.to_bytes(self.load("speedtest_whitelist.txt")) self.advertisement_list = utils.to_bytes(self.load("advertisement_list.txt")) @@ -46,24 +92,56 @@ def load(name): xlog.info("Load file:%s", list_file) - fd = open(list_file, "r") - gfwdict = {} - for line in fd.readlines(): - line = line.strip() - if not line: - continue + with open(list_file, "r") as fd: + gfwdict = {} + for line in fd.readlines(): + line = line.strip() + if not line: + continue - gfwdict["." + line] = 1 + gfwdict["." + line] = 1 gfwlist = [h for h in gfwdict] return tuple(gfwlist) + def load_banlist(self, fn): + gfwdict = {} + ip_masks = [] + keywords = [] + list_file = os.path.join(current_path, fn) + with open(list_file, "r") as fd: + for line in fd.readlines(): + line = line.strip() + if not line or line.startswith("#") or line.startswith("["): + continue + + if line.startswith("DOMAIN-SUFFIX,"): + suffix = line.split(",")[1] + gfwdict["." + suffix] = 1 + + if line.startswith("IP-CIDR,"): + ip_mask = line.split(",")[1] + if ":" not in ip_mask: + ip_masks.append(ip_mask) + + if line.startswith("DOMAIN-KEYWORD,"): + keyword = line.split(",")[1] + keywords.append(keyword) + + gfwlist = [h for h in gfwdict] + return tuple(utils.to_bytes(gfwlist)), ip_masks, keywords + + def ip_in_black_list(self, ip): + return self.black_subnets.check_ip(ip) + def in_block_list(self, host): - dot_host = b"." + host + dot_host = b"." + utils.to_bytes(host) if dot_host.endswith(self.gfw_black_list): return True - - return False + elif self.keyword_re.search(utils.to_str(host)): + return True + else: + return False def in_white_list(self, host): dot_host = b"." + host diff --git a/code/default/smart_router/local/smart_route.py b/code/default/smart_router/local/smart_route.py index 816b2d9883..75224bead7 100644 --- a/code/default/smart_router/local/smart_route.py +++ b/code/default/smart_router/local/smart_route.py @@ -513,8 +513,10 @@ def handle_ip_proxy(sock, ip, port, client_address): elif g.ip_region.check_ip(ip): # China IP rule_list = ["direct", "socks"] + elif g.gfwlist.in_block_list(ip): + rule_list = ["gae", "socks"] else: - rule_list = ["gae", "socks", "direct"] + rule_list = ["direct", "gae", "socks", ] if not g.config.auto_direct: for rule in ["direct", "redirect_https"]: diff --git a/code/default/version.txt b/code/default/version.txt index cf51361190..2054231b6a 100644 --- a/code/default/version.txt +++ b/code/default/version.txt @@ -1 +1 @@ -5.9.0 \ No newline at end of file +5.9.7 \ No newline at end of file diff --git a/code/default/x_tunnel/local/config.py b/code/default/x_tunnel/local/config.py index d4723ba43c..a8b053e43f 100644 --- a/code/default/x_tunnel/local/config.py +++ b/code/default/x_tunnel/local/config.py @@ -92,8 +92,8 @@ def load_config(): if "localhost" in config.server_host or "127.0.0.1" in config.server_host: config.enable_cloudflare = 0 config.enable_tls_relay = 0 - config.enable_seley = 1 - config.enable_direct = 0 + config.enable_seley = 0 + config.enable_direct = 1 xlog.info("Only enable Direct front for localhost") if config.write_log_file: