From 9d0a13a226d5bcefcb900c93540cbb5303aaa97e Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Fri, 2 May 2025 18:24:58 +0330 Subject: [PATCH] Refactor: Implement WARP ACL configuration in Python - remove WARP Plus/Key --- core/cli.py | 7 +- core/cli_api.py | 32 ++-- core/scripts/warp/configure.py | 159 ++++++++++++++++++ core/scripts/warp/configure.sh | 78 --------- .../webpanel/routers/api/v1/config/warp.py | 2 +- .../routers/api/v1/schema/config/warp.py | 2 - menu.sh | 20 +-- 7 files changed, 178 insertions(+), 122 deletions(-) create mode 100644 core/scripts/warp/configure.py delete mode 100644 core/scripts/warp/configure.sh diff --git a/core/cli.py b/core/cli.py index 3440a0d..ea964d1 100644 --- a/core/cli.py +++ b/core/cli.py @@ -365,16 +365,13 @@ def uninstall_warp(): @click.option('--popular-sites', '-p', is_flag=True, help='Use WARP for popular sites like Google, OpenAI, etc') @click.option('--domestic-sites', '-d', is_flag=True, help='Use WARP for Iran domestic sites') @click.option('--block-adult-sites', '-x', is_flag=True, help='Block adult content (porn)') -@click.option('--warp-option', '-w', type=click.Choice(['warp', 'warp plus'], case_sensitive=False), help='Specify whether to use WARP or WARP Plus') -@click.option('--warp-key', '-k', help="WARP Plus key (required if warp-option is 'warp plus')") -def configure_warp(all: bool, popular_sites: bool, domestic_sites: bool, block_adult_sites: bool, warp_option: str, warp_key: str): +def configure_warp(all: bool, popular_sites: bool, domestic_sites: bool, block_adult_sites: bool): try: - cli_api.configure_warp(all, popular_sites, domestic_sites, block_adult_sites, warp_option, warp_key) + cli_api.configure_warp(all, popular_sites, domestic_sites, block_adult_sites) click.echo('WARP configured successfully.') except Exception as e: click.echo(f'{e}', err=True) - @cli.command('warp-status') def warp_status(): try: diff --git a/core/cli_api.py b/core/cli_api.py index 3a0ae5e..dbf92d4 100644 --- a/core/cli_api.py +++ b/core/cli_api.py @@ -45,7 +45,7 @@ class Command(Enum): INSTALL_TCP_BRUTAL = os.path.join(SCRIPT_DIR, 'tcp-brutal', 'install.sh') INSTALL_WARP = os.path.join(SCRIPT_DIR, 'warp', 'install.py') UNINSTALL_WARP = os.path.join(SCRIPT_DIR, 'warp', 'uninstall.py') - CONFIGURE_WARP = os.path.join(SCRIPT_DIR, 'warp', 'configure.sh') + CONFIGURE_WARP = os.path.join(SCRIPT_DIR, 'warp', 'configure.py') STATUS_WARP = os.path.join(SCRIPT_DIR, 'warp', 'status.py') SERVICES_STATUS = os.path.join(SCRIPT_DIR, 'services_status.sh') VERSION = os.path.join(SCRIPT_DIR, 'hysteria2', 'version.py') @@ -442,30 +442,22 @@ def uninstall_warp(): run_cmd(['python3', Command.UNINSTALL_WARP.value]) -def configure_warp(all: bool, popular_sites: bool, domestic_sites: bool, block_adult_sites: bool, warp_option: str, warp_key: str): +def configure_warp(all: bool, popular_sites: bool, domestic_sites: bool, block_adult_sites: bool): ''' Configures WARP with various options. ''' - if warp_option == 'warp plus' and not warp_key: - raise InvalidInputError('Error: WARP Plus key is required when \'warp plus\' is selected.') - options = { - 'all': 'true' if all else 'false', - 'popular_sites': 'true' if popular_sites else 'false', - 'domestic_sites': 'true' if domestic_sites else 'false', - 'block_adult_sites': 'true' if block_adult_sites else 'false', - 'warp_option': warp_option or '', - 'warp_key': warp_key or '' - } cmd_args = [ - 'bash', Command.CONFIGURE_WARP.value, - options['all'], - options['popular_sites'], - options['domestic_sites'], - options['block_adult_sites'], - options['warp_option'] + 'python3', Command.CONFIGURE_WARP.value ] - if options['warp_key']: - cmd_args.append(options['warp_key']) + if all: + cmd_args.append('--all') + if popular_sites: + cmd_args.append('--popular-sites') + if domestic_sites: + cmd_args.append('--domestic-sites') + if block_adult_sites: + cmd_args.append('--block-adult') + run_cmd(cmd_args) diff --git a/core/scripts/warp/configure.py b/core/scripts/warp/configure.py new file mode 100644 index 0000000..6f448aa --- /dev/null +++ b/core/scripts/warp/configure.py @@ -0,0 +1,159 @@ +#!/usr/bin/env python3 + +import json +import sys +import subprocess +from pathlib import Path + +core_scripts_dir = Path(__file__).resolve().parents[1] +if str(core_scripts_dir) not in sys.path: + sys.path.append(str(core_scripts_dir)) + +from paths import * + +def warp_configure_handler(all_traffic=False, popular_sites=False, domestic_sites=False, block_adult_sites=False): + """ + Configure WARP routing rules based on provided parameters + + Args: + all_traffic (bool): Toggle WARP for all traffic + popular_sites (bool): Toggle WARP for popular sites (Google, Netflix, etc.) + domestic_sites (bool): Toggle between WARP and Reject for domestic sites + block_adult_sites (bool): Toggle blocking of adult content + """ + with open(CONFIG_FILE, 'r') as f: + config = json.load(f) + + modified = False + + if all_traffic: + warp_all_active = any(rule == "warps(all)" for rule in config.get('acl', {}).get('inline', [])) + + if warp_all_active: + config['acl']['inline'] = [rule for rule in config['acl']['inline'] if rule != "warps(all)"] + print("Traffic configuration changed to Direct.") + modified = True + else: + if 'acl' not in config: + config['acl'] = {} + if 'inline' not in config['acl']: + config['acl']['inline'] = [] + config['acl']['inline'].append("warps(all)") + print("Traffic configuration changed to WARP.") + modified = True + + if popular_sites: + popular_rules = [ + "warps(geoip:google)", + "warps(geosite:google)", + "warps(geosite:netflix)", + "warps(geosite:spotify)", + "warps(geosite:openai)", + "warps(geoip:openai)" + ] + + rule_exists = any(rule in config.get('acl', {}).get('inline', []) for rule in popular_rules) + + if rule_exists: + config['acl']['inline'] = [rule for rule in config['acl']['inline'] + if rule not in popular_rules] + print("WARP configuration for Google, OpenAI, etc. removed.") + modified = True + else: + if 'acl' not in config: + config['acl'] = {} + if 'inline' not in config['acl']: + config['acl']['inline'] = [] + config['acl']['inline'].extend(popular_rules) + print("WARP configured for Google, OpenAI, etc.") + modified = True + + if domestic_sites: + ir_site_rule = "warps(geosite:ir)" + ir_ip_rule = "warps(geoip:ir)" + reject_site_rule = "reject(geosite:ir)" + reject_ip_rule = "reject(geoip:ir)" + + using_warp = (ir_site_rule in config.get('acl', {}).get('inline', []) and + ir_ip_rule in config.get('acl', {}).get('inline', [])) + using_reject = (reject_site_rule in config.get('acl', {}).get('inline', []) and + reject_ip_rule in config.get('acl', {}).get('inline', [])) + + if 'acl' not in config: + config['acl'] = {} + if 'inline' not in config['acl']: + config['acl']['inline'] = [] + + if using_warp: + config['acl']['inline'] = [reject_site_rule if rule == ir_site_rule else + reject_ip_rule if rule == ir_ip_rule else + rule for rule in config['acl']['inline']] + print("Configuration changed to Reject for geosite:ir and geoip:ir.") + modified = True + elif using_reject: + config['acl']['inline'] = [ir_site_rule if rule == reject_site_rule else + ir_ip_rule if rule == reject_ip_rule else + rule for rule in config['acl']['inline']] + print("Configuration changed to Use WARP for geosite:ir and geoip:ir.") + modified = True + else: + config['acl']['inline'].extend([reject_site_rule, reject_ip_rule]) + print("Added Reject configuration for geosite:ir and geoip:ir.") + modified = True + + if block_adult_sites: + nsfw_rule = "reject(geosite:nsfw)" + + blocked = nsfw_rule in config.get('acl', {}).get('inline', []) + + if blocked: + config['acl']['inline'] = [rule for rule in config['acl']['inline'] + if rule != nsfw_rule] + if 'resolver' not in config: + config['resolver'] = {} + if 'tls' not in config['resolver']: + config['resolver']['tls'] = {} + config['resolver']['tls']['addr'] = "1.1.1.1:853" + print("Adult content blocking removed and resolver updated.") + modified = True + else: + if 'acl' not in config: + config['acl'] = {} + if 'inline' not in config['acl']: + config['acl']['inline'] = [] + config['acl']['inline'].append(nsfw_rule) + if 'resolver' not in config: + config['resolver'] = {} + if 'tls' not in config['resolver']: + config['resolver']['tls'] = {} + config['resolver']['tls']['addr'] = "1.1.1.3:853" + print("Adult content blocked and resolver updated.") + modified = True + + if modified: + with open(CONFIG_FILE, 'w') as f: + json.dump(config, f, indent=2) + + try: + subprocess.run(["python3", CLI_PATH, "restart-hysteria2"], + stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True) + except subprocess.CalledProcessError: + print("Warning: Failed to restart hysteria2") + +if __name__ == "__main__": + import argparse + + parser = argparse.ArgumentParser(description="Configure WARP settings") + parser.add_argument("--all", action="store_true", help="Toggle WARP for all traffic") + parser.add_argument("--popular-sites", action="store_true", help="Toggle WARP for popular sites") + parser.add_argument("--domestic-sites", action="store_true", help="Toggle between WARP and Reject for domestic sites") + parser.add_argument("--block-adult", action="store_true", help="Toggle blocking of adult content") + + args = parser.parse_args() + + warp_configure_handler( + all_traffic=args.all, + popular_sites=args.popular_sites, + domestic_sites=args.domestic_sites, + block_adult_sites=args.block_adult + ) \ No newline at end of file diff --git a/core/scripts/warp/configure.sh b/core/scripts/warp/configure.sh deleted file mode 100644 index 80f8299..0000000 --- a/core/scripts/warp/configure.sh +++ /dev/null @@ -1,78 +0,0 @@ -#!/bin/bash - -source /etc/hysteria/core/scripts/path.sh - -warp_configure_handler() { - local all=$1 - local popular_sites=$2 - local domestic_sites=$3 - local block_adult_sites=$4 - local warp_option=$5 - local warp_key=$6 - - if [ "$all" == "true" ]; then - if [ "$(jq -r 'if .acl.inline | index("warps(all)") then "WARP active" else "Direct" end' "$CONFIG_FILE")" == "WARP active" ]; then - jq 'del(.acl.inline[] | select(. == "warps(all)"))' "$CONFIG_FILE" > "${CONFIG_FILE}.temp" && mv "${CONFIG_FILE}.temp" "$CONFIG_FILE" - echo "Traffic configuration changed to Direct." - else - jq '.acl.inline += ["warps(all)"]' "$CONFIG_FILE" > "${CONFIG_FILE}.temp" && mv "${CONFIG_FILE}.temp" "$CONFIG_FILE" - echo "Traffic configuration changed to WARP." - fi - fi - - if [ "$popular_sites" == "true" ]; then - if [ "$(jq -r 'if (.acl.inline | index("warps(geoip:google)")) or (.acl.inline | index("warps(geosite:google)")) or (.acl.inline | index("warps(geosite:netflix)")) or (.acl.inline | index("warps(geosite:spotify)")) or (.acl.inline | index("warps(geosite:openai)")) or (.acl.inline | index("warps(geoip:openai)")) then "WARP active" else "Direct" end' "$CONFIG_FILE")" == "WARP active" ]; then - jq 'del(.acl.inline[] | select(. == "warps(geoip:google)" or . == "warps(geosite:google)" or . == "warps(geosite:netflix)" or . == "warps(geosite:spotify)" or . == "warps(geosite:openai)" or . == "warps(geoip:openai)"))' "$CONFIG_FILE" > "${CONFIG_FILE}.temp" && mv "${CONFIG_FILE}.temp" "$CONFIG_FILE" - echo "WARP configuration for Google, OpenAI, etc. removed." - else - jq '.acl.inline += ["warps(geoip:google)", "warps(geosite:google)", "warps(geosite:netflix)", "warps(geosite:spotify)", "warps(geosite:openai)", "warps(geoip:openai)"]' "$CONFIG_FILE" > "${CONFIG_FILE}.temp" && mv "${CONFIG_FILE}.temp" "$CONFIG_FILE" - echo "WARP configured for Google, OpenAI, etc." - fi - fi - - if [ "$domestic_sites" == "true" ]; then - if [ "$(jq -r 'if (.acl.inline | index("warps(geosite:ir)")) and (.acl.inline | index("warps(geoip:ir)")) then "Use WARP" else "Reject" end' "$CONFIG_FILE")" == "Use WARP" ]; then - jq '(.acl.inline[] | select(. == "warps(geosite:ir)")) = "reject(geosite:ir)" | (.acl.inline[] | select(. == "warps(geoip:ir)")) = "reject(geoip:ir)"' "$CONFIG_FILE" > "${CONFIG_FILE}.temp" && mv "${CONFIG_FILE}.temp" "$CONFIG_FILE" - echo "Configuration changed to Reject for geosite:ir and geoip:ir." - else - jq '(.acl.inline[] | select(. == "reject(geosite:ir)")) = "warps(geosite:ir)" | (.acl.inline[] | select(. == "reject(geoip:ir)")) = "warps(geoip:ir)"' "$CONFIG_FILE" > "${CONFIG_FILE}.temp" && mv "${CONFIG_FILE}.temp" "$CONFIG_FILE" - echo "Configuration changed to Use WARP for geosite:ir and geoip:ir." - fi - fi - - if [ "$block_adult_sites" == "true" ]; then - if [ "$(jq -r 'if .acl.inline | index("reject(geosite:nsfw)") then "Blocked" else "Not blocked" end' "$CONFIG_FILE")" == "Blocked" ]; then - jq 'del(.acl.inline[] | select(. == "reject(geosite:nsfw)"))' "$CONFIG_FILE" > "${CONFIG_FILE}.temp" && mv "${CONFIG_FILE}.temp" "$CONFIG_FILE" - jq '.resolver.tls.addr = "1.1.1.1:853"' "$CONFIG_FILE" > "${CONFIG_FILE}.temp" && mv "${CONFIG_FILE}.temp" "$CONFIG_FILE" - echo "Adult content blocking removed and resolver updated." - else - jq '.acl.inline += ["reject(geosite:nsfw)"]' "$CONFIG_FILE" > "${CONFIG_FILE}.temp" && mv "${CONFIG_FILE}.temp" "$CONFIG_FILE" - jq '.resolver.tls.addr = "1.1.1.3:853"' "$CONFIG_FILE" > "${CONFIG_FILE}.temp" && mv "${CONFIG_FILE}.temp" "$CONFIG_FILE" - echo "Adult content blocked and resolver updated." - fi - fi - - if [ "$warp_option" == "warp plus" ]; then - if [ -z "$warp_key" ]; then - echo "Error: WARP Plus key is required. Exiting." - exit 1 - fi - cd /etc/warp/ || { echo "Failed to change directory to /etc/warp/"; exit 1; } - - WGCF_LICENSE_KEY="$warp_key" wgcf update - - if [ $? -ne 0 ]; then - echo "Error: Failed to update WARP Plus configuration." - exit 1 - fi - - elif [ "$warp_option" == "warp" ]; then - cd /etc/warp/ || { echo "Failed to change directory to /etc/warp/"; exit 1; } - rm wgcf-account.toml && yes | wgcf register - echo "WARP configured with a new account." - fi - - python3 "$CLI_PATH" restart-hysteria2 > /dev/null 2>&1 -} - -warp_configure_handler "$1" "$2" "$3" "$4" "$5" "$6" diff --git a/core/scripts/webpanel/routers/api/v1/config/warp.py b/core/scripts/webpanel/routers/api/v1/config/warp.py index 87c5d0b..80f79a6 100644 --- a/core/scripts/webpanel/routers/api/v1/config/warp.py +++ b/core/scripts/webpanel/routers/api/v1/config/warp.py @@ -61,7 +61,7 @@ async def configure(body: ConfigureInputBody): """ try: cli_api.configure_warp(body.all, body.popular_sites, body.domestic_sites, - body.block_adult_sites, body.warp_option, body.warp_key) + body.block_adult_sites) return DetailResponse(detail='WARP configured successfully.') except Exception as e: raise HTTPException(status_code=400, detail=f'Error: {str(e)}') diff --git a/core/scripts/webpanel/routers/api/v1/schema/config/warp.py b/core/scripts/webpanel/routers/api/v1/schema/config/warp.py index cc69af3..09e23f0 100644 --- a/core/scripts/webpanel/routers/api/v1/schema/config/warp.py +++ b/core/scripts/webpanel/routers/api/v1/schema/config/warp.py @@ -7,8 +7,6 @@ class ConfigureInputBody(BaseModel): popular_sites: bool = False domestic_sites: bool = False block_adult_sites: bool = False - warp_option: Literal['warp', 'warp plus', ''] = '' - warp_key: str = '' class StatusResponse(BaseModel): diff --git a/menu.sh b/menu.sh index dc51c65..d152e24 100644 --- a/menu.sh +++ b/menu.sh @@ -389,10 +389,8 @@ warp_configure_handler() { echo "2. Use WARP for popular sites" echo "3. Use WARP for domestic sites" echo "4. Block adult content" - echo "5. WARP (Plus) Profile" - echo "6. WARP (Normal) Profile" - echo "7. WARP Status Profile" - echo "8. Change IP address" + echo "5. WARP Status Profile" + echo "6. Change IP address" echo "0. Cancel" read -p "Select an option: " option @@ -402,23 +400,13 @@ warp_configure_handler() { 2) python3 $CLI_PATH configure-warp --popular-sites ;; 3) python3 $CLI_PATH configure-warp --domestic-sites ;; 4) python3 $CLI_PATH configure-warp --block-adult-sites ;; - 5) - echo "Please enter your WARP Plus key:" - read -r warp_key - if [ -z "$warp_key" ]; then - echo "Error: WARP Plus key cannot be empty. Exiting." - return - fi - python3 $CLI_PATH configure-warp --warp-option "warp plus" --warp-key "$warp_key" - ;; - 6) python3 $CLI_PATH configure-warp --warp-option "warp" ;; - 7) + 5) ip=$(curl -s --interface wgcf --connect-timeout 0.5 http://v4.ident.me) cd /etc/warp/ && wgcf status echo echo -e "${yellow}Warp IP :${NC} ${cyan}$ip ${NC}" ;; - 8) + 6) old_ip=$(curl -s --interface wgcf --connect-timeout 0.5 http://v4.ident.me) echo "Current IP address: $old_ip" echo "Restarting $service_name..."