diff --git a/config.py b/config.py index 23297f2..966aa10 100644 --- a/config.py +++ b/config.py @@ -8,3 +8,7 @@ # Tag for advertising, obtainable from @MTProxybot # AD_TAG = "3c09c680b76ee91a4c25ad51f742267d" + +# Uncommenting this do make a proxy harder to detect +# But it can be incompatible with old clients +# SECURE_ONLY = True diff --git a/mtprotoproxy.py b/mtprotoproxy.py index 1d83cb5..2787d51 100755 --- a/mtprotoproxy.py +++ b/mtprotoproxy.py @@ -144,17 +144,32 @@ def debug_signal(signum, frame): AD_TAG = bytes.fromhex(config.get("AD_TAG", "")) # load advanced settings +# if IPv6 avaliable, use it by default PREFER_IPV6 = config.get("PREFER_IPV6", socket.has_ipv6) # disables tg->client trafic reencryption, faster but less secure FAST_MODE = config.get("FAST_MODE", True) +# doesn't allow to connect in not-secure mode +SECURE_ONLY = config.get("SECURE_ONLY", False) +# delay in seconds between stats printing STATS_PRINT_PERIOD = config.get("STATS_PRINT_PERIOD", 600) +# delay in seconds between middle proxy info updates PROXY_INFO_UPDATE_PERIOD = config.get("PROXY_INFO_UPDATE_PERIOD", 24*60*60) +# max socket buffer size to the client direction, the more the faster, but more RAM hungry TO_CLT_BUFSIZE = config.get("TO_CLT_BUFSIZE", 16384) +# max socket buffer size to the telegram servers direction TO_TG_BUFSIZE = config.get("TO_TG_BUFSIZE", 65536) +# keepalive period for clients in secs CLIENT_KEEPALIVE = config.get("CLIENT_KEEPALIVE", 10*60) +# drop client after this timeout if the handshake fail CLIENT_HANDSHAKE_TIMEOUT = config.get("CLIENT_HANDSHAKE_TIMEOUT", 10) +# if client doesn't confirm data for this number of seconds, it is dropped CLIENT_ACK_TIMEOUT = config.get("CLIENT_ACK_TIMEOUT", 5*60) +# telegram servers connect timeout in seconds TG_CONNECT_TIMEOUT = config.get("TG_CONNECT_TIMEOUT", 10) +# listen address for IPv4 +LISTEN_ADDR_IPV4 = config.get("LISTEN_ADDR_IPV4", "0.0.0.0") +# listen address for IPv6 +LISTEN_ADDR_IPV6 = config.get("LISTEN_ADDR_IPV6", "::") TG_DATACENTER_PORT = 443 @@ -588,6 +603,9 @@ async def handle_handshake(reader, writer): if proto_tag not in (PROTO_TAG_ABRIDGED, PROTO_TAG_INTERMEDIATE, PROTO_TAG_SECURE): continue + if SECURE_ONLY and proto_tag != PROTO_TAG_SECURE: + continue + dc_idx = int.from_bytes(decrypted[DC_IDX_POS:DC_IDX_POS+2], "little", signed=True) reader = CryptoWrappedStreamReader(reader, decryptor) @@ -1097,13 +1115,14 @@ def print_tg_info(): for user, secret in sorted(USERS.items(), key=lambda x: x[0]): for ip in ip_addrs: - params = {"server": ip, "port": PORT, "secret": secret} - params_encodeded = urllib.parse.urlencode(params, safe=':') - print("{}: tg://proxy?{}".format(user, params_encodeded), flush=True) + if not SECURE_ONLY: + params = {"server": ip, "port": PORT, "secret": secret} + params_encodeded = urllib.parse.urlencode(params, safe=':') + print("{}: tg://proxy?{}".format(user, params_encodeded), flush=True) params = {"server": ip, "port": PORT, "secret": "dd" + secret} params_encodeded = urllib.parse.urlencode(params, safe=':') - print("{}: tg://proxy?{} (beta)".format(user, params_encodeded), flush=True) + print("{}: tg://proxy?{}".format(user, params_encodeded), flush=True) def loop_exception_handler(loop, context): @@ -1153,12 +1172,12 @@ def main(): reuse_port = hasattr(socket, "SO_REUSEPORT") - task_v4 = asyncio.start_server(handle_client_wrapper, '0.0.0.0', PORT, + task_v4 = asyncio.start_server(handle_client_wrapper, LISTEN_ADDR_IPV4, PORT, limit=TO_TG_BUFSIZE, reuse_port=reuse_port, loop=loop) server_v4 = loop.run_until_complete(task_v4) if socket.has_ipv6: - task_v6 = asyncio.start_server(handle_client_wrapper, '::', PORT, + task_v6 = asyncio.start_server(handle_client_wrapper, LISTEN_ADDR_IPV6, PORT, limit=TO_TG_BUFSIZE, reuse_port=reuse_port, loop=loop) server_v6 = loop.run_until_complete(task_v6)