diff --git a/core/cli_api.py b/core/cli_api.py index 428c491..06775d5 100644 --- a/core/cli_api.py +++ b/core/cli_api.py @@ -29,7 +29,7 @@ class Command(Enum): REMOVE_USER = os.path.join(SCRIPT_DIR, 'hysteria2', 'remove_user.py') SHOW_USER_URI = os.path.join(SCRIPT_DIR, 'hysteria2', 'show_user_uri.py') WRAPPER_URI = os.path.join(SCRIPT_DIR, 'hysteria2', 'wrapper_uri.py') - IP_ADD = os.path.join(SCRIPT_DIR, 'hysteria2', 'ip.sh') + 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') TRAFFIC_STATUS = 'traffic.py' # won't be called directly (it's a python module) @@ -387,7 +387,7 @@ def add_ip_address(): ''' Adds IP addresses from the environment to the .configs.env file. ''' - run_cmd(['bash', Command.IP_ADD.value, 'add']) + run_cmd(['python3', Command.IP_ADD.value, 'add']) def edit_ip_address(ipv4: str, ipv6: str): @@ -402,9 +402,9 @@ def edit_ip_address(ipv4: str, ipv6: str): if not ipv4 and not ipv6: raise InvalidInputError('Error: --edit requires at least one of --ipv4 or --ipv6.') if ipv4: - run_cmd(['bash', Command.IP_ADD.value, 'edit', '-4', ipv4]) + run_cmd(['python3', Command.IP_ADD.value, 'edit', '-4', ipv4]) if ipv6: - run_cmd(['bash', Command.IP_ADD.value, 'edit', '-6', ipv6]) + run_cmd(['python3', Command.IP_ADD.value, 'edit', '-6', ipv6]) def update_geo(country: str): diff --git a/core/scripts/hysteria2/ip.py b/core/scripts/hysteria2/ip.py new file mode 100644 index 0000000..17c6a7e --- /dev/null +++ b/core/scripts/hysteria2/ip.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python3 + +import sys +import re +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 CONFIG_ENV + + +def ensure_env_file_exists(): + if not CONFIG_ENV.exists(): + print("CONFIG_ENV not found. Creating a new one...") + CONFIG_ENV.touch() + + +def update_config(key: str, value: str): + content = [] + if CONFIG_ENV.exists(): + with CONFIG_ENV.open("r") as f: + content = [line for line in f if not line.startswith(f"{key}=")] + content.append(f"{key}={value}\n") + with CONFIG_ENV.open("w") as f: + f.writelines(content) + + +def get_interface_addresses(): + ipv4_address = "" + ipv6_address = "" + + interfaces = subprocess.check_output(["ip", "-o", "link", "show"]).decode() + interfaces = [ + line.split(": ")[1] + for line in interfaces.strip().splitlines() + if not re.match(r"^(lo|wgcf|warp)$", line.split(": ")[1]) + ] + + for iface in interfaces: + try: + ipv4 = subprocess.check_output(["ip", "-o", "-4", "addr", "show", iface]).decode() + for line in ipv4.strip().splitlines(): + addr = line.split()[3].split("/")[0] + if not re.match(r"^(127\.|10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[0-1]))", addr): + ipv4_address = addr + break + ipv6 = subprocess.check_output(["ip", "-o", "-6", "addr", "show", iface]).decode() + for line in ipv6.strip().splitlines(): + addr = line.split()[3].split("/")[0] + if not re.match(r"^(::1|fe80:)", addr): + ipv6_address = addr + break + except subprocess.CalledProcessError: + continue + + return ipv4_address, ipv6_address + + +def add_ips(): + ensure_env_file_exists() + ipv4, ipv6 = get_interface_addresses() + + update_config("IP4", ipv4 or "") + update_config("IP6", ipv6 or "") + + print(f"Updated IP4={ipv4 or 'Not Found'}") + print(f"Updated IP6={ipv6 or 'Not Found'}") + + +def edit_ip(option: str, new_ip: str): + ensure_env_file_exists() + if option == "-4": + update_config("IP4", new_ip) + print(f"IP4 has been updated to {new_ip}.") + elif option == "-6": + update_config("IP6", new_ip) + print(f"IP6 has been updated to {new_ip}.") + else: + print("Invalid option. Use -4 for IPv4 or -6 for IPv6.") + + +def main(): + if len(sys.argv) < 2: + print("Usage: {add|edit -4|-6 }") + sys.exit(1) + + action = sys.argv[1] + + if action == "add": + add_ips() + elif action == "edit" and len(sys.argv) == 4: + edit_ip(sys.argv[2], sys.argv[3]) + else: + print("Usage: {add|edit -4|-6 }") + sys.exit(1) + + +if __name__ == "__main__": + main() diff --git a/core/scripts/hysteria2/ip.sh b/core/scripts/hysteria2/ip.sh deleted file mode 100644 index 27b0da8..0000000 --- a/core/scripts/hysteria2/ip.sh +++ /dev/null @@ -1,71 +0,0 @@ -#!/bin/bash -source /etc/hysteria/core/scripts/path.sh - -if [ ! -f "$CONFIG_ENV" ]; then - echo "CONFIG_ENV not found. Creating a new one..." - touch "$CONFIG_ENV" -fi - -update_config() { - local key=$1 - local value=$2 - - sed -i "/^$key=/d" "$CONFIG_ENV" 2>/dev/null - - echo "$key=$value" >> "$CONFIG_ENV" -} - -add_ips() { - ipv4_address="" - ipv6_address="" - - interfaces=$(ip -o link show | awk -F': ' '{print $2}' | grep -vE '^(lo|wgcf|warp)$') - - for interface in $interfaces; do - if ip addr show "$interface" > /dev/null 2>&1; then - ipv4=$(ip -o -4 addr show "$interface" | awk '{print $4}' | grep -vE '^(127\\.|10\\.|192\\.168\\.|172\\.(1[6-9]|2[0-9]|3[0-1]))' | head -n 1 | cut -d/ -f1) - if [[ -z $ipv4_address && -n $ipv4 ]]; then - ipv4_address=$ipv4 - fi - - ipv6=$(ip -o -6 addr show "$interface" | awk '{print $4}' | grep -vE '^(::1|fe80:)' | head -n 1 | cut -d/ -f1) - if [[ -z $ipv6_address && -n $ipv6 ]]; then - ipv6_address=$ipv6 - fi - fi - done - - update_config "IP4" "${ipv4_address:-}" - update_config "IP6" "${ipv6_address:-}" - - echo "Updated IP4=${ipv4_address:-Not Found}" - echo "Updated IP6=${ipv6_address:-Not Found}" -} - -edit_ip() { - local type=$1 - local new_ip=$2 - - if [[ $type == "-4" ]]; then - update_config "IP4" "$new_ip" - echo "IP4 has been updated to $new_ip." - elif [[ $type == "-6" ]]; then - update_config "IP6" "$new_ip" - echo "IP6 has been updated to $new_ip." - else - echo "Invalid option. Use -4 for IPv4 or -6 for IPv6." - fi -} - -case "$1" in - add) - add_ips - ;; - edit) - edit_ip "$2" "$3" - ;; - *) - echo "Usage: $0 {add|edit -4|-6 }" - exit 1 - ;; -esac