From b8e6a5475bab291e1d4df89a4ab3eaf27bdee0b0 Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Sat, 3 May 2025 21:49:26 +0330 Subject: [PATCH] refactor: masquerade management in Python3 --- core/cli_api.py | 6 +- core/scripts/hysteria2/masquerade.py | 93 ++++++++++++++++++++++++++++ core/scripts/hysteria2/masquerade.sh | 40 ------------ 3 files changed, 96 insertions(+), 43 deletions(-) create mode 100644 core/scripts/hysteria2/masquerade.py delete mode 100644 core/scripts/hysteria2/masquerade.sh diff --git a/core/cli_api.py b/core/cli_api.py index 9198aa4..a84262c 100644 --- a/core/cli_api.py +++ b/core/cli_api.py @@ -31,7 +31,7 @@ class Command(Enum): WRAPPER_URI = os.path.join(SCRIPT_DIR, 'hysteria2', 'wrapper_uri.py') IP_ADD = os.path.join(SCRIPT_DIR, 'hysteria2', 'ip.py') MANAGE_OBFS = os.path.join(SCRIPT_DIR, 'hysteria2', 'manage_obfs.py') - MASQUERADE_SCRIPT = os.path.join(SCRIPT_DIR, 'hysteria2', 'masquerade.sh') + MASQUERADE_SCRIPT = os.path.join(SCRIPT_DIR, 'hysteria2', 'masquerade.py') TRAFFIC_STATUS = 'traffic.py' # won't be called directly (it's a python module) UPDATE_GEO = os.path.join(SCRIPT_DIR, 'hysteria2', 'update_geo.py') LIST_USERS = os.path.join(SCRIPT_DIR, 'hysteria2', 'list_users.sh') @@ -211,12 +211,12 @@ def disable_hysteria2_obfs(): def enable_hysteria2_masquerade(domain: str): '''Enables masquerade for Hysteria2.''' - run_cmd(['bash', Command.MASQUERADE_SCRIPT.value, '1', domain]) + run_cmd(['python3', Command.MASQUERADE_SCRIPT.value, '1', domain]) def disable_hysteria2_masquerade(): '''Disables masquerade for Hysteria2.''' - run_cmd(['bash', Command.MASQUERADE_SCRIPT.value, '2']) + run_cmd(['python3', Command.MASQUERADE_SCRIPT.value, '2']) def get_hysteria2_config_file() -> dict[str, Any]: diff --git a/core/scripts/hysteria2/masquerade.py b/core/scripts/hysteria2/masquerade.py new file mode 100644 index 0000000..21155c0 --- /dev/null +++ b/core/scripts/hysteria2/masquerade.py @@ -0,0 +1,93 @@ +import json +import subprocess +import sys +from init_paths import * +from paths import * + + +def is_masquerade_enabled(): + try: + with open(CONFIG_FILE, 'r') as f: + config = json.load(f) + return "masquerade" in config + except Exception as e: + print(f"Error reading config: {e}") + return False + +def enable_masquerade(domain: str): + if is_masquerade_enabled(): + print("Masquerade is already enabled.") + sys.exit(0) + + url = f"https://{domain}" + try: + with open(CONFIG_FILE, 'r') as f: + config = json.load(f) + + config["masquerade"] = { + "type": "proxy", + "proxy": { + "url": url, + "rewriteHost": True + }, + "listenHTTP": ":80", + "listenHTTPS": ":443", + "forceHTTPS": True + } + + with open(CONFIG_FILE, 'w') as f: + json.dump(config, f, indent=2) + + print(f"Masquerade enabled with URL: {url}") + subprocess.run(["python3", CLI_PATH, "restart-hysteria2"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + + except Exception as e: + print(f"Failed to enable masquerade: {e}") + sys.exit(1) + +def remove_masquerade(): + if not is_masquerade_enabled(): + print("Masquerade is not enabled.") + sys.exit(0) + + try: + with open(CONFIG_FILE, 'r') as f: + config = json.load(f) + + config.pop("masquerade", None) + + with open(CONFIG_FILE, 'w') as f: + json.dump(config, f, indent=2) + + print("Masquerade removed from config.json") + subprocess.run(["python3", CLI_PATH, "restart-hysteria2"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + + except Exception as e: + print(f"Failed to remove masquerade: {e}") + sys.exit(1) + +def main(): + if len(sys.argv) < 2: + print("Usage: python3 masquerade.py {1|2} [domain]") + print("1: Enable Masquerade [domain]") + print("2: Remove Masquerade") + sys.exit(1) + + action = sys.argv[1] + + if action == "1": + if len(sys.argv) < 3: + print("Error: Missing domain argument for enabling masquerade.") + sys.exit(1) + domain = sys.argv[2] + print(f"Enabling 'masquerade' with URL: {domain}...") + enable_masquerade(domain) + elif action == "2": + print("Removing 'masquerade' from config.json...") + remove_masquerade() + else: + print("Invalid option. Use 1 to enable or 2 to disable masquerade.") + sys.exit(1) + +if __name__ == "__main__": + main() diff --git a/core/scripts/hysteria2/masquerade.sh b/core/scripts/hysteria2/masquerade.sh deleted file mode 100644 index d6ed54c..0000000 --- a/core/scripts/hysteria2/masquerade.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash -source /etc/hysteria/core/scripts/path.sh - -function is_masquerade_enabled() { - jq -e '.masquerade' $CONFIG_FILE > /dev/null 2>&1 -} - -function enable_masquerade() { - if is_masquerade_enabled; then - echo "Masquerade is already enabled." - exit 0 - fi - url="https://$1" - jq --arg url "$url" '. + {masquerade: {type: "proxy", proxy: {url: $url, rewriteHost: true}, listenHTTP: ":80", listenHTTPS: ":443", forceHTTPS: true}}' $CONFIG_FILE > tmp.json && mv tmp.json $CONFIG_FILE - echo "Masquerade enabled with URL: $url" - python3 "$CLI_PATH" restart-hysteria2 > /dev/null 2>&1 -} - -function remove_masquerade() { - if ! is_masquerade_enabled; then - echo "Masquerade is not enabled." - exit 0 - fi - jq 'del(.masquerade)' $CONFIG_FILE > tmp.json && mv tmp.json $CONFIG_FILE - echo "Masquerade removed from config.json" - python3 "$CLI_PATH" restart-hysteria2 > /dev/null 2>&1 -} - -if [[ "$1" == "1" ]]; then - echo "Enabling 'masquerade' with URL: $2..." - enable_masquerade "$2" -elif [[ "$1" == "2" ]]; then - echo "Removing 'masquerade' from config.json..." - remove_masquerade -else - echo "Usage: $0 {1|2} [domain]" - echo "1: Enable Masquerade [domain]" - echo "2: Remove Masquerade" - exit 1 -fi