From 0f01b2d52d702adaa07d2e39d1545988247e4391 Mon Sep 17 00:00:00 2001 From: Sarina Date: Sat, 20 Jul 2024 20:26:21 +0330 Subject: [PATCH 01/91] Add cli.py (python command line interface) --- cli.py | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 cli.py diff --git a/cli.py b/cli.py new file mode 100644 index 0000000..699f907 --- /dev/null +++ b/cli.py @@ -0,0 +1,82 @@ +import click +import subprocess + +@click.group() +def cli(): + pass + +# region hysteria2 menu options +@cli.command('install-hysteria2') +def install_hysteria2(): + #subprocess.run(['bash', 'install-hysteria2.sh']) + pass + +@cli.command('uninstall-hysteria2') +def uninstall_hysteria2(): + #subprocess.run(['bash', 'uninstall-hysteria2.sh']) + pass + +@cli.command('update-hysteria2') +def update_hysteria2(): + pass + +@cli.command('change-hysteria2-port') +@click.option('--port','-p', required=True, help='New port for Hysteria2',type=int) +def change_hysteria2_port(): + pass + +@cli.command('add-user') +@click.option('--username','-u', required=True, help='Username for the new user',type=str) +@click.option('--traffic-limit','-t', required=True, help='Traffic limit for the new user in GB',type=float) +@click.option('--expiration-days','-e', required=True, help='Expiration days for the new user',type=int) +def add_user(): + pass + +@cli.command('edit-user') +@click.option('--username','-u', required=True, help='Username for the user to edit',type=str) +def edit_user(): + pass + +@cli.command('remove-user') +@click.option('--username','-u', required=True, help='Username for the user to remove',type=str) +def remove_user(): + pass + +@cli.command('show-user-uri') +@click.option('--username','-u', required=True, help='Username for the user to show the URI',type=str) +def show_user_uri(): + pass + +@cli.command('traffic-status') +def traffic_status(): + pass + +@cli.command('list-users') +def list_users(): + pass + +# endregion + +# region advanced menu + +@cli.command('install-tcp-brutal') +def install_tcp_brutal(): + pass + +@cli.command('install-warp') +def install_warp(): + pass + +@cli.command('uninstall-warp') +def uninstall_warp(): + pass + +@cli.command('configure-warp') +@click.option('--warp-mode','-m', required=True, help='Warp mode',type=click.Choice(['proxy','direct','reject'])) +@click.option('--block-porn','-p', required=False, help='Block porn',type=bool) +def configure_warp(): + pass +# endregion + +if __name__ == '__main__': + cli() \ No newline at end of file From 83d2886e39af0ff30e95f7479d3105f98405bf50 Mon Sep 17 00:00:00 2001 From: Sarina Date: Sat, 20 Jul 2024 20:35:54 +0330 Subject: [PATCH 02/91] Restructure code --- cli.py => core/cli.py | 1 + install.sh => core/scripts/hysteria/install.sh | 0 core/utils.py | 9 +++++++++ 3 files changed, 10 insertions(+) rename cli.py => core/cli.py (99%) rename install.sh => core/scripts/hysteria/install.sh (100%) create mode 100644 core/utils.py diff --git a/cli.py b/core/cli.py similarity index 99% rename from cli.py rename to core/cli.py index 699f907..efe4998 100644 --- a/cli.py +++ b/core/cli.py @@ -1,5 +1,6 @@ import click import subprocess +import utils @click.group() def cli(): diff --git a/install.sh b/core/scripts/hysteria/install.sh similarity index 100% rename from install.sh rename to core/scripts/hysteria/install.sh diff --git a/core/utils.py b/core/utils.py new file mode 100644 index 0000000..800edb9 --- /dev/null +++ b/core/utils.py @@ -0,0 +1,9 @@ +import subprocess + +def generate_password() -> str: + ''' + Generates a random password using pwgen for user. + Could raise subprocess.CalledProcessError + ''' + result = subprocess.check_output(['pwgen', '-s', '32', '1']) + return result.decode().strip() \ No newline at end of file From fc31bc8397808571683b0482972ea36d23c836c1 Mon Sep 17 00:00:00 2001 From: Sarina Date: Sat, 20 Jul 2024 21:19:10 +0330 Subject: [PATCH 03/91] Add core/scripts/tcp-brutal/install.sh --- core/scripts/tcp-brutal/install.sh | 6 ++++++ menu.sh | 9 --------- 2 files changed, 6 insertions(+), 9 deletions(-) create mode 100644 core/scripts/tcp-brutal/install.sh diff --git a/core/scripts/tcp-brutal/install.sh b/core/scripts/tcp-brutal/install.sh new file mode 100644 index 0000000..356fd70 --- /dev/null +++ b/core/scripts/tcp-brutal/install.sh @@ -0,0 +1,6 @@ +#!/bin/bash +echo "Installing TCP Brutal..." +bash <(curl -fsSL https://tcp.hy2.sh/) +sleep 3 +clear +echo "TCP Brutal installation complete." \ No newline at end of file diff --git a/menu.sh b/menu.sh index 387ffcb..24b75b2 100644 --- a/menu.sh +++ b/menu.sh @@ -268,15 +268,6 @@ uninstall_hysteria() { echo "" } -# Function to install TCP Brutal -install_tcp_brutal() { - echo "Installing TCP Brutal..." - bash <(curl -fsSL https://tcp.hy2.sh/) - sleep 3 - clear - echo "TCP Brutal installation complete." -} - # Function to install WARP and update config.json install_warp() { # Check if wg-quick@wgcf.service is active From 35b343ce2316361aa008cd1890c49a167d170352 Mon Sep 17 00:00:00 2001 From: Sarina Date: Sat, 20 Jul 2024 21:21:49 +0330 Subject: [PATCH 04/91] Add empty warp scripts --- core/scripts/warp/configure.sh | 0 core/scripts/warp/install.sh | 0 core/scripts/warp/uninstall.sh | 0 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 core/scripts/warp/configure.sh create mode 100644 core/scripts/warp/install.sh create mode 100644 core/scripts/warp/uninstall.sh diff --git a/core/scripts/warp/configure.sh b/core/scripts/warp/configure.sh new file mode 100644 index 0000000..e69de29 diff --git a/core/scripts/warp/install.sh b/core/scripts/warp/install.sh new file mode 100644 index 0000000..e69de29 diff --git a/core/scripts/warp/uninstall.sh b/core/scripts/warp/uninstall.sh new file mode 100644 index 0000000..e69de29 From 3ec0966df7a57ba46ac2cc2beed796621a4dbd0b Mon Sep 17 00:00:00 2001 From: Sarina Date: Sat, 20 Jul 2024 21:22:20 +0330 Subject: [PATCH 05/91] Move traffic.py to core/ & make it as a module --- traffic.py => core/traffic.py | 1 - 1 file changed, 1 deletion(-) rename traffic.py => core/traffic.py (99%) diff --git a/traffic.py b/core/traffic.py similarity index 99% rename from traffic.py rename to core/traffic.py index d874694..b430d4c 100644 --- a/traffic.py +++ b/core/traffic.py @@ -109,4 +109,3 @@ def format_bytes(bytes): else: return f"{bytes / 1099511627776:.2f}TB" -traffic_status() From 98c6b67b3de239e4cbd0139b8f58e937bddf0213 Mon Sep 17 00:00:00 2001 From: Sarina Date: Sat, 20 Jul 2024 21:22:47 +0330 Subject: [PATCH 06/91] Remove unwanted utils.py --- core/utils.py | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 core/utils.py diff --git a/core/utils.py b/core/utils.py deleted file mode 100644 index 800edb9..0000000 --- a/core/utils.py +++ /dev/null @@ -1,9 +0,0 @@ -import subprocess - -def generate_password() -> str: - ''' - Generates a random password using pwgen for user. - Could raise subprocess.CalledProcessError - ''' - result = subprocess.check_output(['pwgen', '-s', '32', '1']) - return result.decode().strip() \ No newline at end of file From f0892da4cb2750ce57c85b22da367ba8010053cc Mon Sep 17 00:00:00 2001 From: Sarina Date: Sat, 20 Jul 2024 21:23:36 +0330 Subject: [PATCH 07/91] Rename core/scripts/hysteria to core/scripts/hysteria2 --- core/scripts/{hysteria => hysteria2}/install.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename core/scripts/{hysteria => hysteria2}/install.sh (100%) diff --git a/core/scripts/hysteria/install.sh b/core/scripts/hysteria2/install.sh similarity index 100% rename from core/scripts/hysteria/install.sh rename to core/scripts/hysteria2/install.sh From 7ada53c6ad5e0207edb8e393f91f86aabad7c166 Mon Sep 17 00:00:00 2001 From: Sarina Date: Sat, 20 Jul 2024 21:24:17 +0330 Subject: [PATCH 08/91] Change cli.py --- core/cli.py | 94 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 71 insertions(+), 23 deletions(-) diff --git a/core/cli.py b/core/cli.py index efe4998..2943c75 100644 --- a/core/cli.py +++ b/core/cli.py @@ -1,6 +1,52 @@ -import click +#!/usr/bin/env python3 + +import os import subprocess -import utils +import click +from enum import StrEnum + +import traffic + +SCRIPT_DIR = 'scripts' +DEBUG = True + +class Command(StrEnum): + '''Constais path to command's script''' + INSTALL_HYSTERIA2 = os.path.join(SCRIPT_DIR,'hysteria2' ,'install.sh') + UNINSTALL_HYSTERIA2 = os.path.join(SCRIPT_DIR,'hysteria2', 'uninstall.sh') + UPDATE_HYSTERIA2 = os.path.join(SCRIPT_DIR,'hysteria2', 'update.sh') + CHANGE_PORT_HYSTERIA2 = os.path.join(SCRIPT_DIR,'hysteria2' ,'change_port.sh') + ADD_USER = os.path.join(SCRIPT_DIR,'hysteria2' ,'add_user.sh') + EDIT_USER = os.path.join(SCRIPT_DIR,'hysteria2' ,'edit_user.sh') + REMOVE_USER = os.path.join(SCRIPT_DIR,'hysteria2' ,'remove_user.sh') + SHOW_USER_URI = os.path.join(SCRIPT_DIR,'hysteria2' ,'show_user_uri.sh') + TRAFFIC_STATUS = 'traffic.py' # won't be call directly (it's a python module) + LIST_USERS = '' # unknown for now + INSTALL_TCP_BRUTAL = os.path.join(SCRIPT_DIR,'tcp-brutal', 'install.sh') + INSTALL_WARP = os.path.join(SCRIPT_DIR,'warp', 'install.sh') + UNINSTALL_WARP = os.path.join(SCRIPT_DIR,'warp', 'uninstall.sh') + CONFIGURE_WARP = os.path.join(SCRIPT_DIR,'warp', 'configure.sh') + + +# region utils +def run_cmd(command:list[str]): + ''' + Runs a command and returns the output. + Could raise subprocess.CalledProcessError + ''' + result = subprocess.check_output(command, shell=True) + if DEBUG: + print(result.decode().strip()) + +def generate_password() -> str: + ''' + Generates a random password using pwgen for user. + Could raise subprocess.CalledProcessError + ''' + return subprocess.check_output(['pwgen', '-s', '32', '1'], shell=True).decode().strip() + +# endregion + @click.group() def cli(): @@ -9,48 +55,49 @@ def cli(): # region hysteria2 menu options @cli.command('install-hysteria2') def install_hysteria2(): - #subprocess.run(['bash', 'install-hysteria2.sh']) - pass + run_cmd(['bash', Command.INSTALL_HYSTERIA2]) + @cli.command('uninstall-hysteria2') def uninstall_hysteria2(): - #subprocess.run(['bash', 'uninstall-hysteria2.sh']) - pass + run_cmd(['bash', Command.UNINSTALL_HYSTERIA2]) @cli.command('update-hysteria2') def update_hysteria2(): - pass + run_cmd(['bash', Command.UPDATE_HYSTERIA2]) @cli.command('change-hysteria2-port') @click.option('--port','-p', required=True, help='New port for Hysteria2',type=int) -def change_hysteria2_port(): - pass +def change_hysteria2_port(port:int): + run_cmd(['bash', Command.CHANGE_PORT_HYSTERIA2, str(port)]) @cli.command('add-user') @click.option('--username','-u', required=True, help='Username for the new user',type=str) @click.option('--traffic-limit','-t', required=True, help='Traffic limit for the new user in GB',type=float) @click.option('--expiration-days','-e', required=True, help='Expiration days for the new user',type=int) -def add_user(): - pass +def add_user(username:str, traffic_limit:float, expiration_days:int): + run_cmd(['bash', Command.ADD_USER, username, str(traffic_limit), str(expiration_days)]) @cli.command('edit-user') @click.option('--username','-u', required=True, help='Username for the user to edit',type=str) -def edit_user(): - pass +@click.option('--traffic-limit','-t', required=True, help='Traffic limit for the new user in GB',type=float) +@click.option('--expiration-days','-e', required=True, help='Expiration days for the new user',type=int) +def edit_user(username:str, traffic_limit:float, expiration_days:int): + run_cmd(['bash', Command.EDIT_USER, username, str(traffic_limit), str(expiration_days)]) @cli.command('remove-user') @click.option('--username','-u', required=True, help='Username for the user to remove',type=str) -def remove_user(): - pass +def remove_user(username:str): + run_cmd(['bash', Command.REMOVE_USER, username]) @cli.command('show-user-uri') @click.option('--username','-u', required=True, help='Username for the user to show the URI',type=str) -def show_user_uri(): - pass +def show_user_uri(username:str): + run_cmd(['bash', Command.SHOW_USER_URI, username]) @cli.command('traffic-status') def traffic_status(): - pass + traffic.traffic_status() @cli.command('list-users') def list_users(): @@ -62,21 +109,22 @@ def list_users(): @cli.command('install-tcp-brutal') def install_tcp_brutal(): - pass + run_cmd(['bash', Command.INSTALL_TCP_BRUTAL]) @cli.command('install-warp') def install_warp(): - pass + run_cmd(['bash', Command.INSTALL_WARP]) @cli.command('uninstall-warp') def uninstall_warp(): - pass + run_cmd(['bash', Command.UNINSTALL_WARP]) @cli.command('configure-warp') @click.option('--warp-mode','-m', required=True, help='Warp mode',type=click.Choice(['proxy','direct','reject'])) @click.option('--block-porn','-p', required=False, help='Block porn',type=bool) -def configure_warp(): - pass +def configure_warp(warp_mode:str, block_porn:bool): + run_cmd(['bash', Command.CONFIGURE_WARP, warp_mode, str(block_porn)]) + # endregion if __name__ == '__main__': From c1007c59ef3df2dadc6c6b0153b3f8e84dbbff73 Mon Sep 17 00:00:00 2001 From: Sarina Date: Sat, 20 Jul 2024 22:58:02 +0330 Subject: [PATCH 09/91] Isolate uninstall_hysteria --- core/scripts/hysteria2/uninstall.sh | 24 ++++++++++++++++++++++++ menu.sh | 4 +++- 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 core/scripts/hysteria2/uninstall.sh diff --git a/core/scripts/hysteria2/uninstall.sh b/core/scripts/hysteria2/uninstall.sh new file mode 100644 index 0000000..88fe0d3 --- /dev/null +++ b/core/scripts/hysteria2/uninstall.sh @@ -0,0 +1,24 @@ +echo "Uninstalling Hysteria2..." +sleep 1 +echo "Running uninstallation script..." +bash <(curl -fsSL https://get.hy2.sh/) --remove >/dev/null 2>&1 +sleep 1 +echo "Removing Hysteria folder..." +rm -rf /etc/hysteria >/dev/null 2>&1 +sleep 1 +echo "Deleting hysteria user..." +userdel -r hysteria >/dev/null 2>&1 +sleep 1 +echo "Removing systemd service files..." +rm -f /etc/systemd/system/multi-user.target.wants/hysteria-server.service >/dev/null 2>&1 +rm -f /etc/systemd/system/multi-user.target.wants/hysteria-server@*.service >/dev/null 2>&1 +sleep 1 +echo "Reloading systemd daemon..." +systemctl daemon-reload >/dev/null 2>&1 +sleep 1 +echo "Removing cron jobs..." +(crontab -l | grep -v "python3 /etc/hysteria/traffic.py" | crontab -) >/dev/null 2>&1 +(crontab -l | grep -v "/etc/hysteria/users/kick.sh" | crontab -) >/dev/null 2>&1 +sleep 1 +echo "Hysteria2 uninstalled!" +echo "" \ No newline at end of file diff --git a/menu.sh b/menu.sh index 24b75b2..dad8118 100644 --- a/menu.sh +++ b/menu.sh @@ -56,6 +56,7 @@ install_and_configure() { fi } +# TODO: remove # Function to update Hysteria2 update_core() { echo "Starting the update process for Hysteria2..." @@ -223,7 +224,7 @@ traffic_status() { done } - +# TODO: remove # Function to restart Hysteria2 service restart_hysteria_service() { python3 /etc/hysteria/traffic.py >/dev/null 2>&1 @@ -240,6 +241,7 @@ modify_users() { python3 "$modify_script" } +# TODO: remove # Function to uninstall Hysteria2 uninstall_hysteria() { echo "Uninstalling Hysteria2..." From 71fff6c0174fba67e7f509435e116497519be5eb Mon Sep 17 00:00:00 2001 From: Sarina Date: Sat, 20 Jul 2024 23:01:57 +0330 Subject: [PATCH 10/91] Just Isolate some codes (not complete) --- core/cli.py | 15 +++++++- core/scripts/hysteria2/restart.sh | 1 + core/scripts/hysteria2/update.sh | 42 +++++++++++++++++++++ core/scripts/warp/uninstall.sh | 30 +++++++++++++++ menu.sh | 62 ------------------------------- 5 files changed, 87 insertions(+), 63 deletions(-) create mode 100644 core/scripts/hysteria2/restart.sh create mode 100644 core/scripts/hysteria2/update.sh diff --git a/core/cli.py b/core/cli.py index 2943c75..82f98ba 100644 --- a/core/cli.py +++ b/core/cli.py @@ -1,9 +1,11 @@ #!/usr/bin/env python3 import os -import subprocess +import io import click +import subprocess from enum import StrEnum +from contextlib import redirect_stdout import traffic @@ -15,6 +17,7 @@ class Command(StrEnum): INSTALL_HYSTERIA2 = os.path.join(SCRIPT_DIR,'hysteria2' ,'install.sh') UNINSTALL_HYSTERIA2 = os.path.join(SCRIPT_DIR,'hysteria2', 'uninstall.sh') UPDATE_HYSTERIA2 = os.path.join(SCRIPT_DIR,'hysteria2', 'update.sh') + RESTART_HYSTERIA2 = os.path.join(SCRIPT_DIR,'hysteria2','restart.sh') CHANGE_PORT_HYSTERIA2 = os.path.join(SCRIPT_DIR,'hysteria2' ,'change_port.sh') ADD_USER = os.path.join(SCRIPT_DIR,'hysteria2' ,'add_user.sh') EDIT_USER = os.path.join(SCRIPT_DIR,'hysteria2' ,'edit_user.sh') @@ -66,6 +69,16 @@ def uninstall_hysteria2(): def update_hysteria2(): run_cmd(['bash', Command.UPDATE_HYSTERIA2]) +@cli.command('restart-hysteria2') +def restart_hysteria2(): + # save traffic status before restarting hysteria2 + # ignore the traffic_status prints + f = io.StringIO() + with redirect_stdout(f): + traffic.traffic_status() + run_cmd(['bash', Command.RESTART_HYSTERIA2]) + + @cli.command('change-hysteria2-port') @click.option('--port','-p', required=True, help='New port for Hysteria2',type=int) def change_hysteria2_port(port:int): diff --git a/core/scripts/hysteria2/restart.sh b/core/scripts/hysteria2/restart.sh new file mode 100644 index 0000000..315a734 --- /dev/null +++ b/core/scripts/hysteria2/restart.sh @@ -0,0 +1 @@ +systemctl restart hysteria-server.service \ No newline at end of file diff --git a/core/scripts/hysteria2/update.sh b/core/scripts/hysteria2/update.sh new file mode 100644 index 0000000..606edc2 --- /dev/null +++ b/core/scripts/hysteria2/update.sh @@ -0,0 +1,42 @@ +echo "Starting the update process for Hysteria2..." +echo "Backing up the current configuration..." +cp /etc/hysteria/config.json /etc/hysteria/config_backup.json +if [ $? -ne 0 ]; then + echo "${red}Error:${NC} Failed to back up configuration. Aborting update." + return 1 +fi + +echo "Downloading and installing the latest version of Hysteria2..." +bash <(curl -fsSL https://get.hy2.sh/) >/dev/null 2>&1 +if [ $? -ne 0 ]; then + echo "${red}Error:${NC} Failed to download or install the latest version. Restoring backup configuration." + mv /etc/hysteria/config_backup.json /etc/hysteria/config.json + restart_hysteria_service >/dev/null 2>&1 + return 1 +fi + +echo "Restoring configuration from backup..." +mv /etc/hysteria/config_backup.json /etc/hysteria/config.json +if [ $? -ne 0 ]; then + echo "${red}Error:${NC} Failed to restore configuration from backup." + return 1 +fi + +echo "Modifying systemd service to use config.json..." +sed -i 's|/etc/hysteria/config.yaml|/etc/hysteria/config.json|' /etc/systemd/system/hysteria-server.service +if [ $? -ne 0 ]; then + echo "${red}Error:${NC} Failed to modify systemd service." + return 1 +fi + +rm /etc/hysteria/config.yaml +systemctl daemon-reload >/dev/null 2>&1 +restart_hysteria_service >/dev/null 2>&1 +if [ $? -ne 0 ]; then + echo "${red}Error:${NC} Failed to restart Hysteria2 service." + return 1 +fi + +echo "Hysteria2 has been successfully updated." +echo "" +return 0 \ No newline at end of file diff --git a/core/scripts/warp/uninstall.sh b/core/scripts/warp/uninstall.sh index e69de29..f8d8cd0 100644 --- a/core/scripts/warp/uninstall.sh +++ b/core/scripts/warp/uninstall.sh @@ -0,0 +1,30 @@ +if systemctl is-active --quiet wg-quick@wgcf.service; then + echo "Uninstalling WARP..." + bash <(curl -fsSL git.io/warp.sh) dwg + + if [ -f "/etc/hysteria/config.json" ]; then + default_config='["reject(geosite:ir)", "reject(geoip:ir)", "reject(geosite:category-ads-all)", "reject(geoip:private)", "reject(geosite:google@ads)"]' + + jq --argjson default_config "$default_config" ' + .acl.inline |= map( + if . == "warps(all)" or . == "warps(geoip:google)" or . == "warps(geosite:google)" or . == "warps(geosite:netflix)" or . == "warps(geosite:spotify)" or . == "warps(geosite:openai)" or . == "warps(geoip:openai)" then + "direct" + elif . == "warps(geosite:ir)" then + "reject(geosite:ir)" + elif . == "warps(geoip:ir)" then + "reject(geoip:ir)" + else + . + end + ) | .acl.inline |= ($default_config + (. - $default_config | map(select(. != "direct")))) + ' /etc/hysteria/config.json > /etc/hysteria/config_temp.json && mv /etc/hysteria/config_temp.json /etc/hysteria/config.json + jq 'del(.outbounds[] | select(.name == "warps" and .type == "direct" and .direct.mode == 4 and .direct.bindDevice == "wgcf"))' /etc/hysteria/config.json > /etc/hysteria/config_temp.json && mv /etc/hysteria/config_temp.json /etc/hysteria/config.json + + restart_hysteria_service >/dev/null 2>&1 + echo "WARP uninstalled and configurations reset to default." + else + echo "${red}Error:${NC} Config file /etc/hysteria/config.json not found." + fi +else + echo "WARP is not active. Skipping uninstallation." +fi \ No newline at end of file diff --git a/menu.sh b/menu.sh index dad8118..2618215 100644 --- a/menu.sh +++ b/menu.sh @@ -241,35 +241,6 @@ modify_users() { python3 "$modify_script" } -# TODO: remove -# Function to uninstall Hysteria2 -uninstall_hysteria() { - echo "Uninstalling Hysteria2..." - sleep 1 - echo "Running uninstallation script..." - bash <(curl -fsSL https://get.hy2.sh/) --remove >/dev/null 2>&1 - sleep 1 - echo "Removing Hysteria folder..." - rm -rf /etc/hysteria >/dev/null 2>&1 - sleep 1 - echo "Deleting hysteria user..." - userdel -r hysteria >/dev/null 2>&1 - sleep 1 - echo "Removing systemd service files..." - rm -f /etc/systemd/system/multi-user.target.wants/hysteria-server.service >/dev/null 2>&1 - rm -f /etc/systemd/system/multi-user.target.wants/hysteria-server@*.service >/dev/null 2>&1 - sleep 1 - echo "Reloading systemd daemon..." - systemctl daemon-reload >/dev/null 2>&1 - sleep 1 - echo "Removing cron jobs..." - (crontab -l | grep -v "python3 /etc/hysteria/traffic.py" | crontab -) >/dev/null 2>&1 - (crontab -l | grep -v "/etc/hysteria/users/kick.sh" | crontab -) >/dev/null 2>&1 - sleep 1 - echo "Hysteria2 uninstalled!" - echo "" -} - # Function to install WARP and update config.json install_warp() { # Check if wg-quick@wgcf.service is active @@ -292,39 +263,6 @@ install_warp() { fi } -# Function to uninstall WARP and update config.json -uninstall_warp() { - if systemctl is-active --quiet wg-quick@wgcf.service; then - echo "Uninstalling WARP..." - bash <(curl -fsSL git.io/warp.sh) dwg - - if [ -f "/etc/hysteria/config.json" ]; then - default_config='["reject(geosite:ir)", "reject(geoip:ir)", "reject(geosite:category-ads-all)", "reject(geoip:private)", "reject(geosite:google@ads)"]' - - jq --argjson default_config "$default_config" ' - .acl.inline |= map( - if . == "warps(all)" or . == "warps(geoip:google)" or . == "warps(geosite:google)" or . == "warps(geosite:netflix)" or . == "warps(geosite:spotify)" or . == "warps(geosite:openai)" or . == "warps(geoip:openai)" then - "direct" - elif . == "warps(geosite:ir)" then - "reject(geosite:ir)" - elif . == "warps(geoip:ir)" then - "reject(geoip:ir)" - else - . - end - ) | .acl.inline |= ($default_config + (. - $default_config | map(select(. != "direct")))) - ' /etc/hysteria/config.json > /etc/hysteria/config_temp.json && mv /etc/hysteria/config_temp.json /etc/hysteria/config.json - jq 'del(.outbounds[] | select(.name == "warps" and .type == "direct" and .direct.mode == 4 and .direct.bindDevice == "wgcf"))' /etc/hysteria/config.json > /etc/hysteria/config_temp.json && mv /etc/hysteria/config_temp.json /etc/hysteria/config.json - - restart_hysteria_service >/dev/null 2>&1 - echo "WARP uninstalled and configurations reset to default." - else - echo "${red}Error:${NC} Config file /etc/hysteria/config.json not found." - fi - else - echo "WARP is not active. Skipping uninstallation." - fi -} # Function to configure WARP configure_warp() { From 16f94eeee3a5f8cc372b811f92aea323a9ade6e3 Mon Sep 17 00:00:00 2001 From: Sarina Date: Sun, 21 Jul 2024 18:01:42 +0330 Subject: [PATCH 11/91] Isolate install_warp --- core/scripts/warp/install.sh | 18 ++++++++++++++++++ menu.sh | 23 ----------------------- 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/core/scripts/warp/install.sh b/core/scripts/warp/install.sh index e69de29..42403ed 100644 --- a/core/scripts/warp/install.sh +++ b/core/scripts/warp/install.sh @@ -0,0 +1,18 @@ +# Check if wg-quick@wgcf.service is active +if systemctl is-active --quiet wg-quick@wgcf.service; then + echo "WARP is already active. Skipping installation and configuration update." +else + echo "Installing WARP..." + bash <(curl -fsSL git.io/warp.sh) wgx + + # Check if the config file exists + if [ -f "/etc/hysteria/config.json" ]; then + # Add the outbound configuration to the config.json file + jq '.outbounds += [{"name": "warps", "type": "direct", "direct": {"mode": 4, "bindDevice": "wgcf"}}]' /etc/hysteria/config.json > /etc/hysteria/config_temp.json && mv /etc/hysteria/config_temp.json /etc/hysteria/config.json + # Restart the hysteria-server service + restart_hysteria_service >/dev/null 2>&1 + echo "WARP installed and outbound added to config.json." + else + echo "${red}Error:${NC} Config file /etc/hysteria/config.json not found." + fi +fi \ No newline at end of file diff --git a/menu.sh b/menu.sh index 2618215..d91f4f1 100644 --- a/menu.sh +++ b/menu.sh @@ -241,29 +241,6 @@ modify_users() { python3 "$modify_script" } -# Function to install WARP and update config.json -install_warp() { - # Check if wg-quick@wgcf.service is active - if systemctl is-active --quiet wg-quick@wgcf.service; then - echo "WARP is already active. Skipping installation and configuration update." - else - echo "Installing WARP..." - bash <(curl -fsSL git.io/warp.sh) wgx - - # Check if the config file exists - if [ -f "/etc/hysteria/config.json" ]; then - # Add the outbound configuration to the config.json file - jq '.outbounds += [{"name": "warps", "type": "direct", "direct": {"mode": 4, "bindDevice": "wgcf"}}]' /etc/hysteria/config.json > /etc/hysteria/config_temp.json && mv /etc/hysteria/config_temp.json /etc/hysteria/config.json - # Restart the hysteria-server service - restart_hysteria_service >/dev/null 2>&1 - echo "WARP installed and outbound added to config.json." - else - echo "${red}Error:${NC} Config file /etc/hysteria/config.json not found." - fi - fi -} - - # Function to configure WARP configure_warp() { # Check if wg-quick@wgcf.service is active From 749f524490ca276a03b1e50d2be383d7fb398582 Mon Sep 17 00:00:00 2001 From: Sarina Date: Sun, 21 Jul 2024 18:03:54 +0330 Subject: [PATCH 12/91] Isolate configure_warp --- core/scripts/warp/configure.sh | 74 ++++++++++++++++++++++++++++++++ menu.sh | 77 ---------------------------------- 2 files changed, 74 insertions(+), 77 deletions(-) diff --git a/core/scripts/warp/configure.sh b/core/scripts/warp/configure.sh index e69de29..b2b15a5 100644 --- a/core/scripts/warp/configure.sh +++ b/core/scripts/warp/configure.sh @@ -0,0 +1,74 @@ + # Check if wg-quick@wgcf.service is active +if ! systemctl is-active --quiet wg-quick@wgcf.service; then + echo "WARP is not active. Please install WARP before configuring." + return +fi + +CONFIG_FILE="/etc/hysteria/config.json" + +if [ -f "$CONFIG_FILE" ]; then + # Check the current status of WARP configurations + warp_all_status=$(jq -r 'if .acl.inline | index("warps(all)") then "WARP active" else "Direct" end' "$CONFIG_FILE") + google_openai_status=$(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") + iran_status=$(jq -r 'if (.acl.inline | index("warps(geosite:ir)")) and (.acl.inline | index("warps(geoip:ir)")) then "Use WARP" else "Reject" end' "$CONFIG_FILE") + adult_content_status=$(jq -r 'if .acl.inline | index("reject(geosite:category-porn)") then "Blocked" else "Not blocked" end' "$CONFIG_FILE") + + echo "===== Configuration Menu =====" + echo "1. Use WARP for all traffic ($warp_all_status)" + echo "2. Use WARP for Google, OpenAI, etc. ($google_openai_status)" + echo "3. Use WARP for geosite:ir and geoip:ir ($iran_status)" + echo "4. Block adult content ($adult_content_status)" + echo "5. Back to Advance Menu" + echo "===================================" + + read -p "Enter your choice: " choice + case $choice in + 1) + if [ "$warp_all_status" == "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 + ;; + 2) + if [ "$google_openai_status" == "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 + ;; + 3) + if [ "$iran_status" == "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 + ;; + 4) + if [ "$adult_content_status" == "Blocked" ]; then + jq 'del(.acl.inline[] | select(. == "reject(geosite:category-porn)"))' "$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:category-porn)"]' "$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 + ;; + 5) + return + ;; + *) + echo "Invalid option. Please try again." + ;; + esac + restart_hysteria_service >/dev/null 2>&1 +else + echo "${red}Error:${NC} Config file $CONFIG_FILE not found." +fi \ No newline at end of file diff --git a/menu.sh b/menu.sh index d91f4f1..b629187 100644 --- a/menu.sh +++ b/menu.sh @@ -241,83 +241,6 @@ modify_users() { python3 "$modify_script" } -# Function to configure WARP -configure_warp() { - # Check if wg-quick@wgcf.service is active - if ! systemctl is-active --quiet wg-quick@wgcf.service; then - echo "WARP is not active. Please install WARP before configuring." - return - fi - - CONFIG_FILE="/etc/hysteria/config.json" - - if [ -f "$CONFIG_FILE" ]; then - # Check the current status of WARP configurations - warp_all_status=$(jq -r 'if .acl.inline | index("warps(all)") then "WARP active" else "Direct" end' "$CONFIG_FILE") - google_openai_status=$(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") - iran_status=$(jq -r 'if (.acl.inline | index("warps(geosite:ir)")) and (.acl.inline | index("warps(geoip:ir)")) then "Use WARP" else "Reject" end' "$CONFIG_FILE") - adult_content_status=$(jq -r 'if .acl.inline | index("reject(geosite:category-porn)") then "Blocked" else "Not blocked" end' "$CONFIG_FILE") - - echo "===== Configuration Menu =====" - echo "1. Use WARP for all traffic ($warp_all_status)" - echo "2. Use WARP for Google, OpenAI, etc. ($google_openai_status)" - echo "3. Use WARP for geosite:ir and geoip:ir ($iran_status)" - echo "4. Block adult content ($adult_content_status)" - echo "5. Back to Advance Menu" - echo "===================================" - - read -p "Enter your choice: " choice - case $choice in - 1) - if [ "$warp_all_status" == "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 - ;; - 2) - if [ "$google_openai_status" == "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 - ;; - 3) - if [ "$iran_status" == "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 - ;; - 4) - if [ "$adult_content_status" == "Blocked" ]; then - jq 'del(.acl.inline[] | select(. == "reject(geosite:category-porn)"))' "$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:category-porn)"]' "$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 - ;; - 5) - return - ;; - *) - echo "Invalid option. Please try again." - ;; - esac - restart_hysteria_service >/dev/null 2>&1 - else - echo "${red}Error:${NC} Config file $CONFIG_FILE not found." - fi -} # Function to add a new user to the configuration add_user() { while true; do From d68530728035ccb7deee7a2e02f0eea9108fc657 Mon Sep 17 00:00:00 2001 From: Sarina Date: Sun, 21 Jul 2024 18:09:00 +0330 Subject: [PATCH 13/91] Isolate change_port --- core/scripts/hysteria2/change_port.sh | 16 ++ core/scripts/hysteria2/install.sh | 230 +++++++++++++++----------- menu.sh | 86 ---------- 3 files changed, 145 insertions(+), 187 deletions(-) create mode 100644 core/scripts/hysteria2/change_port.sh diff --git a/core/scripts/hysteria2/change_port.sh b/core/scripts/hysteria2/change_port.sh new file mode 100644 index 0000000..66d33fc --- /dev/null +++ b/core/scripts/hysteria2/change_port.sh @@ -0,0 +1,16 @@ +while true; do + read -p "Enter the new port number you want to use: " port + if ! [[ "$port" =~ ^[0-9]+$ ]] || [ "$port" -lt 1 ] || [ "$port" -gt 65535 ]; then + echo "Invalid port number. Please enter a number between 1 and 65535." + else + break + fi +done + +if [ -f "/etc/hysteria/config.json" ]; then + jq --arg port "$port" '.listen = ":" + $port' /etc/hysteria/config.json > /etc/hysteria/config_temp.json && mv /etc/hysteria/config_temp.json /etc/hysteria/config.json + restart_hysteria_service >/dev/null 2>&1 + echo "Port changed successfully to $port." +else + echo "${red}Error:${NC} Config file /etc/hysteria/config.json not found." +fi \ No newline at end of file diff --git a/core/scripts/hysteria2/install.sh b/core/scripts/hysteria2/install.sh index 6b5f289..0a46aa2 100644 --- a/core/scripts/hysteria2/install.sh +++ b/core/scripts/hysteria2/install.sh @@ -1,4 +1,5 @@ #!/bin/bash + define_colors() { green='\033[0;32m' cyan='\033[0;36m' @@ -7,120 +8,147 @@ define_colors() { LPurple='\033[1;35m' NC='\033[0m' } -# Step 1: Install Hysteria2 -echo "Installing Hysteria2..." -bash <(curl -fsSL https://get.hy2.sh/) >/dev/null 2>&1 -# Step 2: Create hysteria directory and navigate into it -mkdir -p /etc/hysteria && cd /etc/hysteria/ - -# Step 3: Generate CA key and certificate and download geo data -echo "Generating CA key and certificate..." -openssl ecparam -genkey -name prime256v1 -out ca.key >/dev/null 2>&1 -openssl req -new -x509 -days 36500 -key ca.key -out ca.crt -subj "/CN=bts.com" >/dev/null 2>&1 -echo "Downloading geo data..." -wget -O /etc/hysteria/geosite.dat https://raw.githubusercontent.com/Chocolate4U/Iran-v2ray-rules/release/geosite.dat >/dev/null 2>&1 -wget -O /etc/hysteria/geoip.dat https://raw.githubusercontent.com/Chocolate4U/Iran-v2ray-rules/release/geoip.dat >/dev/null 2>&1 - -# Step 4: Extract the SHA-256 fingerprint -fingerprint=$(openssl x509 -noout -fingerprint -sha256 -inform pem -in ca.crt | sed 's/.*=//;s/://g') - -# Step 5: Generate the base64 encoded SHA-256 fingerprint -echo "Generating base64 encoded SHA-256 fingerprint..." -echo "import re, base64, binascii - -hex_string = \"$fingerprint\" -binary_data = binascii.unhexlify(hex_string) -base64_encoded = base64.b64encode(binary_data).decode('utf-8') - -print(\"sha256/\" + base64_encoded)" > generate.py - -sha256=$(python3 generate.py) - -# Step 6: Download the config.json file -echo "Downloading config.json..." -wget https://raw.githubusercontent.com/ReturnFI/Hysteria2/main/config.json -O /etc/hysteria/config.json >/dev/null 2>&1 -echo - -# Step 7: Ask for the port number and validate input -while true; do - read -p "Enter the port number you want to use (1-65535): " port - if [[ $port =~ ^[0-9]+$ ]] && (( port >= 1 && port <= 65535 )); then - # Check if the port is in use - if ss -tuln | grep -q ":$port\b"; then - clear - echo -e "\e[91mPort $port is already in use. Please choose another port.\e[0m" - echo +install_hysteria() { + # Step 1: Install Hysteria2 + echo "Installing Hysteria2..." + bash <(curl -fsSL https://get.hy2.sh/) >/dev/null 2>&1 + + # Step 2: Create hysteria directory and navigate into it + mkdir -p /etc/hysteria && cd /etc/hysteria/ + + # Step 3: Generate CA key and certificate and download geo data + echo "Generating CA key and certificate..." + openssl ecparam -genkey -name prime256v1 -out ca.key >/dev/null 2>&1 + openssl req -new -x509 -days 36500 -key ca.key -out ca.crt -subj "/CN=bts.com" >/dev/null 2>&1 + echo "Downloading geo data..." + wget -O /etc/hysteria/geosite.dat https://raw.githubusercontent.com/Chocolate4U/Iran-v2ray-rules/release/geosite.dat >/dev/null 2>&1 + wget -O /etc/hysteria/geoip.dat https://raw.githubusercontent.com/Chocolate4U/Iran-v2ray-rules/release/geoip.dat >/dev/null 2>&1 + + # Step 4: Extract the SHA-256 fingerprint + fingerprint=$(openssl x509 -noout -fingerprint -sha256 -inform pem -in ca.crt | sed 's/.*=//;s/://g') + + # Step 5: Generate the base64 encoded SHA-256 fingerprint + echo "Generating base64 encoded SHA-256 fingerprint..." + echo "import re, base64, binascii + + hex_string = \"$fingerprint\" + binary_data = binascii.unhexlify(hex_string) + base64_encoded = base64.b64encode(binary_data).decode('utf-8') + + print(\"sha256/\" + base64_encoded)" > generate.py + + sha256=$(python3 generate.py) + + # Step 6: Download the config.json file + echo "Downloading config.json..." + wget https://raw.githubusercontent.com/ReturnFI/Hysteria2/main/config.json -O /etc/hysteria/config.json >/dev/null 2>&1 + echo + + # Step 7: Ask for the port number and validate input + while true; do + read -p "Enter the port number you want to use (1-65535): " port + if [[ $port =~ ^[0-9]+$ ]] && (( port >= 1 && port <= 65535 )); then + # Check if the port is in use + if ss -tuln | grep -q ":$port\b"; then + clear + echo -e "\e[91mPort $port is already in use. Please choose another port.\e[0m" + echo + else + break + fi else - break + echo "Invalid port number. Please enter a number between 1 and 65535." fi - else - echo "Invalid port number. Please enter a number between 1 and 65535." + done + + # Step 8: Generate required passwords and UUID + echo "Generating passwords and UUID..." + obfspassword=$(pwgen -s 32 1) + UUID=$(uuidgen) + + # Step 9: Adjust file permissions for Hysteria service + chown hysteria:hysteria /etc/hysteria/ca.key /etc/hysteria/ca.crt + chmod 640 /etc/hysteria/ca.key /etc/hysteria/ca.crt + + # Create hysteria user without login permissions + if ! id -u hysteria &> /dev/null; then + useradd -r -s /usr/sbin/nologin hysteria fi -done + + # Get the default network interface + networkdef=$(ip route | grep "^default" | awk '{print $5}') + + # Step 10: Customize the config.json file + echo "Customizing config.json..." + jq --arg port "$port" \ + --arg sha256 "$sha256" \ + --arg obfspassword "$obfspassword" \ + --arg UUID "$UUID" \ + --arg networkdef "$networkdef" \ + '.listen = ":\($port)" | + .tls.cert = "/etc/hysteria/ca.crt" | + .tls.key = "/etc/hysteria/ca.key" | + .tls.pinSHA256 = $sha256 | + .obfs.salamander.password = $obfspassword | + .trafficStats.secret = $UUID | + .outbounds[0].direct.bindDevice = $networkdef' /etc/hysteria/config.json > /etc/hysteria/config_temp.json && mv /etc/hysteria/config_temp.json /etc/hysteria/config.json + + # Step 11: Modify the systemd service file to use config.json + echo "Updating hysteria-server.service to use config.json..." + sed -i 's|(config.yaml)||' /etc/systemd/system/hysteria-server.service + sed -i 's|/etc/hysteria/config.yaml|/etc/hysteria/config.json|' /etc/systemd/system/hysteria-server.service + rm /etc/hysteria/config.yaml + sleep 1 + + # Step 12: Start and enable the Hysteria service + echo "Starting and enabling Hysteria service..." + systemctl daemon-reload >/dev/null 2>&1 + systemctl start hysteria-server.service >/dev/null 2>&1 + systemctl enable hysteria-server.service >/dev/null 2>&1 + systemctl restart hysteria-server.service >/dev/null 2>&1 + + # Step 13: Check if the hysteria-server.service is active + if systemctl is-active --quiet hysteria-server.service; then + echo "${cyan}Hysteria2${green} has been successfully install." + else + echo "${red}Error:${NC} hysteria-server.service is not active." + fi + + # Step 15: wget Traffic/user/kick script + wget https://raw.githubusercontent.com/ReturnFI/Hysteria2/main/traffic.py -O /etc/hysteria/traffic.py >/dev/null 2>&1 + mkdir -p /etc/hysteria/users + wget https://raw.githubusercontent.com/ReturnFI/Hysteria2/main/user.sh -O /etc/hysteria/users/user.sh >/dev/null 2>&1 + wget https://raw.githubusercontent.com/ReturnFI/Hysteria2/main/kick.sh -O /etc/hysteria/users/kick.sh >/dev/null 2>&1 + wget https://raw.githubusercontent.com/ReturnFI/Hysteria2/main/modify.py -O /etc/hysteria/users/modify.py >/dev/null 2>&1 + + chmod +x /etc/hysteria/users/user.sh + chmod +x /etc/hysteria/users/kick.sh + # Add the commands to the crontab + (crontab -l ; echo "*/1 * * * * python3 /etc/hysteria/traffic.py >/dev/null 2>&1") | crontab - + (crontab -l ; echo "*/1 * * * * /etc/hysteria/users/kick.sh >/dev/null 2>&1") | crontab - + } -# Step 8: Generate required passwords and UUID -echo "Generating passwords and UUID..." -obfspassword=$(pwgen -s 32 1) -UUID=$(uuidgen) -# Step 9: Adjust file permissions for Hysteria service -chown hysteria:hysteria /etc/hysteria/ca.key /etc/hysteria/ca.crt -chmod 640 /etc/hysteria/ca.key /etc/hysteria/ca.crt -# Create hysteria user without login permissions -if ! id -u hysteria &> /dev/null; then - useradd -r -s /usr/sbin/nologin hysteria -fi -# Get the default network interface -networkdef=$(ip route | grep "^default" | awk '{print $5}') -# Step 10: Customize the config.json file -echo "Customizing config.json..." -jq --arg port "$port" \ - --arg sha256 "$sha256" \ - --arg obfspassword "$obfspassword" \ - --arg UUID "$UUID" \ - --arg networkdef "$networkdef" \ - '.listen = ":\($port)" | - .tls.cert = "/etc/hysteria/ca.crt" | - .tls.key = "/etc/hysteria/ca.key" | - .tls.pinSHA256 = $sha256 | - .obfs.salamander.password = $obfspassword | - .trafficStats.secret = $UUID | - .outbounds[0].direct.bindDevice = $networkdef' /etc/hysteria/config.json > /etc/hysteria/config_temp.json && mv /etc/hysteria/config_temp.json /etc/hysteria/config.json -# Step 11: Modify the systemd service file to use config.json -echo "Updating hysteria-server.service to use config.json..." -sed -i 's|(config.yaml)||' /etc/systemd/system/hysteria-server.service -sed -i 's|/etc/hysteria/config.yaml|/etc/hysteria/config.json|' /etc/systemd/system/hysteria-server.service -rm /etc/hysteria/config.yaml -sleep 1 -# Step 12: Start and enable the Hysteria service -echo "Starting and enabling Hysteria service..." -systemctl daemon-reload >/dev/null 2>&1 -systemctl start hysteria-server.service >/dev/null 2>&1 -systemctl enable hysteria-server.service >/dev/null 2>&1 -systemctl restart hysteria-server.service >/dev/null 2>&1 -# Step 13: Check if the hysteria-server.service is active if systemctl is-active --quiet hysteria-server.service; then - echo "${cyan}Hysteria2${green} has been successfully install." + echo -e "${red}Error:${NC} Hysteria2 is already installed and running." + echo + echo "If you need to update the core, please use the 'Update Core' option." else - echo "${red}Error:${NC} hysteria-server.service is not active." + echo "Installing and configuring Hysteria2..." + install_hysteria + echo -e "\n" + + if systemctl is-active --quiet hysteria-server.service; then + echo "Installation and configuration complete." + else + echo -e "${red}Error:${NC} Hysteria2 service is not active. Please check the logs for more details." + fi fi -# Step 15: wget Traffic/user/kick script -wget https://raw.githubusercontent.com/ReturnFI/Hysteria2/main/traffic.py -O /etc/hysteria/traffic.py >/dev/null 2>&1 -mkdir -p /etc/hysteria/users -wget https://raw.githubusercontent.com/ReturnFI/Hysteria2/main/user.sh -O /etc/hysteria/users/user.sh >/dev/null 2>&1 -wget https://raw.githubusercontent.com/ReturnFI/Hysteria2/main/kick.sh -O /etc/hysteria/users/kick.sh >/dev/null 2>&1 -wget https://raw.githubusercontent.com/ReturnFI/Hysteria2/main/modify.py -O /etc/hysteria/users/modify.py >/dev/null 2>&1 - -chmod +x /etc/hysteria/users/user.sh -chmod +x /etc/hysteria/users/kick.sh -# Add the commands to the crontab -(crontab -l ; echo "*/1 * * * * python3 /etc/hysteria/traffic.py >/dev/null 2>&1") | crontab - -(crontab -l ; echo "*/1 * * * * /etc/hysteria/users/kick.sh >/dev/null 2>&1") | crontab - \ No newline at end of file diff --git a/menu.sh b/menu.sh index b629187..80dcda2 100644 --- a/menu.sh +++ b/menu.sh @@ -37,92 +37,6 @@ get_system_info() { RAM=$(free -m | awk 'NR==2{printf "%.2f%%", $3*100/$2 }') } -# Function to install and configure Hysteria2 -install_and_configure() { - if systemctl is-active --quiet hysteria-server.service; then - echo -e "${red}Error:${NC} Hysteria2 is already installed and running." - echo - echo "If you need to update the core, please use the 'Update Core' option." - else - echo "Installing and configuring Hysteria2..." - bash <(curl -s https://raw.githubusercontent.com/ReturnFI/Hysteria2/main/install.sh) - echo -e "\n" - - if systemctl is-active --quiet hysteria-server.service; then - echo "Installation and configuration complete." - else - echo -e "${red}Error:${NC} Hysteria2 service is not active. Please check the logs for more details." - fi - fi -} - -# TODO: remove -# Function to update Hysteria2 -update_core() { - echo "Starting the update process for Hysteria2..." - echo "Backing up the current configuration..." - cp /etc/hysteria/config.json /etc/hysteria/config_backup.json - if [ $? -ne 0 ]; then - echo "${red}Error:${NC} Failed to back up configuration. Aborting update." - return 1 - fi - - echo "Downloading and installing the latest version of Hysteria2..." - bash <(curl -fsSL https://get.hy2.sh/) >/dev/null 2>&1 - if [ $? -ne 0 ]; then - echo "${red}Error:${NC} Failed to download or install the latest version. Restoring backup configuration." - mv /etc/hysteria/config_backup.json /etc/hysteria/config.json - restart_hysteria_service >/dev/null 2>&1 - return 1 - fi - - echo "Restoring configuration from backup..." - mv /etc/hysteria/config_backup.json /etc/hysteria/config.json - if [ $? -ne 0 ]; then - echo "${red}Error:${NC} Failed to restore configuration from backup." - return 1 - fi - - echo "Modifying systemd service to use config.json..." - sed -i 's|/etc/hysteria/config.yaml|/etc/hysteria/config.json|' /etc/systemd/system/hysteria-server.service - if [ $? -ne 0 ]; then - echo "${red}Error:${NC} Failed to modify systemd service." - return 1 - fi - - rm /etc/hysteria/config.yaml - systemctl daemon-reload >/dev/null 2>&1 - restart_hysteria_service >/dev/null 2>&1 - if [ $? -ne 0 ]; then - echo "${red}Error:${NC} Failed to restart Hysteria2 service." - return 1 - fi - - echo "Hysteria2 has been successfully updated." - echo "" - return 0 -} - -# Function to change port -change_port() { - while true; do - read -p "Enter the new port number you want to use: " port - if ! [[ "$port" =~ ^[0-9]+$ ]] || [ "$port" -lt 1 ] || [ "$port" -gt 65535 ]; then - echo "Invalid port number. Please enter a number between 1 and 65535." - else - break - fi - done - - if [ -f "/etc/hysteria/config.json" ]; then - jq --arg port "$port" '.listen = ":" + $port' /etc/hysteria/config.json > /etc/hysteria/config_temp.json && mv /etc/hysteria/config_temp.json /etc/hysteria/config.json - restart_hysteria_service >/dev/null 2>&1 - echo "Port changed successfully to $port." - else - echo "${red}Error:${NC} Config file /etc/hysteria/config.json not found." - fi -} - # Function to show URI if Hysteria2 is installed and active show_uri() { if [ -f "/etc/hysteria/users/users.json" ]; then From 662b701199d195248eeba8dc779b3ee5edb1edc4 Mon Sep 17 00:00:00 2001 From: Sarina Date: Sun, 21 Jul 2024 18:16:00 +0330 Subject: [PATCH 14/91] Isolate show_uri --- core/scripts/hysteria2/show_user_uri.sh | 64 +++++++++++++++++++++++++ menu.sh | 59 ----------------------- 2 files changed, 64 insertions(+), 59 deletions(-) create mode 100644 core/scripts/hysteria2/show_user_uri.sh diff --git a/core/scripts/hysteria2/show_user_uri.sh b/core/scripts/hysteria2/show_user_uri.sh new file mode 100644 index 0000000..35302b3 --- /dev/null +++ b/core/scripts/hysteria2/show_user_uri.sh @@ -0,0 +1,64 @@ +#!/bin/bash + +# Function to show URI if Hysteria2 is installed and active +show_uri() { + if [ -f "/etc/hysteria/users/users.json" ]; then + if systemctl is-active --quiet hysteria-server.service; then + # Check if the username is provided as an argument + if [ -z "$1" ]; then + echo "Usage: $0 " + exit 1 + fi + + username=$1 + + # Validate the username + if jq -e "has(\"$username\")" /etc/hysteria/users/users.json > /dev/null; then + # Get the selected user's details + authpassword=$(jq -r ".\"$username\".password" /etc/hysteria/users/users.json) + port=$(jq -r '.listen' /etc/hysteria/config.json | cut -d':' -f2) + sha256=$(jq -r '.tls.pinSHA256' /etc/hysteria/config.json) + obfspassword=$(jq -r '.obfs.salamander.password' /etc/hysteria/config.json) + + # Get IP addresses + IP=$(curl -s -4 ip.gs) + IP6=$(curl -s -6 ip.gs) + + # Construct URI + URI="hy2://$username%3A$authpassword@$IP:$port?obfs=salamander&obfs-password=$obfspassword&pinSHA256=$sha256&insecure=1&sni=bts.com#$username-IPv4" + URI6="hy2://$username%3A$authpassword@[$IP6]:$port?obfs=salamander&obfs-password=$obfspassword&pinSHA256=$sha256&insecure=1&sni=bts.com#$username-IPv6" + + # Generate QR codes + qr1=$(echo -n "$URI" | qrencode -t UTF8 -s 3 -m 2) + qr2=$(echo -n "$URI6" | qrencode -t UTF8 -s 3 -m 2) + + # Display QR codes and URIs + cols=$(tput cols) + echo -e "\nIPv4:\n" + echo "$qr1" | while IFS= read -r line; do + printf "%*s\n" $(( (${#line} + cols) / 2)) "$line" + done + + echo -e "\nIPv6:\n" + echo "$qr2" | while IFS= read -r line; do + printf "%*s\n" $(( (${#line} + cols) / 2)) "$line" + done + + echo + echo "IPv4: $URI" + echo + echo "IPv6: $URI6" + echo + else + echo "Invalid username. Please try again." + fi + else + echo -e "\033[0;31mError:\033[0m Hysteria2 is not active." + fi + else + echo -e "\033[0;31mError:\033[0m Config file /etc/hysteria/users/users.json not found." + fi +} + +# Call the function with the provided username argument +show_uri "$1" diff --git a/menu.sh b/menu.sh index 80dcda2..5d583ab 100644 --- a/menu.sh +++ b/menu.sh @@ -37,65 +37,6 @@ get_system_info() { RAM=$(free -m | awk 'NR==2{printf "%.2f%%", $3*100/$2 }') } -# Function to show URI if Hysteria2 is installed and active -show_uri() { - if [ -f "/etc/hysteria/users/users.json" ]; then - if systemctl is-active --quiet hysteria-server.service; then - # Get the list of configured usernames - usernames=$(jq -r 'keys_unsorted[]' /etc/hysteria/users/users.json) - - # Prompt the user to select a username - PS3="Select a username: " - select username in $usernames; do - if [ -n "$username" ]; then - # Get the selected user's details - authpassword=$(jq -r ".\"$username\".password" /etc/hysteria/users/users.json) - port=$(jq -r '.listen' /etc/hysteria/config.json | cut -d':' -f2) - sha256=$(jq -r '.tls.pinSHA256' /etc/hysteria/config.json) - obfspassword=$(jq -r '.obfs.salamander.password' /etc/hysteria/config.json) - - # Get IP addresses - IP=$(curl -s -4 ip.gs) - IP6=$(curl -s -6 ip.gs) - - # Construct URI - URI="hy2://$username%3A$authpassword@$IP:$port?obfs=salamander&obfs-password=$obfspassword&pinSHA256=$sha256&insecure=1&sni=bts.com#$username-IPv4" - URI6="hy2://$username%3A$authpassword@[$IP6]:$port?obfs=salamander&obfs-password=$obfspassword&pinSHA256=$sha256&insecure=1&sni=bts.com#$username-IPv6" - - # Generate QR codes - qr1=$(echo -n "$URI" | qrencode -t UTF8 -s 3 -m 2) - qr2=$(echo -n "$URI6" | qrencode -t UTF8 -s 3 -m 2) - - # Display QR codes and URIs - cols=$(tput cols) - echo -e "\nIPv4:\n" - echo "$qr1" | while IFS= read -r line; do - printf "%*s\n" $(( (${#line} + cols) / 2)) "$line" - done - - echo -e "\nIPv6:\n" - echo "$qr2" | while IFS= read -r line; do - printf "%*s\n" $(( (${#line} + cols) / 2)) "$line" - done - - echo - echo "IPv4: $URI" - echo - echo "IPv6: $URI6" - echo - break - else - echo "Invalid selection. Please try again." - fi - done - else - echo -e "\033[0;31mError:\033[0m Hysteria2 is not active." - fi - else - echo -e "\033[0;31mError:\033[0m Config file /etc/hysteria/users/users.json not found." - fi -} - # Function to check traffic status for each user traffic_status() { if [ -f "/etc/hysteria/traffic.py" ]; then From 40599ecbf97fea70b2b9c813c0cf6825893851cf Mon Sep 17 00:00:00 2001 From: Sarina Date: Sun, 21 Jul 2024 18:17:11 +0330 Subject: [PATCH 15/91] Isolate add_user --- core/scripts/hysteria2/add_user.sh | 40 ++++++++++++++++++++++++++++++ menu.sh | 32 ------------------------ 2 files changed, 40 insertions(+), 32 deletions(-) create mode 100644 core/scripts/hysteria2/add_user.sh diff --git a/core/scripts/hysteria2/add_user.sh b/core/scripts/hysteria2/add_user.sh new file mode 100644 index 0000000..36ecf34 --- /dev/null +++ b/core/scripts/hysteria2/add_user.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +# Function to add a new user to the configuration +add_user() { + if [ $# -ne 3 ]; then + echo "Usage: $0 " + exit 1 + fi + + username=$1 + traffic_gb=$2 + expiration_days=$3 + + # Validate the username + if ! [[ "$username" =~ ^[a-z0-9]+$ ]]; then + echo -e "\033[0;31mError:\033[0m Username can only contain lowercase letters and numbers." + exit 1 + fi + + # Convert GB to bytes (1 GB = 1073741824 bytes) + traffic=$((traffic_gb * 1073741824)) + + password=$(pwgen -s 32 1) + creation_date=$(date +%Y-%m-%d) + + if [ ! -f "/etc/hysteria/users/users.json" ]; then + echo "{}" > /etc/hysteria/users/users.json + fi + + jq --arg username "$username" --arg password "$password" --argjson traffic "$traffic" --argjson expiration_days "$expiration_days" --arg creation_date "$creation_date" \ + '.[$username] = {password: $password, max_download_bytes: $traffic, expiration_days: $expiration_days, account_creation_date: $creation_date, blocked: false}' \ + /etc/hysteria/users/users.json > /etc/hysteria/users/users_temp.json && mv /etc/hysteria/users/users_temp.json /etc/hysteria/users/users.json + + restart_hysteria_service >/dev/null 2>&1 + + echo -e "\033[0;32mUser $username added successfully.\033[0m" +} + +# Call the function with the provided arguments +add_user "$1" "$2" "$3" diff --git a/menu.sh b/menu.sh index 5d583ab..b8fe0b6 100644 --- a/menu.sh +++ b/menu.sh @@ -96,38 +96,6 @@ modify_users() { python3 "$modify_script" } -# Function to add a new user to the configuration -add_user() { - while true; do - read -p "Enter the username: " username - - if [[ "$username" =~ ^[a-z0-9]+$ ]]; then - break - else - echo -e "\033[0;31mError:\033[0m Username can only contain lowercase letters and numbers." - fi - done - - read -p "Enter the traffic limit (in GB): " traffic_gb - # Convert GB to bytes (1 GB = 1073741824 bytes) - traffic=$((traffic_gb * 1073741824)) - - read -p "Enter the expiration days: " expiration_days - password=$(pwgen -s 32 1) - creation_date=$(date +%Y-%m-%d) - - if [ ! -f "/etc/hysteria/users/users.json" ]; then - echo "{}" > /etc/hysteria/users/users.json - fi - - jq --arg username "$username" --arg password "$password" --argjson traffic "$traffic" --argjson expiration_days "$expiration_days" --arg creation_date "$creation_date" \ - '.[$username] = {password: $password, max_download_bytes: $traffic, expiration_days: $expiration_days, account_creation_date: $creation_date, blocked: false}' \ - /etc/hysteria/users/users.json > /etc/hysteria/users/users_temp.json && mv /etc/hysteria/users/users_temp.json /etc/hysteria/users/users.json - - restart_hysteria_service >/dev/null 2>&1 - - echo -e "\033[0;32mUser $username added successfully.\033[0m" -} # Function to remove a user from the configuration From 6fa0ec4657c3ae8befa36e35a1c17fbf8d5e6ce3 Mon Sep 17 00:00:00 2001 From: Sarina Date: Sun, 21 Jul 2024 18:17:41 +0330 Subject: [PATCH 16/91] Isolate remove_user --- core/scripts/hysteria2/remove_user.sh | 32 ++++++++++++++++++ menu.sh | 48 --------------------------- 2 files changed, 32 insertions(+), 48 deletions(-) create mode 100644 core/scripts/hysteria2/remove_user.sh diff --git a/core/scripts/hysteria2/remove_user.sh b/core/scripts/hysteria2/remove_user.sh new file mode 100644 index 0000000..89ea1f2 --- /dev/null +++ b/core/scripts/hysteria2/remove_user.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +# Function to remove a user from the configuration +remove_user() { + if [ $# -ne 1 ]; then + echo "Usage: $0 " + exit 1 + fi + + username=$1 + + if [ -f "/etc/hysteria/users/users.json" ]; then + # Check if the username exists in the users.json file + if jq -e "has(\"$username\")" /etc/hysteria/users/users.json > /dev/null; then + jq --arg username "$username" 'del(.[$username])' /etc/hysteria/users/users.json > /etc/hysteria/users/users_temp.json && mv /etc/hysteria/users/users_temp.json /etc/hysteria/users/users.json + + if [ -f "/etc/hysteria/traffic_data.json" ]; then + jq --arg username "$username" 'del(.[$username])' /etc/hysteria/traffic_data.json > /etc/hysteria/traffic_data_temp.json && mv /etc/hysteria/traffic_data_temp.json /etc/hysteria/traffic_data.json + fi + + restart_hysteria_service >/dev/null 2>&1 + echo "User $username removed successfully." + else + echo -e "\033[0;31mError:\033[0m User $username not found." + fi + else + echo -e "\033[0;31mError:\033[0m Config file /etc/hysteria/users/users.json not found." + fi +} + +# Call the function with the provided username argument +remove_user "$1" diff --git a/menu.sh b/menu.sh index b8fe0b6..ef317d9 100644 --- a/menu.sh +++ b/menu.sh @@ -97,54 +97,6 @@ modify_users() { } - -# Function to remove a user from the configuration -remove_user() { - if [ -f "/etc/hysteria/users/users.json" ]; then - # Extract current users from the users.json file - users=$(jq -r 'keys[]' /etc/hysteria/users/users.json) - - if [ -z "$users" ]; then - echo "No users found." - return - fi - - # Display current users with numbering - echo "Current users:" - echo "-----------------" - i=1 - for user in $users; do - echo "$i. $user" - ((i++)) - done - echo "-----------------" - - read -p "Enter the number of the user to remove: " selected_number - - if ! [[ "$selected_number" =~ ^[0-9]+$ ]]; then - echo "${red}Error:${NC} Invalid input. Please enter a number." - return - fi - - if [ "$selected_number" -lt 1 ] || [ "$selected_number" -gt "$i" ]; then - echo "${red}Error:${NC} Invalid selection. Please enter a number within the range." - return - fi - - selected_user=$(echo "$users" | sed -n "${selected_number}p") - - jq --arg selected_user "$selected_user" 'del(.[$selected_user])' /etc/hysteria/users/users.json > /etc/hysteria/users/users_temp.json && mv /etc/hysteria/users/users_temp.json /etc/hysteria/users/users.json - - if [ -f "/etc/hysteria/traffic_data.json" ]; then - jq --arg selected_user "$selected_user" 'del(.[$selected_user])' /etc/hysteria/traffic_data.json > /etc/hysteria/traffic_data_temp.json && mv /etc/hysteria/traffic_data_temp.json /etc/hysteria/traffic_data.json - fi - - restart_hysteria_service >/dev/null 2>&1 - echo "User $selected_user removed successfully." - else - echo "${red}Error:${NC} Config file /etc/hysteria/traffic_data.json not found." - fi -} # Function to display the main menu display_main_menu() { clear From 8bb000565a40b30cff89b2d84ce2346549d5aded Mon Sep 17 00:00:00 2001 From: Sarina Date: Sun, 21 Jul 2024 18:18:54 +0330 Subject: [PATCH 17/91] Remove traffic_status in menu.sh --- menu.sh | 42 ------------------------------------------ 1 file changed, 42 deletions(-) diff --git a/menu.sh b/menu.sh index ef317d9..f0ca386 100644 --- a/menu.sh +++ b/menu.sh @@ -37,48 +37,6 @@ get_system_info() { RAM=$(free -m | awk 'NR==2{printf "%.2f%%", $3*100/$2 }') } -# Function to check traffic status for each user -traffic_status() { - if [ -f "/etc/hysteria/traffic.py" ]; then - python3 /etc/hysteria/traffic.py >/dev/null 2>&1 - else - echo "Error: /etc/hysteria/traffic.py not found." - return 1 - fi - - if [ ! -f "/etc/hysteria/traffic_data.json" ]; then - echo "Error: /etc/hysteria/traffic_data.json not found." - return 1 - fi - - data=$(cat /etc/hysteria/traffic_data.json) - echo "Traffic Data:" - echo "---------------------------------------------------------------------------" - echo -e "User Upload (TX) Download (RX) Status" - echo "---------------------------------------------------------------------------" - - echo "$data" | jq -r 'to_entries[] | [.key, .value.upload_bytes, .value.download_bytes, .value.status] | @tsv' | while IFS=$'\t' read -r user upload_bytes download_bytes status; do - if [ $(echo "$upload_bytes < 1073741824" | bc -l) -eq 1 ]; then - upload=$(echo "scale=2; $upload_bytes / 1024 / 1024" | bc) - upload_unit="MB" - else - upload=$(echo "scale=2; $upload_bytes / 1024 / 1024 / 1024" | bc) - upload_unit="GB" - fi - - if [ $(echo "$download_bytes < 1073741824" | bc -l) -eq 1 ]; then - download=$(echo "scale=2; $download_bytes / 1024 / 1024" | bc) - download_unit="MB" - else - download=$(echo "scale=2; $download_bytes / 1024 / 1024 / 1024" | bc) - download_unit="GB" - fi - - printf "${yellow}%-15s ${cyan}%-15s ${green}%-15s ${NC}%-10s\n" "$user" "$(printf "%.2f%s" "$upload" "$upload_unit")" "$(printf "%.2f%s" "$download" "$download_unit")" "$status" - echo "---------------------------------------------------------------------------" - done -} - # TODO: remove # Function to restart Hysteria2 service restart_hysteria_service() { From 7afe429bc96fffedcb3f25458fac65cbe26e5a5c Mon Sep 17 00:00:00 2001 From: Sarina Date: Sun, 21 Jul 2024 18:24:16 +0330 Subject: [PATCH 18/91] Modify restart-hysteria2 --- core/cli.py | 5 ----- core/scripts/hysteria2/restart.sh | 3 +++ 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/core/cli.py b/core/cli.py index 82f98ba..46dc3f4 100644 --- a/core/cli.py +++ b/core/cli.py @@ -71,11 +71,6 @@ def update_hysteria2(): @cli.command('restart-hysteria2') def restart_hysteria2(): - # save traffic status before restarting hysteria2 - # ignore the traffic_status prints - f = io.StringIO() - with redirect_stdout(f): - traffic.traffic_status() run_cmd(['bash', Command.RESTART_HYSTERIA2]) diff --git a/core/scripts/hysteria2/restart.sh b/core/scripts/hysteria2/restart.sh index 315a734..fa4be6c 100644 --- a/core/scripts/hysteria2/restart.sh +++ b/core/scripts/hysteria2/restart.sh @@ -1 +1,4 @@ +#!/bin/bash + +python3 /etc/hysteria/core/cli.py traffic-status > /dev/null 2>&1 systemctl restart hysteria-server.service \ No newline at end of file From 0ae8f882e1566993469d487215c50cb8b6fc00b5 Mon Sep 17 00:00:00 2001 From: Sarina Date: Sun, 21 Jul 2024 18:25:25 +0330 Subject: [PATCH 19/91] Remove restart_hysteria_service from menu.sh --- menu.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/menu.sh b/menu.sh index f0ca386..4c7d617 100644 --- a/menu.sh +++ b/menu.sh @@ -37,12 +37,6 @@ get_system_info() { RAM=$(free -m | awk 'NR==2{printf "%.2f%%", $3*100/$2 }') } -# TODO: remove -# Function to restart Hysteria2 service -restart_hysteria_service() { - python3 /etc/hysteria/traffic.py >/dev/null 2>&1 - systemctl restart hysteria-server.service -} # Function to modify users modify_users() { From 8ea571eb1b0cabbf9de083f73825e3a00955cad8 Mon Sep 17 00:00:00 2001 From: Sarina Date: Sun, 21 Jul 2024 18:28:02 +0330 Subject: [PATCH 20/91] Remove dependency to restart_hysteria_service function instead use cli.py restart-hysteria2 --- core/scripts/hysteria2/add_user.sh | 2 +- core/scripts/hysteria2/change_port.sh | 2 +- core/scripts/hysteria2/remove_user.sh | 2 +- core/scripts/hysteria2/update.sh | 4 ++-- core/scripts/warp/configure.sh | 2 +- core/scripts/warp/install.sh | 2 +- core/scripts/warp/uninstall.sh | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/core/scripts/hysteria2/add_user.sh b/core/scripts/hysteria2/add_user.sh index 36ecf34..92bd35e 100644 --- a/core/scripts/hysteria2/add_user.sh +++ b/core/scripts/hysteria2/add_user.sh @@ -31,7 +31,7 @@ add_user() { '.[$username] = {password: $password, max_download_bytes: $traffic, expiration_days: $expiration_days, account_creation_date: $creation_date, blocked: false}' \ /etc/hysteria/users/users.json > /etc/hysteria/users/users_temp.json && mv /etc/hysteria/users/users_temp.json /etc/hysteria/users/users.json - restart_hysteria_service >/dev/null 2>&1 + python3 /etc/hysteria/core/cli.py restart-hysteria2 > /dev/null 2>&1 echo -e "\033[0;32mUser $username added successfully.\033[0m" } diff --git a/core/scripts/hysteria2/change_port.sh b/core/scripts/hysteria2/change_port.sh index 66d33fc..76bcb56 100644 --- a/core/scripts/hysteria2/change_port.sh +++ b/core/scripts/hysteria2/change_port.sh @@ -9,7 +9,7 @@ done if [ -f "/etc/hysteria/config.json" ]; then jq --arg port "$port" '.listen = ":" + $port' /etc/hysteria/config.json > /etc/hysteria/config_temp.json && mv /etc/hysteria/config_temp.json /etc/hysteria/config.json - restart_hysteria_service >/dev/null 2>&1 + python3 /etc/hysteria/core/cli.py restart-hysteria2 > /dev/null 2>&1 echo "Port changed successfully to $port." else echo "${red}Error:${NC} Config file /etc/hysteria/config.json not found." diff --git a/core/scripts/hysteria2/remove_user.sh b/core/scripts/hysteria2/remove_user.sh index 89ea1f2..628ff6e 100644 --- a/core/scripts/hysteria2/remove_user.sh +++ b/core/scripts/hysteria2/remove_user.sh @@ -18,7 +18,7 @@ remove_user() { jq --arg username "$username" 'del(.[$username])' /etc/hysteria/traffic_data.json > /etc/hysteria/traffic_data_temp.json && mv /etc/hysteria/traffic_data_temp.json /etc/hysteria/traffic_data.json fi - restart_hysteria_service >/dev/null 2>&1 + python3 /etc/hysteria/core/cli.py restart-hysteria2 > /dev/null 2>&1 echo "User $username removed successfully." else echo -e "\033[0;31mError:\033[0m User $username not found." diff --git a/core/scripts/hysteria2/update.sh b/core/scripts/hysteria2/update.sh index 606edc2..0c0a4e2 100644 --- a/core/scripts/hysteria2/update.sh +++ b/core/scripts/hysteria2/update.sh @@ -11,7 +11,7 @@ bash <(curl -fsSL https://get.hy2.sh/) >/dev/null 2>&1 if [ $? -ne 0 ]; then echo "${red}Error:${NC} Failed to download or install the latest version. Restoring backup configuration." mv /etc/hysteria/config_backup.json /etc/hysteria/config.json - restart_hysteria_service >/dev/null 2>&1 + python3 /etc/hysteria/core/cli.py restart-hysteria2 > /dev/null 2>&1 return 1 fi @@ -31,7 +31,7 @@ fi rm /etc/hysteria/config.yaml systemctl daemon-reload >/dev/null 2>&1 -restart_hysteria_service >/dev/null 2>&1 +python3 /etc/hysteria/core/cli.py restart-hysteria2 > /dev/null 2>&1 if [ $? -ne 0 ]; then echo "${red}Error:${NC} Failed to restart Hysteria2 service." return 1 diff --git a/core/scripts/warp/configure.sh b/core/scripts/warp/configure.sh index b2b15a5..a827275 100644 --- a/core/scripts/warp/configure.sh +++ b/core/scripts/warp/configure.sh @@ -68,7 +68,7 @@ if [ -f "$CONFIG_FILE" ]; then echo "Invalid option. Please try again." ;; esac - restart_hysteria_service >/dev/null 2>&1 + python3 /etc/hysteria/core/cli.py restart-hysteria2 > /dev/null 2>&1 else echo "${red}Error:${NC} Config file $CONFIG_FILE not found." fi \ No newline at end of file diff --git a/core/scripts/warp/install.sh b/core/scripts/warp/install.sh index 42403ed..0cb0327 100644 --- a/core/scripts/warp/install.sh +++ b/core/scripts/warp/install.sh @@ -10,7 +10,7 @@ else # Add the outbound configuration to the config.json file jq '.outbounds += [{"name": "warps", "type": "direct", "direct": {"mode": 4, "bindDevice": "wgcf"}}]' /etc/hysteria/config.json > /etc/hysteria/config_temp.json && mv /etc/hysteria/config_temp.json /etc/hysteria/config.json # Restart the hysteria-server service - restart_hysteria_service >/dev/null 2>&1 + python3 /etc/hysteria/core/cli.py restart-hysteria2 > /dev/null 2>&1 echo "WARP installed and outbound added to config.json." else echo "${red}Error:${NC} Config file /etc/hysteria/config.json not found." diff --git a/core/scripts/warp/uninstall.sh b/core/scripts/warp/uninstall.sh index f8d8cd0..ae87a35 100644 --- a/core/scripts/warp/uninstall.sh +++ b/core/scripts/warp/uninstall.sh @@ -20,7 +20,7 @@ if systemctl is-active --quiet wg-quick@wgcf.service; then ' /etc/hysteria/config.json > /etc/hysteria/config_temp.json && mv /etc/hysteria/config_temp.json /etc/hysteria/config.json jq 'del(.outbounds[] | select(.name == "warps" and .type == "direct" and .direct.mode == 4 and .direct.bindDevice == "wgcf"))' /etc/hysteria/config.json > /etc/hysteria/config_temp.json && mv /etc/hysteria/config_temp.json /etc/hysteria/config.json - restart_hysteria_service >/dev/null 2>&1 + python3 /etc/hysteria/core/cli.py restart-hysteria2 > /dev/null 2>&1 echo "WARP uninstalled and configurations reset to default." else echo "${red}Error:${NC} Config file /etc/hysteria/config.json not found." From 04ae67929466508674431a95e689f435fefad373 Mon Sep 17 00:00:00 2001 From: Sarina Date: Sun, 21 Jul 2024 18:46:02 +0330 Subject: [PATCH 21/91] Lil refactor --- core/scripts/hysteria2/install.sh | 10 ++-------- core/scripts/utils.sh | 10 ++++++++++ menu.sh | 18 +++++------------- 3 files changed, 17 insertions(+), 21 deletions(-) create mode 100644 core/scripts/utils.sh diff --git a/core/scripts/hysteria2/install.sh b/core/scripts/hysteria2/install.sh index 0a46aa2..ae54d23 100644 --- a/core/scripts/hysteria2/install.sh +++ b/core/scripts/hysteria2/install.sh @@ -1,13 +1,7 @@ #!/bin/bash -define_colors() { - green='\033[0;32m' - cyan='\033[0;36m' - red='\033[0;31m' - yellow='\033[0;33m' - LPurple='\033[1;35m' - NC='\033[0m' -} +source /etc/hysteria/core/scripts/utils.sh +define_colors install_hysteria() { # Step 1: Install Hysteria2 diff --git a/core/scripts/utils.sh b/core/scripts/utils.sh new file mode 100644 index 0000000..799109b --- /dev/null +++ b/core/scripts/utils.sh @@ -0,0 +1,10 @@ + +# Function to define colors +define_colors() { + green='\033[0;32m' + cyan='\033[0;36m' + red='\033[0;31m' + yellow='\033[0;33m' + LPurple='\033[1;35m' + NC='\033[0m' # No Color +} \ No newline at end of file diff --git a/menu.sh b/menu.sh index 4c7d617..08224b0 100644 --- a/menu.sh +++ b/menu.sh @@ -1,14 +1,6 @@ #!/bin/bash -# Function to define colors -define_colors() { - green='\033[0;32m' - cyan='\033[0;36m' - red='\033[0;31m' - yellow='\033[0;33m' - LPurple='\033[1;35m' - NC='\033[0m' # No Color -} +source /etc/hysteria/core/scripts/utils.sh # Ensure necessary packages are installed clear @@ -20,8 +12,8 @@ if ! command -v jq &> /dev/null || ! command -v qrencode &> /dev/null || ! comma fi # Add alias 'hys2' for Hysteria2 -if ! grep -q "alias hys2='bash <(curl https://raw.githubusercontent.com/H-Return/Hysteria2/main/menu.sh)'" ~/.bashrc; then - echo "alias hys2='bash <(curl https://raw.githubusercontent.com/H-Return/Hysteria2/main/menu.sh)'" >> ~/.bashrc +if ! grep -q "alias hys2='/etc/hysteria/menu.sh'" ~/.bashrc; then + echo "alias hys2='/etc/hysteria/menu.sh'" >> ~/.bashrc source ~/.bashrc fi @@ -124,11 +116,11 @@ hysteria2_menu() { display_hysteria2_menu read -r choice case $choice in - 1) install_and_configure ;; + 1) python3 /etc/hysteria/core/cli.py install-hysteria2 ;; 2) add_user ;; 3) modify_users ;; 4) show_uri ;; - 5) traffic_status ;; + 5) python3 /etc/hysteria2/core/cli.py traffic_status ;; 6) remove_user ;; 0) return ;; *) echo "Invalid option. Please try again." ;; From 5874cc525d674e90664c990e7ea365ebb1fab99e Mon Sep 17 00:00:00 2001 From: Sarina Date: Sun, 21 Jul 2024 19:01:21 +0330 Subject: [PATCH 22/91] Add install script --- install.sh | 26 ++++++++++++++++++++++++++ menu.sh | 15 --------------- 2 files changed, 26 insertions(+), 15 deletions(-) create mode 100644 install.sh diff --git a/install.sh b/install.sh new file mode 100644 index 0000000..463775a --- /dev/null +++ b/install.sh @@ -0,0 +1,26 @@ +# Ensure necessary packages are installed +# Check if the script is being run by the root user +if [ "$(id -u)" -ne 0 ]; then + echo "This script must be run as root." + exit 1 +fi + +clear +if ! command -v jq &> /dev/null || ! command -v git &> /dev/null || ! command -v qrencode &> /dev/null || ! command -v curl &> /dev/null; then + echo "${yellow}Necessary packages are not installed. Please wait while they are being installed..." + sleep 3 + echo + apt update && apt upgrade -y && apt install jq qrencode curl pwgen uuid-runtime python3 python3-pip git -y +fi + +# Add alias 'hys2' for Hysteria2 +if ! grep -q "alias hys2='/etc/hysteria/menu.sh'" ~/.bashrc; then + echo "alias hys2='/etc/hysteria/menu.sh'" >> ~/.bashrc + source ~/.bashrc +fi + +git clone https://github.com/ReturnFI/Hysteria2 /etc/hysteria + +cd /etc/hysteria +chmod +x menu.sh +./menu.sh diff --git a/menu.sh b/menu.sh index 08224b0..0b10bf0 100644 --- a/menu.sh +++ b/menu.sh @@ -2,21 +2,6 @@ source /etc/hysteria/core/scripts/utils.sh -# Ensure necessary packages are installed -clear -if ! command -v jq &> /dev/null || ! command -v qrencode &> /dev/null || ! command -v curl &> /dev/null; then - echo "${yellow}Necessary packages are not installed. Please wait while they are being installed..." - sleep 3 - echo - apt update && apt upgrade -y && apt install jq qrencode curl pwgen uuid-runtime python3 python3-pip -y -fi - -# Add alias 'hys2' for Hysteria2 -if ! grep -q "alias hys2='/etc/hysteria/menu.sh'" ~/.bashrc; then - echo "alias hys2='/etc/hysteria/menu.sh'" >> ~/.bashrc - source ~/.bashrc -fi - # Function to get system information get_system_info() { OS=$(lsb_release -d | awk -F'\t' '{print $2}') From ad6911ed66becec6b11e814e8e4441c474b2a22f Mon Sep 17 00:00:00 2001 From: Sarina Date: Sun, 21 Jul 2024 19:03:24 +0330 Subject: [PATCH 23/91] Refactor menu.sh --- menu.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/menu.sh b/menu.sh index 0b10bf0..6b1b9cb 100644 --- a/menu.sh +++ b/menu.sh @@ -53,7 +53,6 @@ main_menu() { clear local choice while true; do - define_colors get_system_info display_main_menu read -r choice @@ -96,7 +95,6 @@ hysteria2_menu() { clear local choice while true; do - define_colors get_system_info display_hysteria2_menu read -r choice @@ -120,7 +118,6 @@ advance_menu() { clear local choice while true; do - define_colors display_advance_menu read -r choice case $choice in @@ -162,5 +159,6 @@ main() { main_menu } +define_colors # Run the main function main From 9a2420c82a3ce9f98cc5c3ded60d392f52cdbf06 Mon Sep 17 00:00:00 2001 From: Sarina Date: Sun, 21 Jul 2024 19:16:45 +0330 Subject: [PATCH 24/91] Refactor menu.sh --- core/scripts/utils.sh | 12 ++++++ menu.sh | 86 ++++++++++++++++++++++++------------------- 2 files changed, 60 insertions(+), 38 deletions(-) diff --git a/core/scripts/utils.sh b/core/scripts/utils.sh index 799109b..3e261d8 100644 --- a/core/scripts/utils.sh +++ b/core/scripts/utils.sh @@ -7,4 +7,16 @@ define_colors() { yellow='\033[0;33m' LPurple='\033[1;35m' NC='\033[0m' # No Color +} + +# Function to get system information +get_system_info() { + OS=$(lsb_release -d | awk -F'\t' '{print $2}') + ARCH=$(uname -m) + # Fetching detailed IP information in JSON format + IP_API_DATA=$(curl -s https://ipapi.co/json/ -4) + ISP=$(echo "$IP_API_DATA" | jq -r '.org') + IP=$(echo "$IP_API_DATA" | jq -r '.ip') + CPU=$(top -bn1 | grep "Cpu(s)" | awk '{print $2 + $4 "%"}') + RAM=$(free -m | awk 'NR==2{printf "%.2f%%", $3*100/$2 }') } \ No newline at end of file diff --git a/menu.sh b/menu.sh index 6b1b9cb..4aa8acd 100644 --- a/menu.sh +++ b/menu.sh @@ -2,21 +2,27 @@ source /etc/hysteria/core/scripts/utils.sh -# Function to get system information -get_system_info() { - OS=$(lsb_release -d | awk -F'\t' '{print $2}') - ARCH=$(uname -m) - # Fetching detailed IP information in JSON format - IP_API_DATA=$(curl -s https://ipapi.co/json/ -4) - ISP=$(echo "$IP_API_DATA" | jq -r '.org') - IP=$(echo "$IP_API_DATA" | jq -r '.ip') - CPU=$(top -bn1 | grep "Cpu(s)" | awk '{print $2 + $4 "%"}') - RAM=$(free -m | awk 'NR==2{printf "%.2f%%", $3*100/$2 }') +# OPTION HANDLERS (ONLY NEEDED ONE) + +hysteria2_add_user_handler() { + +} + +hysteria2_remove_user_handler() { + +} + +hysteria2_show_user_uri_hanndler() { + +} + +hysteria2_change_port_handler() { + } # Function to modify users -modify_users() { +hysteria2_modify_users() { modify_script="/etc/hysteria/users/modify.py" github_raw_url="https://raw.githubusercontent.com/ReturnFI/Hysteria2/main/modify.py" @@ -25,6 +31,10 @@ modify_users() { python3 "$modify_script" } +warp_configure_handler() { + +} + # Function to display the main menu display_main_menu() { @@ -100,34 +110,11 @@ hysteria2_menu() { read -r choice case $choice in 1) python3 /etc/hysteria/core/cli.py install-hysteria2 ;; - 2) add_user ;; - 3) modify_users ;; - 4) show_uri ;; + 2) hysteria2_add_user_handler ;; + 3) hysteria2_modify_users ;; + 4) hysteria2_show_user_uri_hanndler ;; 5) python3 /etc/hysteria2/core/cli.py traffic_status ;; - 6) remove_user ;; - 0) return ;; - *) echo "Invalid option. Please try again." ;; - esac - echo - read -rp "Press Enter to continue..." - done -} - -# Function to handle Advance menu options -advance_menu() { - clear - local choice - while true; do - display_advance_menu - read -r choice - case $choice in - 1) install_tcp_brutal ;; - 2) install_warp ;; - 3) configure_warp ;; - 4) uninstall_warp ;; - 5) change_port ;; - 6) update_core ;; - 7) uninstall_hysteria ;; + 6) hysteria2_remove_user_handler ;; 0) return ;; *) echo "Invalid option. Please try again." ;; esac @@ -154,6 +141,29 @@ display_advance_menu() { echo -ne "${yellow}➜ Enter your option: ${NC}" } +# Function to handle Advance menu options +advance_menu() { + clear + local choice + while true; do + display_advance_menu + read -r choice + case $choice in + 1) python3 /etc/hysteria/core/cli.py install-tcp-brutal ;; + 2) python3 /etc/hysteria/core/cli.py install-warp ;; + 3) warp_configure_handler ;; + 4) python3 /etc/hysteria/core/cli.py uninstall-warp ;; + 5) hysteria2_change_port_handler ;; + 6) python3 /etc/hysteria/core/cli.py update-hysteria2 ;; + 7) python3 /etc/hysteria/core/cli.py uninstall-hysteria2 ;; + 0) return ;; + *) echo "Invalid option. Please try again." ;; + esac + echo + read -rp "Press Enter to continue..." + done +} + # Main function to run the script main() { main_menu From 70ada7dc273d36007e2bd60b8ec614d18bb9d6bd Mon Sep 17 00:00:00 2001 From: Sarina Date: Sun, 21 Jul 2024 19:29:45 +0330 Subject: [PATCH 25/91] Improve add_user.sh --- core/scripts/hysteria2/add_user.sh | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/core/scripts/hysteria2/add_user.sh b/core/scripts/hysteria2/add_user.sh index 92bd35e..9fcfe98 100644 --- a/core/scripts/hysteria2/add_user.sh +++ b/core/scripts/hysteria2/add_user.sh @@ -10,6 +10,26 @@ add_user() { username=$1 traffic_gb=$2 expiration_days=$3 + password=$4 + if [ -z "$password" ]; then + password=$(pwgen -s 32 1) + fi + creation_date=$5 + # Check if the creation_date is empty + if [ -z "$creation_date" ]; then + creation_date=$(date +%Y-%m-%d) + else + # Validate the date format (YYYY-MM-DD) + if ! [[ "$creation_date" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]; then + echo "Invalid date format. Expected YYYY-MM-DD." + exit 1 + fi + # Check if the date is valid + if ! date -d "$creation_date" >/dev/null 2>&1; then + echo "Invalid date. Please provide a valid date in YYYY-MM-DD format." + exit 1 + fi + fi # Validate the username if ! [[ "$username" =~ ^[a-z0-9]+$ ]]; then @@ -20,8 +40,6 @@ add_user() { # Convert GB to bytes (1 GB = 1073741824 bytes) traffic=$((traffic_gb * 1073741824)) - password=$(pwgen -s 32 1) - creation_date=$(date +%Y-%m-%d) if [ ! -f "/etc/hysteria/users/users.json" ]; then echo "{}" > /etc/hysteria/users/users.json @@ -37,4 +55,4 @@ add_user() { } # Call the function with the provided arguments -add_user "$1" "$2" "$3" +add_user "$1" "$2" "$3" "$4" "$5" From 44f7b51eefea15353bdd3a11c40cda0f97dc44f4 Mon Sep 17 00:00:00 2001 From: Sarina Date: Sun, 21 Jul 2024 19:35:59 +0330 Subject: [PATCH 26/91] Improve add_user command in cli.py --- core/cli.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/core/cli.py b/core/cli.py index 46dc3f4..4c4f025 100644 --- a/core/cli.py +++ b/core/cli.py @@ -1,5 +1,6 @@ #!/usr/bin/env python3 +from datetime import datetime import os import io import click @@ -83,8 +84,19 @@ def change_hysteria2_port(port:int): @click.option('--username','-u', required=True, help='Username for the new user',type=str) @click.option('--traffic-limit','-t', required=True, help='Traffic limit for the new user in GB',type=float) @click.option('--expiration-days','-e', required=True, help='Expiration days for the new user',type=int) -def add_user(username:str, traffic_limit:float, expiration_days:int): - run_cmd(['bash', Command.ADD_USER, username, str(traffic_limit), str(expiration_days)]) +@click.option('--password','-p',required=False, help='Password for the user',type=str) +@click.option('--creation-date','-c',required=False, help='Creation date for the user',type=str) +def add_user(username:str, traffic_limit:float, expiration_days:int,password:str,creation_date:str): + if not password: + try: + password = generate_password() + except subprocess.CalledProcessError as e: + print(f'Error: failed to generate password\n{e}') + exit(1) + if not creation_date: + creation_date = datetime.now().strftime('%Y-%m-%d') + + run_cmd(['bash', Command.ADD_USER, username, str(traffic_limit), str(expiration_days), password, creation_date]) @cli.command('edit-user') @click.option('--username','-u', required=True, help='Username for the user to edit',type=str) From 6f76b9717cd33b156fa16a11955c3b771c184cd9 Mon Sep 17 00:00:00 2001 From: Sarina Date: Sun, 21 Jul 2024 20:36:31 +0330 Subject: [PATCH 27/91] Fix change_port.sh --- core/scripts/hysteria2/change_port.sh | 30 ++++++++++++++++----------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/core/scripts/hysteria2/change_port.sh b/core/scripts/hysteria2/change_port.sh index 76bcb56..be7bd31 100644 --- a/core/scripts/hysteria2/change_port.sh +++ b/core/scripts/hysteria2/change_port.sh @@ -1,16 +1,22 @@ -while true; do - read -p "Enter the new port number you want to use: " port +# Function to update port number in configuration +update_port() { + local port=$1 + + # Validate the port number if ! [[ "$port" =~ ^[0-9]+$ ]] || [ "$port" -lt 1 ] || [ "$port" -gt 65535 ]; then echo "Invalid port number. Please enter a number between 1 and 65535." - else - break + return 1 fi -done -if [ -f "/etc/hysteria/config.json" ]; then - jq --arg port "$port" '.listen = ":" + $port' /etc/hysteria/config.json > /etc/hysteria/config_temp.json && mv /etc/hysteria/config_temp.json /etc/hysteria/config.json - python3 /etc/hysteria/core/cli.py restart-hysteria2 > /dev/null 2>&1 - echo "Port changed successfully to $port." -else - echo "${red}Error:${NC} Config file /etc/hysteria/config.json not found." -fi \ No newline at end of file + # Check if the config file exists and update the port number + if [ -f "/etc/hysteria/config.json" ]; then + jq --arg port "$port" '.listen = ":" + $port' /etc/hysteria/config.json > /etc/hysteria/config_temp.json && mv /etc/hysteria/config_temp.json /etc/hysteria/config.json + python3 /etc/hysteria/core/cli.py restart-hysteria2 > /dev/null 2>&1 + echo "Port changed successfully to $port." + else + echo "Error: Config file /etc/hysteria/config.json not found." + return 1 + fi +} + +update_port "$1" \ No newline at end of file From 11e206e16f45f20c0d8c0460052859ec22d097a5 Mon Sep 17 00:00:00 2001 From: Sarina Date: Sun, 21 Jul 2024 20:54:19 +0330 Subject: [PATCH 28/91] Fix cli.py install-hysteria2 --- core/cli.py | 9 +++++---- core/validator.py | 10 ++++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 core/validator.py diff --git a/core/cli.py b/core/cli.py index 4c4f025..26ab005 100644 --- a/core/cli.py +++ b/core/cli.py @@ -6,9 +6,9 @@ import io import click import subprocess from enum import StrEnum -from contextlib import redirect_stdout import traffic +import validator SCRIPT_DIR = 'scripts' DEBUG = True @@ -58,8 +58,9 @@ def cli(): # region hysteria2 menu options @cli.command('install-hysteria2') -def install_hysteria2(): - run_cmd(['bash', Command.INSTALL_HYSTERIA2]) +@click.option('--port','-p', required=True, help='New port for Hysteria2',type=int,validate=validator.validate_port) +def install_hysteria2(port:int): + run_cmd(['bash', Command.INSTALL_HYSTERIA2, str(port)]) @cli.command('uninstall-hysteria2') @@ -76,7 +77,7 @@ def restart_hysteria2(): @cli.command('change-hysteria2-port') -@click.option('--port','-p', required=True, help='New port for Hysteria2',type=int) +@click.option('--port','-p', required=True, help='New port for Hysteria2',type=int,validate=validator.validate_port) def change_hysteria2_port(port:int): run_cmd(['bash', Command.CHANGE_PORT_HYSTERIA2, str(port)]) diff --git a/core/validator.py b/core/validator.py new file mode 100644 index 0000000..1ede3d4 --- /dev/null +++ b/core/validator.py @@ -0,0 +1,10 @@ +import os + + +def validate_port(p:int)-> bool: + if p < 1 or p > 65535: + return False + # check if port is in use + if os.system(f'lsof -i:{p}') == 0: + return False + return True \ No newline at end of file From f5367ec89ee1087185adc0a9c264bcba58eaf8fd Mon Sep 17 00:00:00 2001 From: Sarina Date: Sun, 21 Jul 2024 21:10:46 +0330 Subject: [PATCH 29/91] Improve hysteria2/install.sh --- core/scripts/hysteria2/install.sh | 53 ++++++++++++++----------------- 1 file changed, 24 insertions(+), 29 deletions(-) diff --git a/core/scripts/hysteria2/install.sh b/core/scripts/hysteria2/install.sh index ae54d23..c8d1e26 100644 --- a/core/scripts/hysteria2/install.sh +++ b/core/scripts/hysteria2/install.sh @@ -34,27 +34,26 @@ install_hysteria() { sha256=$(python3 generate.py) + # WE CLONED THE REPO, SO WE HAVE THE config.json ALREADY # Step 6: Download the config.json file - echo "Downloading config.json..." - wget https://raw.githubusercontent.com/ReturnFI/Hysteria2/main/config.json -O /etc/hysteria/config.json >/dev/null 2>&1 - echo + # echo "Downloading config.json..." + # wget https://raw.githubusercontent.com/ReturnFI/Hysteria2/main/config.json -O /etc/hysteria/config.json >/dev/null 2>&1 + # echo # Step 7: Ask for the port number and validate input - while true; do - read -p "Enter the port number you want to use (1-65535): " port - if [[ $port =~ ^[0-9]+$ ]] && (( port >= 1 && port <= 65535 )); then - # Check if the port is in use - if ss -tuln | grep -q ":$port\b"; then - clear - echo -e "\e[91mPort $port is already in use. Please choose another port.\e[0m" - echo - else - break - fi + port=$1 + if [[ $port =~ ^[0-9]+$ ]] && (( port >= 1 && port <= 65535 )); then + # Check if the port is in use + if ss -tuln | grep -q ":$port\b"; then + echo -e "\e[91mPort $port is already in use. Please choose another port.\e[0m" + exit 1 else - echo "Invalid port number. Please enter a number between 1 and 65535." + break fi - done + else + echo "Invalid port number. Please enter a number between 1 and 65535." + exit 1 + fi # Step 8: Generate required passwords and UUID echo "Generating passwords and UUID..." @@ -107,20 +106,16 @@ install_hysteria() { echo "${cyan}Hysteria2${green} has been successfully install." else echo "${red}Error:${NC} hysteria-server.service is not active." + exit 1 fi - # Step 15: wget Traffic/user/kick script - wget https://raw.githubusercontent.com/ReturnFI/Hysteria2/main/traffic.py -O /etc/hysteria/traffic.py >/dev/null 2>&1 - mkdir -p /etc/hysteria/users - wget https://raw.githubusercontent.com/ReturnFI/Hysteria2/main/user.sh -O /etc/hysteria/users/user.sh >/dev/null 2>&1 - wget https://raw.githubusercontent.com/ReturnFI/Hysteria2/main/kick.sh -O /etc/hysteria/users/kick.sh >/dev/null 2>&1 - wget https://raw.githubusercontent.com/ReturnFI/Hysteria2/main/modify.py -O /etc/hysteria/users/modify.py >/dev/null 2>&1 - - chmod +x /etc/hysteria/users/user.sh - chmod +x /etc/hysteria/users/kick.sh - # Add the commands to the crontab - (crontab -l ; echo "*/1 * * * * python3 /etc/hysteria/traffic.py >/dev/null 2>&1") | crontab - - (crontab -l ; echo "*/1 * * * * /etc/hysteria/users/kick.sh >/dev/null 2>&1") | crontab - + # Step 15: Give right permissions to scripts + chmod +x /etc/hysteria/core/scripts/hysteria2/user.sh + chmod +x /etc/hysteria/core/scripts/hysteria2/kick.sh + + # Add the scripts to the crontab + (crontab -l ; echo "*/1 * * * * python3 /etc/hysteria/core/cli.py traffic-status >/dev/null 2>&1") | crontab - + (crontab -l ; echo "*/1 * * * * /etc/hysteria/core/scripts/hysteria2/kick.sh >/dev/null 2>&1") | crontab - } @@ -136,7 +131,7 @@ if systemctl is-active --quiet hysteria-server.service; then echo "If you need to update the core, please use the 'Update Core' option." else echo "Installing and configuring Hysteria2..." - install_hysteria + install_hysteria "$1" echo -e "\n" if systemctl is-active --quiet hysteria-server.service; then From 2c9128b0ca1ae029380cb57983374ea2ce1d6c76 Mon Sep 17 00:00:00 2001 From: Sarina Date: Sun, 21 Jul 2024 21:13:14 +0330 Subject: [PATCH 30/91] Fix path in config.json --- config.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config.json b/config.json index fd9d9d4..81afeba 100644 --- a/config.json +++ b/config.json @@ -14,7 +14,7 @@ }, "auth": { "type": "command", - "command": "/etc/hysteria/users/user.sh" + "command": "/etc/hysteria/core/scripts/hysteria2/user.sh" }, "quic": { "initStreamReceiveWindow": 8388608, @@ -80,4 +80,4 @@ "listen": "127.0.0.1:25413", "secret": "$UUID" } -} +} \ No newline at end of file From 71d8c165a3ba21483462bd6ab4a3dd4c14f52d55 Mon Sep 17 00:00:00 2001 From: Sarina Date: Sun, 21 Jul 2024 21:14:36 +0330 Subject: [PATCH 31/91] Move kick.sh and user.sh --- kick.sh => core/scripts/hysteria2/kick.sh | 0 user.sh => core/scripts/hysteria2/user.sh | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename kick.sh => core/scripts/hysteria2/kick.sh (100%) rename user.sh => core/scripts/hysteria2/user.sh (100%) diff --git a/kick.sh b/core/scripts/hysteria2/kick.sh similarity index 100% rename from kick.sh rename to core/scripts/hysteria2/kick.sh diff --git a/user.sh b/core/scripts/hysteria2/user.sh similarity index 100% rename from user.sh rename to core/scripts/hysteria2/user.sh From 484821c499582e49270efa404a0e65290ec5419e Mon Sep 17 00:00:00 2001 From: Sarina Date: Sun, 21 Jul 2024 21:18:16 +0330 Subject: [PATCH 32/91] Fix path in uninstall.sh --- core/scripts/hysteria2/uninstall.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/scripts/hysteria2/uninstall.sh b/core/scripts/hysteria2/uninstall.sh index 88fe0d3..5265833 100644 --- a/core/scripts/hysteria2/uninstall.sh +++ b/core/scripts/hysteria2/uninstall.sh @@ -17,8 +17,8 @@ echo "Reloading systemd daemon..." systemctl daemon-reload >/dev/null 2>&1 sleep 1 echo "Removing cron jobs..." -(crontab -l | grep -v "python3 /etc/hysteria/traffic.py" | crontab -) >/dev/null 2>&1 -(crontab -l | grep -v "/etc/hysteria/users/kick.sh" | crontab -) >/dev/null 2>&1 +(crontab -l | grep -v "python3 /etc/hysteria/core/cli.py traffic-status" | crontab -) >/dev/null 2>&1 +(crontab -l | grep -v "/etc/hysteria/core/scripts/hysteria2/kick.sh" | crontab -) >/dev/null 2>&1 sleep 1 echo "Hysteria2 uninstalled!" echo "" \ No newline at end of file From 14f61134dc5a536218584f59d958a637109b9019 Mon Sep 17 00:00:00 2001 From: Sarina Date: Sun, 21 Jul 2024 21:32:11 +0330 Subject: [PATCH 33/91] Fix path related issues --- core/scripts/hysteria2/add_user.sh | 6 +++--- core/scripts/hysteria2/install.sh | 2 +- core/scripts/hysteria2/remove_user.sh | 8 ++++---- core/scripts/hysteria2/show_user_uri.sh | 8 ++++---- core/scripts/hysteria2/user.sh | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/core/scripts/hysteria2/add_user.sh b/core/scripts/hysteria2/add_user.sh index 9fcfe98..17c7d59 100644 --- a/core/scripts/hysteria2/add_user.sh +++ b/core/scripts/hysteria2/add_user.sh @@ -41,13 +41,13 @@ add_user() { traffic=$((traffic_gb * 1073741824)) - if [ ! -f "/etc/hysteria/users/users.json" ]; then - echo "{}" > /etc/hysteria/users/users.json + if [ ! -f "/etc/hysteria/users.json" ]; then + echo "{}" > /etc/hysteria/users.json fi jq --arg username "$username" --arg password "$password" --argjson traffic "$traffic" --argjson expiration_days "$expiration_days" --arg creation_date "$creation_date" \ '.[$username] = {password: $password, max_download_bytes: $traffic, expiration_days: $expiration_days, account_creation_date: $creation_date, blocked: false}' \ - /etc/hysteria/users/users.json > /etc/hysteria/users/users_temp.json && mv /etc/hysteria/users/users_temp.json /etc/hysteria/users/users.json + /etc/hysteria/users.json > /etc/hysteria/users_temp.json && mv /etc/hysteria/users_temp.json /etc/hysteria/users.json python3 /etc/hysteria/core/cli.py restart-hysteria2 > /dev/null 2>&1 diff --git a/core/scripts/hysteria2/install.sh b/core/scripts/hysteria2/install.sh index c8d1e26..34cae15 100644 --- a/core/scripts/hysteria2/install.sh +++ b/core/scripts/hysteria2/install.sh @@ -116,7 +116,7 @@ install_hysteria() { # Add the scripts to the crontab (crontab -l ; echo "*/1 * * * * python3 /etc/hysteria/core/cli.py traffic-status >/dev/null 2>&1") | crontab - (crontab -l ; echo "*/1 * * * * /etc/hysteria/core/scripts/hysteria2/kick.sh >/dev/null 2>&1") | crontab - - } +} diff --git a/core/scripts/hysteria2/remove_user.sh b/core/scripts/hysteria2/remove_user.sh index 628ff6e..619617b 100644 --- a/core/scripts/hysteria2/remove_user.sh +++ b/core/scripts/hysteria2/remove_user.sh @@ -9,10 +9,10 @@ remove_user() { username=$1 - if [ -f "/etc/hysteria/users/users.json" ]; then + if [ -f "/etc/hysteria/users.json" ]; then # Check if the username exists in the users.json file - if jq -e "has(\"$username\")" /etc/hysteria/users/users.json > /dev/null; then - jq --arg username "$username" 'del(.[$username])' /etc/hysteria/users/users.json > /etc/hysteria/users/users_temp.json && mv /etc/hysteria/users/users_temp.json /etc/hysteria/users/users.json + if jq -e "has(\"$username\")" /etc/hysteria/users.json > /dev/null; then + jq --arg username "$username" 'del(.[$username])' /etc/hysteria/users.json > /etc/hysteria/users_temp.json && mv /etc/hysteria/users_temp.json /etc/hysteria/users.json if [ -f "/etc/hysteria/traffic_data.json" ]; then jq --arg username "$username" 'del(.[$username])' /etc/hysteria/traffic_data.json > /etc/hysteria/traffic_data_temp.json && mv /etc/hysteria/traffic_data_temp.json /etc/hysteria/traffic_data.json @@ -24,7 +24,7 @@ remove_user() { echo -e "\033[0;31mError:\033[0m User $username not found." fi else - echo -e "\033[0;31mError:\033[0m Config file /etc/hysteria/users/users.json not found." + echo -e "\033[0;31mError:\033[0m Config file /etc/hysteria/users.json not found." fi } diff --git a/core/scripts/hysteria2/show_user_uri.sh b/core/scripts/hysteria2/show_user_uri.sh index 35302b3..0009c2a 100644 --- a/core/scripts/hysteria2/show_user_uri.sh +++ b/core/scripts/hysteria2/show_user_uri.sh @@ -2,7 +2,7 @@ # Function to show URI if Hysteria2 is installed and active show_uri() { - if [ -f "/etc/hysteria/users/users.json" ]; then + if [ -f "/etc/hysteria/users.json" ]; then if systemctl is-active --quiet hysteria-server.service; then # Check if the username is provided as an argument if [ -z "$1" ]; then @@ -13,9 +13,9 @@ show_uri() { username=$1 # Validate the username - if jq -e "has(\"$username\")" /etc/hysteria/users/users.json > /dev/null; then + if jq -e "has(\"$username\")" /etc/hysteria/users.json > /dev/null; then # Get the selected user's details - authpassword=$(jq -r ".\"$username\".password" /etc/hysteria/users/users.json) + authpassword=$(jq -r ".\"$username\".password" /etc/hysteria/users.json) port=$(jq -r '.listen' /etc/hysteria/config.json | cut -d':' -f2) sha256=$(jq -r '.tls.pinSHA256' /etc/hysteria/config.json) obfspassword=$(jq -r '.obfs.salamander.password' /etc/hysteria/config.json) @@ -56,7 +56,7 @@ show_uri() { echo -e "\033[0;31mError:\033[0m Hysteria2 is not active." fi else - echo -e "\033[0;31mError:\033[0m Config file /etc/hysteria/users/users.json not found." + echo -e "\033[0;31mError:\033[0m Config file /etc/hysteria/users.json not found." fi } diff --git a/core/scripts/hysteria2/user.sh b/core/scripts/hysteria2/user.sh index 4e6f115..f20f17c 100644 --- a/core/scripts/hysteria2/user.sh +++ b/core/scripts/hysteria2/user.sh @@ -4,7 +4,7 @@ ADDR="$1" AUTH="$2" TX="$3" -USERS_FILE="/etc/hysteria/users/users.json" +USERS_FILE="/etc/hysteria/users.json" TRAFFIC_FILE="/etc/hysteria/traffic_data.json" CONFIG_FILE="/etc/hysteria/config.json" From a3858b38dca256ba174756f1b134ca6ab97b8ed6 Mon Sep 17 00:00:00 2001 From: Sarina Date: Mon, 22 Jul 2024 13:30:04 +0330 Subject: [PATCH 34/91] Add list users script (empty) --- core/cli.py | 4 ++-- core/scripts/hysteria2/list_users.sh | 0 2 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 core/scripts/hysteria2/list_users.sh diff --git a/core/cli.py b/core/cli.py index 26ab005..9823c6d 100644 --- a/core/cli.py +++ b/core/cli.py @@ -25,7 +25,7 @@ class Command(StrEnum): REMOVE_USER = os.path.join(SCRIPT_DIR,'hysteria2' ,'remove_user.sh') SHOW_USER_URI = os.path.join(SCRIPT_DIR,'hysteria2' ,'show_user_uri.sh') TRAFFIC_STATUS = 'traffic.py' # won't be call directly (it's a python module) - LIST_USERS = '' # unknown for now + LIST_USERS = os.path.join(SCRIPT_DIR,'hysteria2','list_users.sh') INSTALL_TCP_BRUTAL = os.path.join(SCRIPT_DIR,'tcp-brutal', 'install.sh') INSTALL_WARP = os.path.join(SCRIPT_DIR,'warp', 'install.sh') UNINSTALL_WARP = os.path.join(SCRIPT_DIR,'warp', 'uninstall.sh') @@ -122,7 +122,7 @@ def traffic_status(): @cli.command('list-users') def list_users(): - pass + run_cmd(['bash',Command.LIST_USERS]) # endregion diff --git a/core/scripts/hysteria2/list_users.sh b/core/scripts/hysteria2/list_users.sh new file mode 100644 index 0000000..e69de29 From f620980ed43cdb8a8b8a6e2ad8ab4c02928c2571 Mon Sep 17 00:00:00 2001 From: Sarina Date: Mon, 22 Jul 2024 13:30:45 +0330 Subject: [PATCH 35/91] Fix path in kick.sh --- core/scripts/hysteria2/kick.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/scripts/hysteria2/kick.sh b/core/scripts/hysteria2/kick.sh index da6c872..ea8a1f4 100644 --- a/core/scripts/hysteria2/kick.sh +++ b/core/scripts/hysteria2/kick.sh @@ -1,6 +1,6 @@ #!/bin/bash -USERS_FILE="/etc/hysteria/users/users.json" +USERS_FILE="/etc/hysteria/users.json" TRAFFIC_FILE="/etc/hysteria/traffic_data.json" CONFIG_FILE="/etc/hysteria/config.json" From 9c818db99cf283b0c3afbddab509aa29d141b941 Mon Sep 17 00:00:00 2001 From: Sarina Date: Mon, 22 Jul 2024 13:37:31 +0330 Subject: [PATCH 36/91] Add path.sh --- core/scripts/hysteria2/kick.sh | 4 +--- core/scripts/path.sh | 4 ++++ 2 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 core/scripts/path.sh diff --git a/core/scripts/hysteria2/kick.sh b/core/scripts/hysteria2/kick.sh index ea8a1f4..be6f3df 100644 --- a/core/scripts/hysteria2/kick.sh +++ b/core/scripts/hysteria2/kick.sh @@ -1,8 +1,6 @@ #!/bin/bash -USERS_FILE="/etc/hysteria/users.json" -TRAFFIC_FILE="/etc/hysteria/traffic_data.json" -CONFIG_FILE="/etc/hysteria/config.json" +source /etc/hysteria/core/scripts/path.sh kick_user() { local username=$1 diff --git a/core/scripts/path.sh b/core/scripts/path.sh new file mode 100644 index 0000000..d44a4b6 --- /dev/null +++ b/core/scripts/path.sh @@ -0,0 +1,4 @@ +CLI_PATH="/etc/hysteria/core/cli.py" +USERS_FILE="/etc/hysteria/users.json" +TRAFFIC_FILE="/etc/hysteria/traffic_data.json" +CONFIG_FILE="/etc/hysteria/config.json" \ No newline at end of file From 1985a171e9b8fe72c11473b9aa52967730280fa9 Mon Sep 17 00:00:00 2001 From: Sarina Date: Mon, 22 Jul 2024 13:43:41 +0330 Subject: [PATCH 37/91] Write menu.sh handlers --- menu.sh | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 65 insertions(+), 9 deletions(-) diff --git a/menu.sh b/menu.sh index 4aa8acd..0dcd2d6 100644 --- a/menu.sh +++ b/menu.sh @@ -1,26 +1,82 @@ #!/bin/bash source /etc/hysteria/core/scripts/utils.sh +source /etc/hysteria/core/scripts/path.sh # OPTION HANDLERS (ONLY NEEDED ONE) +hysteria2_install_handler() { + while true; do + read -p "Enter the new port number you want to use: " port + if ! [[ "$port" =~ ^[0-9]+$ ]] || [ "$port" -lt 1 ] || [ "$port" -gt 65535 ]; then + echo "Invalid port number. Please enter a number between 1 and 65535." + else + break + fi + done + python3 $CLI_PATH install-hysteria2 --port "$port" +} hysteria2_add_user_handler() { + while true; do + read -p "Enter the username: " username + if [[ "$username" =~ ^[a-z0-9]+$ ]]; then + break + else + echo -e "\033[0;31mError:\033[0m Username can only contain lowercase letters and numbers." + fi + done + + read -p "Enter the traffic limit (in GB): " traffic_gb + # Convert GB to bytes (1 GB = 1073741824 bytes) + traffic=$((traffic_gb * 1073741824)) + + read -p "Enter the expiration days: " expiration_days + password=$(pwgen -s 32 1) + creation_date=$(date +%Y-%m-%d) + + python3 $CLI_PATH add-user --username "$username" --traffic-limit "$traffic" --expiration-days "$expiration_days" --password "$password" --creation-date "$creation_date" } hysteria2_remove_user_handler() { + while true; do + read -p "Enter the username: " username + if [[ "$username" =~ ^[a-z0-9]+$ ]]; then + break + else + echo -e "\033[0;31mError:\033[0m Username can only contain lowercase letters and numbers." + fi + done + python3 $CLI_PATH remove-user --username "$username" } hysteria2_show_user_uri_hanndler() { + while true; do + read -p "Enter the username: " username + if [[ "$username" =~ ^[a-z0-9]+$ ]]; then + break + else + echo -e "\033[0;31mError:\033[0m Username can only contain lowercase letters and numbers." + fi + done + python3 $CLI_PATH show-user-uri --username "$username" } hysteria2_change_port_handler() { - + while true; do + read -p "Enter the new port number you want to use: " port + if ! [[ "$port" =~ ^[0-9]+$ ]] || [ "$port" -lt 1 ] || [ "$port" -gt 65535 ]; then + echo "Invalid port number. Please enter a number between 1 and 65535." + else + break + fi + done + python3 $CLI_PATH change-port --port "$port" } - +# TODO check it out # Function to modify users hysteria2_modify_users() { modify_script="/etc/hysteria/users/modify.py" @@ -109,11 +165,11 @@ hysteria2_menu() { display_hysteria2_menu read -r choice case $choice in - 1) python3 /etc/hysteria/core/cli.py install-hysteria2 ;; + 1) hysteria2_install_handler ;; 2) hysteria2_add_user_handler ;; 3) hysteria2_modify_users ;; 4) hysteria2_show_user_uri_hanndler ;; - 5) python3 /etc/hysteria2/core/cli.py traffic_status ;; + 5) python3 $CLI_PATH traffic_status ;; 6) hysteria2_remove_user_handler ;; 0) return ;; *) echo "Invalid option. Please try again." ;; @@ -149,13 +205,13 @@ advance_menu() { display_advance_menu read -r choice case $choice in - 1) python3 /etc/hysteria/core/cli.py install-tcp-brutal ;; - 2) python3 /etc/hysteria/core/cli.py install-warp ;; + 1) python3 $CLI_PATH install-tcp-brutal ;; + 2) python3 $CLI_PATH install-warp ;; 3) warp_configure_handler ;; - 4) python3 /etc/hysteria/core/cli.py uninstall-warp ;; + 4) python3 $CLI_PATH uninstall-warp ;; 5) hysteria2_change_port_handler ;; - 6) python3 /etc/hysteria/core/cli.py update-hysteria2 ;; - 7) python3 /etc/hysteria/core/cli.py uninstall-hysteria2 ;; + 6) python3 $CLI_PATH update-hysteria2 ;; + 7) python3 $CLI_PATH uninstall-hysteria2 ;; 0) return ;; *) echo "Invalid option. Please try again." ;; esac From ba9ff87b8c474aeceac8e6d2c0147babe589257d Mon Sep 17 00:00:00 2001 From: Sarina Date: Mon, 22 Jul 2024 15:46:16 +0330 Subject: [PATCH 38/91] Refactor paths --- core/scripts/hysteria2/add_user.sh | 26 ++++++++++++--------- core/scripts/hysteria2/change_port.sh | 15 ++++++++---- core/scripts/hysteria2/install.sh | 29 +++++++---------------- core/scripts/hysteria2/remove_user.sh | 21 ++++++++++------- core/scripts/hysteria2/show_user_uri.sh | 17 ++++++++------ core/scripts/hysteria2/update.sh | 31 ++++++++++++++----------- core/scripts/hysteria2/user.sh | 14 +++++++---- core/scripts/warp/configure.sh | 20 +++++++++------- core/scripts/warp/install.sh | 15 ++++++++---- core/scripts/warp/uninstall.sh | 20 +++++++++++----- core/traffic.py | 21 ++++++++++------- 11 files changed, 133 insertions(+), 96 deletions(-) diff --git a/core/scripts/hysteria2/add_user.sh b/core/scripts/hysteria2/add_user.sh index 17c7d59..d90ca10 100644 --- a/core/scripts/hysteria2/add_user.sh +++ b/core/scripts/hysteria2/add_user.sh @@ -1,9 +1,14 @@ #!/bin/bash +# Source the path.sh script to load the necessary variables +source /etc/hysteria/core/scripts/path.sh +source /etc/hysteria/core/scripts/utils.sh +define_colors + # Function to add a new user to the configuration add_user() { - if [ $# -ne 3 ]; then - echo "Usage: $0 " + if [ $# -ne 3 ] && [ $# -ne 5 ]; then + echo "Usage: $0 [password] [creation_date]" exit 1 fi @@ -11,11 +16,11 @@ add_user() { traffic_gb=$2 expiration_days=$3 password=$4 + creation_date=$5 + if [ -z "$password" ]; then password=$(pwgen -s 32 1) fi - creation_date=$5 - # Check if the creation_date is empty if [ -z "$creation_date" ]; then creation_date=$(date +%Y-%m-%d) else @@ -33,25 +38,24 @@ add_user() { # Validate the username if ! [[ "$username" =~ ^[a-z0-9]+$ ]]; then - echo -e "\033[0;31mError:\033[0m Username can only contain lowercase letters and numbers." + echo -e "${red}Error:${NC} Username can only contain lowercase letters and numbers." exit 1 fi # Convert GB to bytes (1 GB = 1073741824 bytes) traffic=$((traffic_gb * 1073741824)) - - if [ ! -f "/etc/hysteria/users.json" ]; then - echo "{}" > /etc/hysteria/users.json + if [ ! -f "$USERS_FILE" ]; then + echo "{}" > "$USERS_FILE" fi jq --arg username "$username" --arg password "$password" --argjson traffic "$traffic" --argjson expiration_days "$expiration_days" --arg creation_date "$creation_date" \ '.[$username] = {password: $password, max_download_bytes: $traffic, expiration_days: $expiration_days, account_creation_date: $creation_date, blocked: false}' \ - /etc/hysteria/users.json > /etc/hysteria/users_temp.json && mv /etc/hysteria/users_temp.json /etc/hysteria/users.json + "$USERS_FILE" > "${USERS_FILE}.temp" && mv "${USERS_FILE}.temp" "$USERS_FILE" - python3 /etc/hysteria/core/cli.py restart-hysteria2 > /dev/null 2>&1 + python3 "$CLI_PATH" restart-hysteria2 > /dev/null 2>&1 - echo -e "\033[0;32mUser $username added successfully.\033[0m" + echo -e "${green}User $username added successfully.${NC}" } # Call the function with the provided arguments diff --git a/core/scripts/hysteria2/change_port.sh b/core/scripts/hysteria2/change_port.sh index be7bd31..c5a8d30 100644 --- a/core/scripts/hysteria2/change_port.sh +++ b/core/scripts/hysteria2/change_port.sh @@ -1,3 +1,8 @@ +#!/bin/bash + +# Source the path.sh script to load the CONFIG_FILE variable +source /etc/hysteria/core/scripts/path.sh + # Function to update port number in configuration update_port() { local port=$1 @@ -9,14 +14,14 @@ update_port() { fi # Check if the config file exists and update the port number - if [ -f "/etc/hysteria/config.json" ]; then - jq --arg port "$port" '.listen = ":" + $port' /etc/hysteria/config.json > /etc/hysteria/config_temp.json && mv /etc/hysteria/config_temp.json /etc/hysteria/config.json - python3 /etc/hysteria/core/cli.py restart-hysteria2 > /dev/null 2>&1 + if [ -f "$CONFIG_FILE" ]; then + jq --arg port "$port" '.listen = ":" + $port' "$CONFIG_FILE" > "${CONFIG_FILE}.temp" && mv "${CONFIG_FILE}.temp" "$CONFIG_FILE" + python3 "$CLI_PATH" restart-hysteria2 > /dev/null 2>&1 echo "Port changed successfully to $port." else - echo "Error: Config file /etc/hysteria/config.json not found." + echo "Error: Config file $CONFIG_FILE not found." return 1 fi } -update_port "$1" \ No newline at end of file +update_port "$1" diff --git a/core/scripts/hysteria2/install.sh b/core/scripts/hysteria2/install.sh index 34cae15..c278bc6 100644 --- a/core/scripts/hysteria2/install.sh +++ b/core/scripts/hysteria2/install.sh @@ -1,9 +1,13 @@ #!/bin/bash +# Source the path.sh script to load the necessary variables +source /etc/hysteria/core/scripts/path.sh source /etc/hysteria/core/scripts/utils.sh define_colors install_hysteria() { + local port=$1 + # Step 1: Install Hysteria2 echo "Installing Hysteria2..." bash <(curl -fsSL https://get.hy2.sh/) >/dev/null 2>&1 @@ -34,21 +38,12 @@ install_hysteria() { sha256=$(python3 generate.py) - # WE CLONED THE REPO, SO WE HAVE THE config.json ALREADY - # Step 6: Download the config.json file - # echo "Downloading config.json..." - # wget https://raw.githubusercontent.com/ReturnFI/Hysteria2/main/config.json -O /etc/hysteria/config.json >/dev/null 2>&1 - # echo - # Step 7: Ask for the port number and validate input - port=$1 if [[ $port =~ ^[0-9]+$ ]] && (( port >= 1 && port <= 65535 )); then # Check if the port is in use if ss -tuln | grep -q ":$port\b"; then - echo -e "\e[91mPort $port is already in use. Please choose another port.\e[0m" + echo -e "${red}Port $port is already in use. Please choose another port.${NC}" exit 1 - else - break fi else echo "Invalid port number. Please enter a number between 1 and 65535." @@ -85,12 +80,12 @@ install_hysteria() { .tls.pinSHA256 = $sha256 | .obfs.salamander.password = $obfspassword | .trafficStats.secret = $UUID | - .outbounds[0].direct.bindDevice = $networkdef' /etc/hysteria/config.json > /etc/hysteria/config_temp.json && mv /etc/hysteria/config_temp.json /etc/hysteria/config.json + .outbounds[0].direct.bindDevice = $networkdef' "$CONFIG_FILE" > "${CONFIG_FILE}.temp" && mv "${CONFIG_FILE}.temp" "$CONFIG_FILE" # Step 11: Modify the systemd service file to use config.json echo "Updating hysteria-server.service to use config.json..." sed -i 's|(config.yaml)||' /etc/systemd/system/hysteria-server.service - sed -i 's|/etc/hysteria/config.yaml|/etc/hysteria/config.json|' /etc/systemd/system/hysteria-server.service + sed -i "s|/etc/hysteria/config.yaml|$CONFIG_FILE|" /etc/systemd/system/hysteria-server.service rm /etc/hysteria/config.yaml sleep 1 @@ -103,7 +98,7 @@ install_hysteria() { # Step 13: Check if the hysteria-server.service is active if systemctl is-active --quiet hysteria-server.service; then - echo "${cyan}Hysteria2${green} has been successfully install." + echo "${cyan}Hysteria2${green} has been successfully installed." else echo "${red}Error:${NC} hysteria-server.service is not active." exit 1 @@ -118,13 +113,6 @@ install_hysteria() { (crontab -l ; echo "*/1 * * * * /etc/hysteria/core/scripts/hysteria2/kick.sh >/dev/null 2>&1") | crontab - } - - - - - - - if systemctl is-active --quiet hysteria-server.service; then echo -e "${red}Error:${NC} Hysteria2 is already installed and running." echo @@ -140,4 +128,3 @@ else echo -e "${red}Error:${NC} Hysteria2 service is not active. Please check the logs for more details." fi fi - diff --git a/core/scripts/hysteria2/remove_user.sh b/core/scripts/hysteria2/remove_user.sh index 619617b..1759032 100644 --- a/core/scripts/hysteria2/remove_user.sh +++ b/core/scripts/hysteria2/remove_user.sh @@ -1,5 +1,10 @@ #!/bin/bash +# Source the path.sh script to load the necessary variables +source /etc/hysteria/core/scripts/path.sh +source /etc/hysteria/core/scripts/utils.sh +define_colors + # Function to remove a user from the configuration remove_user() { if [ $# -ne 1 ]; then @@ -9,22 +14,22 @@ remove_user() { username=$1 - if [ -f "/etc/hysteria/users.json" ]; then + if [ -f "$USERS_FILE" ]; then # Check if the username exists in the users.json file - if jq -e "has(\"$username\")" /etc/hysteria/users.json > /dev/null; then - jq --arg username "$username" 'del(.[$username])' /etc/hysteria/users.json > /etc/hysteria/users_temp.json && mv /etc/hysteria/users_temp.json /etc/hysteria/users.json + if jq -e "has(\"$username\")" "$USERS_FILE" > /dev/null; then + jq --arg username "$username" 'del(.[$username])' "$USERS_FILE" > "${USERS_FILE}.temp" && mv "${USERS_FILE}.temp" "$USERS_FILE" - if [ -f "/etc/hysteria/traffic_data.json" ]; then - jq --arg username "$username" 'del(.[$username])' /etc/hysteria/traffic_data.json > /etc/hysteria/traffic_data_temp.json && mv /etc/hysteria/traffic_data_temp.json /etc/hysteria/traffic_data.json + if [ -f "$TRAFFIC_FILE" ]; then + jq --arg username "$username" 'del(.[$username])' "$TRAFFIC_FILE" > "${TRAFFIC_FILE}.temp" && mv "${TRAFFIC_FILE}.temp" "$TRAFFIC_FILE" fi - python3 /etc/hysteria/core/cli.py restart-hysteria2 > /dev/null 2>&1 + python3 "$CLI_PATH" restart-hysteria2 > /dev/null 2>&1 echo "User $username removed successfully." else - echo -e "\033[0;31mError:\033[0m User $username not found." + echo -e "${red}Error:${NC} User $username not found." fi else - echo -e "\033[0;31mError:\033[0m Config file /etc/hysteria/users.json not found." + echo -e "${red}Error:${NC} Config file $USERS_FILE not found." fi } diff --git a/core/scripts/hysteria2/show_user_uri.sh b/core/scripts/hysteria2/show_user_uri.sh index 0009c2a..e6b4e0c 100644 --- a/core/scripts/hysteria2/show_user_uri.sh +++ b/core/scripts/hysteria2/show_user_uri.sh @@ -1,8 +1,11 @@ #!/bin/bash +# Source the path.sh script to load the configuration variables +source /etc/hysteria/core/scripts/path.sh + # Function to show URI if Hysteria2 is installed and active show_uri() { - if [ -f "/etc/hysteria/users.json" ]; then + if [ -f "$USERS_FILE" ]; then if systemctl is-active --quiet hysteria-server.service; then # Check if the username is provided as an argument if [ -z "$1" ]; then @@ -13,12 +16,12 @@ show_uri() { username=$1 # Validate the username - if jq -e "has(\"$username\")" /etc/hysteria/users.json > /dev/null; then + if jq -e "has(\"$username\")" "$USERS_FILE" > /dev/null; then # Get the selected user's details - authpassword=$(jq -r ".\"$username\".password" /etc/hysteria/users.json) - port=$(jq -r '.listen' /etc/hysteria/config.json | cut -d':' -f2) - sha256=$(jq -r '.tls.pinSHA256' /etc/hysteria/config.json) - obfspassword=$(jq -r '.obfs.salamander.password' /etc/hysteria/config.json) + authpassword=$(jq -r ".\"$username\".password" "$USERS_FILE") + port=$(jq -r '.listen' "$CONFIG_FILE" | cut -d':' -f2) + sha256=$(jq -r '.tls.pinSHA256' "$CONFIG_FILE") + obfspassword=$(jq -r '.obfs.salamander.password' "$CONFIG_FILE") # Get IP addresses IP=$(curl -s -4 ip.gs) @@ -56,7 +59,7 @@ show_uri() { echo -e "\033[0;31mError:\033[0m Hysteria2 is not active." fi else - echo -e "\033[0;31mError:\033[0m Config file /etc/hysteria/users.json not found." + echo -e "\033[0;31mError:\033[0m Config file $USERS_FILE not found." fi } diff --git a/core/scripts/hysteria2/update.sh b/core/scripts/hysteria2/update.sh index 0c0a4e2..2b4e40b 100644 --- a/core/scripts/hysteria2/update.sh +++ b/core/scripts/hysteria2/update.sh @@ -1,42 +1,47 @@ -echo "Starting the update process for Hysteria2..." +#!/bin/bash + +# Source the path.sh script to load the CONFIG_FILE variable +source /etc/hysteria/core/scripts/path.sh + +echo "Starting the update process for Hysteria2..." echo "Backing up the current configuration..." -cp /etc/hysteria/config.json /etc/hysteria/config_backup.json +cp "$CONFIG_FILE" /etc/hysteria/config_backup.json if [ $? -ne 0 ]; then - echo "${red}Error:${NC} Failed to back up configuration. Aborting update." + echo "Error: Failed to back up configuration. Aborting update." return 1 fi echo "Downloading and installing the latest version of Hysteria2..." bash <(curl -fsSL https://get.hy2.sh/) >/dev/null 2>&1 if [ $? -ne 0 ]; then - echo "${red}Error:${NC} Failed to download or install the latest version. Restoring backup configuration." - mv /etc/hysteria/config_backup.json /etc/hysteria/config.json - python3 /etc/hysteria/core/cli.py restart-hysteria2 > /dev/null 2>&1 + echo "Error: Failed to download or install the latest version. Restoring backup configuration." + mv /etc/hysteria/config_backup.json "$CONFIG_FILE" + python3 "$CLI_PATH" restart-hysteria2 > /dev/null 2>&1 return 1 fi echo "Restoring configuration from backup..." -mv /etc/hysteria/config_backup.json /etc/hysteria/config.json +mv /etc/hysteria/config_backup.json "$CONFIG_FILE" if [ $? -ne 0 ]; then - echo "${red}Error:${NC} Failed to restore configuration from backup." + echo "Error: Failed to restore configuration from backup." return 1 fi echo "Modifying systemd service to use config.json..." -sed -i 's|/etc/hysteria/config.yaml|/etc/hysteria/config.json|' /etc/systemd/system/hysteria-server.service +sed -i "s|/etc/hysteria/config.yaml|$CONFIG_FILE|" /etc/systemd/system/hysteria-server.service if [ $? -ne 0 ]; then - echo "${red}Error:${NC} Failed to modify systemd service." + echo "Error: Failed to modify systemd service." return 1 fi rm /etc/hysteria/config.yaml systemctl daemon-reload >/dev/null 2>&1 -python3 /etc/hysteria/core/cli.py restart-hysteria2 > /dev/null 2>&1 +python3 "$CLI_PATH" restart-hysteria2 > /dev/null 2>&1 if [ $? -ne 0 ]; then - echo "${red}Error:${NC} Failed to restart Hysteria2 service." + echo "Error: Failed to restart Hysteria2 service." return 1 fi echo "Hysteria2 has been successfully updated." echo "" -return 0 \ No newline at end of file +return 0 diff --git a/core/scripts/hysteria2/user.sh b/core/scripts/hysteria2/user.sh index f20f17c..f5e5ad0 100644 --- a/core/scripts/hysteria2/user.sh +++ b/core/scripts/hysteria2/user.sh @@ -4,26 +4,30 @@ ADDR="$1" AUTH="$2" TX="$3" -USERS_FILE="/etc/hysteria/users.json" -TRAFFIC_FILE="/etc/hysteria/traffic_data.json" -CONFIG_FILE="/etc/hysteria/config.json" +# Source the path.sh script to load variables +source /etc/hysteria/core/scripts/path.sh +# Extract username and password from AUTH IFS=':' read -r USERNAME PASSWORD <<< "$AUTH" +# Retrieve stored user data STORED_PASSWORD=$(jq -r --arg user "$USERNAME" '.[$user].password' "$USERS_FILE") MAX_DOWNLOAD_BYTES=$(jq -r --arg user "$USERNAME" '.[$user].max_download_bytes' "$USERS_FILE") EXPIRATION_DAYS=$(jq -r --arg user "$USERNAME" '.[$user].expiration_days' "$USERS_FILE") ACCOUNT_CREATION_DATE=$(jq -r --arg user "$USERNAME" '.[$user].account_creation_date' "$USERS_FILE") BLOCKED=$(jq -r --arg user "$USERNAME" '.[$user].blocked' "$USERS_FILE") +# Check if the user is blocked if [ "$BLOCKED" == "true" ]; then exit 1 fi +# Check if the provided password matches the stored password if [ "$STORED_PASSWORD" != "$PASSWORD" ]; then exit 1 fi +# Check if the user's account has expired CURRENT_DATE=$(date +%s) EXPIRATION_DATE=$(date -d "$ACCOUNT_CREATION_DATE + $EXPIRATION_DAYS days" +%s) @@ -32,6 +36,7 @@ if [ "$CURRENT_DATE" -ge "$EXPIRATION_DATE" ]; then exit 1 fi +# Check if the user's download limit has been exceeded CURRENT_DOWNLOAD_BYTES=$(jq -r --arg user "$USERNAME" '.[$user].download_bytes' "$TRAFFIC_FILE") if [ "$CURRENT_DOWNLOAD_BYTES" -ge "$MAX_DOWNLOAD_BYTES" ]; then @@ -43,5 +48,6 @@ if [ "$CURRENT_DOWNLOAD_BYTES" -ge "$MAX_DOWNLOAD_BYTES" ]; then exit 1 fi +# If all checks pass, print the username and exit successfully echo "$USERNAME" -exit 0 \ No newline at end of file +exit 0 diff --git a/core/scripts/warp/configure.sh b/core/scripts/warp/configure.sh index a827275..249748c 100644 --- a/core/scripts/warp/configure.sh +++ b/core/scripts/warp/configure.sh @@ -1,11 +1,15 @@ - # Check if wg-quick@wgcf.service is active +#!/bin/bash + +# Source the path.sh script to load the CONFIG_FILE and CLI_PATH variables +source /etc/hysteria/core/scripts/path.sh + +# Check if wg-quick@wgcf.service is active if ! systemctl is-active --quiet wg-quick@wgcf.service; then echo "WARP is not active. Please install WARP before configuring." - return + exit 1 fi -CONFIG_FILE="/etc/hysteria/config.json" - +# Check if the config file exists if [ -f "$CONFIG_FILE" ]; then # Check the current status of WARP configurations warp_all_status=$(jq -r 'if .acl.inline | index("warps(all)") then "WARP active" else "Direct" end' "$CONFIG_FILE") @@ -62,13 +66,13 @@ if [ -f "$CONFIG_FILE" ]; then fi ;; 5) - return + exit 0 ;; *) echo "Invalid option. Please try again." ;; esac - python3 /etc/hysteria/core/cli.py restart-hysteria2 > /dev/null 2>&1 + python3 "$CLI_PATH" restart-hysteria2 > /dev/null 2>&1 else - echo "${red}Error:${NC} Config file $CONFIG_FILE not found." -fi \ No newline at end of file + echo "Error: Config file $CONFIG_FILE not found." +fi diff --git a/core/scripts/warp/install.sh b/core/scripts/warp/install.sh index 0cb0327..1e66ad3 100644 --- a/core/scripts/warp/install.sh +++ b/core/scripts/warp/install.sh @@ -1,3 +1,8 @@ +#!/bin/bash + +# Source the path.sh script to load the CONFIG_FILE variable +source /etc/hysteria/core/scripts/path.sh + # Check if wg-quick@wgcf.service is active if systemctl is-active --quiet wg-quick@wgcf.service; then echo "WARP is already active. Skipping installation and configuration update." @@ -6,13 +11,13 @@ else bash <(curl -fsSL git.io/warp.sh) wgx # Check if the config file exists - if [ -f "/etc/hysteria/config.json" ]; then + if [ -f "$CONFIG_FILE" ]; then # Add the outbound configuration to the config.json file - jq '.outbounds += [{"name": "warps", "type": "direct", "direct": {"mode": 4, "bindDevice": "wgcf"}}]' /etc/hysteria/config.json > /etc/hysteria/config_temp.json && mv /etc/hysteria/config_temp.json /etc/hysteria/config.json + jq '.outbounds += [{"name": "warps", "type": "direct", "direct": {"mode": 4, "bindDevice": "wgcf"}}]' "$CONFIG_FILE" > /etc/hysteria/config_temp.json && mv /etc/hysteria/config_temp.json "$CONFIG_FILE" # Restart the hysteria-server service - python3 /etc/hysteria/core/cli.py restart-hysteria2 > /dev/null 2>&1 + python3 "$CLI_PATH" restart-hysteria2 > /dev/null 2>&1 echo "WARP installed and outbound added to config.json." else - echo "${red}Error:${NC} Config file /etc/hysteria/config.json not found." + echo "Error: Config file $CONFIG_FILE not found." fi -fi \ No newline at end of file +fi diff --git a/core/scripts/warp/uninstall.sh b/core/scripts/warp/uninstall.sh index ae87a35..c51aedf 100644 --- a/core/scripts/warp/uninstall.sh +++ b/core/scripts/warp/uninstall.sh @@ -1,8 +1,15 @@ +#!/bin/bash + +# Source the path.sh script to load the CONFIG_FILE and CLI_PATH variables +source /etc/hysteria/core/scripts/path.sh + +# Check if WARP is active if systemctl is-active --quiet wg-quick@wgcf.service; then echo "Uninstalling WARP..." bash <(curl -fsSL git.io/warp.sh) dwg - if [ -f "/etc/hysteria/config.json" ]; then + # Check if the config file exists + if [ -f "$CONFIG_FILE" ]; then default_config='["reject(geosite:ir)", "reject(geoip:ir)", "reject(geosite:category-ads-all)", "reject(geoip:private)", "reject(geosite:google@ads)"]' jq --argjson default_config "$default_config" ' @@ -17,14 +24,15 @@ if systemctl is-active --quiet wg-quick@wgcf.service; then . end ) | .acl.inline |= ($default_config + (. - $default_config | map(select(. != "direct")))) - ' /etc/hysteria/config.json > /etc/hysteria/config_temp.json && mv /etc/hysteria/config_temp.json /etc/hysteria/config.json - jq 'del(.outbounds[] | select(.name == "warps" and .type == "direct" and .direct.mode == 4 and .direct.bindDevice == "wgcf"))' /etc/hysteria/config.json > /etc/hysteria/config_temp.json && mv /etc/hysteria/config_temp.json /etc/hysteria/config.json + ' "$CONFIG_FILE" > /etc/hysteria/config_temp.json && mv /etc/hysteria/config_temp.json "$CONFIG_FILE" - python3 /etc/hysteria/core/cli.py restart-hysteria2 > /dev/null 2>&1 + jq 'del(.outbounds[] | select(.name == "warps" and .type == "direct" and .direct.mode == 4 and .direct.bindDevice == "wgcf"))' "$CONFIG_FILE" > /etc/hysteria/config_temp.json && mv /etc/hysteria/config_temp.json "$CONFIG_FILE" + + python3 "$CLI_PATH" restart-hysteria2 > /dev/null 2>&1 echo "WARP uninstalled and configurations reset to default." else - echo "${red}Error:${NC} Config file /etc/hysteria/config.json not found." + echo "Error: Config file $CONFIG_FILE not found." fi else echo "WARP is not active. Skipping uninstallation." -fi \ No newline at end of file +fi diff --git a/core/traffic.py b/core/traffic.py index b430d4c..a623ba5 100644 --- a/core/traffic.py +++ b/core/traffic.py @@ -3,15 +3,21 @@ import subprocess import json import os +# Define static variables for paths and URLs +CONFIG_FILE = '/etc/hysteria/config.json' +TRAFFIC_FILE = '/etc/hysteria/traffic_data.json' +TRAFFIC_API_URL = 'http://127.0.0.1:25413/traffic?clear=1' +ONLINE_API_URL = 'http://127.0.0.1:25413/online' + def traffic_status(): green = '\033[0;32m' cyan = '\033[0;36m' NC = '\033[0m' try: - secret = subprocess.check_output(['jq', '-r', '.trafficStats.secret', '/etc/hysteria/config.json']).decode().strip() + secret = subprocess.check_output(['jq', '-r', '.trafficStats.secret', CONFIG_FILE]).decode().strip() except subprocess.CalledProcessError as e: - print(f"Error: Failed to read secret from config.json. Details: {e}") + print(f"Error: Failed to read secret from {CONFIG_FILE}. Details: {e}") return if not secret: @@ -19,7 +25,7 @@ def traffic_status(): return try: - response = subprocess.check_output(['curl', '-s', '-H', f'Authorization: {secret}', 'http://127.0.0.1:25413/traffic?clear=1']).decode().strip() + response = subprocess.check_output(['curl', '-s', '-H', f'Authorization: {secret}', TRAFFIC_API_URL]).decode().strip() except subprocess.CalledProcessError as e: print(f"Error: Failed to fetch traffic data. Details: {e}") return @@ -29,7 +35,7 @@ def traffic_status(): return try: - online_response = subprocess.check_output(['curl', '-s', '-H', f'Authorization: {secret}', 'http://127.0.0.1:25413/online']).decode().strip() + online_response = subprocess.check_output(['curl', '-s', '-H', f'Authorization: {secret}', ONLINE_API_URL]).decode().strip() except subprocess.CalledProcessError as e: print(f"Error: Failed to fetch online status data. Details: {e}") return @@ -55,9 +61,9 @@ def traffic_status(): } existing_data = {} - if os.path.exists('/etc/hysteria/traffic_data.json'): + if os.path.exists(TRAFFIC_FILE): try: - with open('/etc/hysteria/traffic_data.json', 'r') as json_file: + with open(TRAFFIC_FILE, 'r') as json_file: existing_data = json.load(json_file) except json.JSONDecodeError: print("Error: Failed to parse existing traffic data JSON file.") @@ -71,7 +77,7 @@ def traffic_status(): else: existing_data[user] = data - with open('/etc/hysteria/traffic_data.json', 'w') as json_file: + with open(TRAFFIC_FILE, 'w') as json_file: json.dump(existing_data, json_file, indent=4) display_traffic_data(existing_data, green, cyan, NC) @@ -108,4 +114,3 @@ def format_bytes(bytes): return f"{bytes / 1073741824:.2f}GB" else: return f"{bytes / 1099511627776:.2f}TB" - From 874d9b865267e00fa441880fc85589e423020a96 Mon Sep 17 00:00:00 2001 From: Sarina Date: Mon, 22 Jul 2024 15:47:30 +0330 Subject: [PATCH 39/91] Change repo url --- install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install.sh b/install.sh index 463775a..b69eb92 100644 --- a/install.sh +++ b/install.sh @@ -19,7 +19,8 @@ if ! grep -q "alias hys2='/etc/hysteria/menu.sh'" ~/.bashrc; then source ~/.bashrc fi -git clone https://github.com/ReturnFI/Hysteria2 /etc/hysteria +# TODO: change the url later +git clone https://github.com/Iam54r1n4/Hysteria2 /etc/hysteria cd /etc/hysteria chmod +x menu.sh From dc026ba6a69e59f15a693d9f4ef758d6346022e4 Mon Sep 17 00:00:00 2001 From: Sarina Date: Mon, 22 Jul 2024 15:59:02 +0330 Subject: [PATCH 40/91] Fix syntax error in menu.sh --- menu.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/menu.sh b/menu.sh index 0dcd2d6..d734f43 100644 --- a/menu.sh +++ b/menu.sh @@ -51,7 +51,7 @@ hysteria2_remove_user_handler() { python3 $CLI_PATH remove-user --username "$username" } -hysteria2_show_user_uri_hanndler() { +hysteria2_show_user_uri_handler() { while true; do read -p "Enter the username: " username @@ -88,10 +88,10 @@ hysteria2_modify_users() { } warp_configure_handler() { - + # Placeholder function, add implementation here if needed + echo "empty" } - # Function to display the main menu display_main_menu() { clear @@ -168,7 +168,7 @@ hysteria2_menu() { 1) hysteria2_install_handler ;; 2) hysteria2_add_user_handler ;; 3) hysteria2_modify_users ;; - 4) hysteria2_show_user_uri_hanndler ;; + 4) hysteria2_show_user_uri_handler ;; 5) python3 $CLI_PATH traffic_status ;; 6) hysteria2_remove_user_handler ;; 0) return ;; From a9fe44c7716e6309d0b975d3888716228c42991b Mon Sep 17 00:00:00 2001 From: Sarina Date: Mon, 22 Jul 2024 16:08:04 +0330 Subject: [PATCH 41/91] Fix bug python 3.10 doesn't supprot StrEnum --- core/cli.py | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/core/cli.py b/core/cli.py index 9823c6d..5573e9c 100644 --- a/core/cli.py +++ b/core/cli.py @@ -5,15 +5,16 @@ import os import io import click import subprocess -from enum import StrEnum +from enum import Enum import traffic import validator + SCRIPT_DIR = 'scripts' DEBUG = True -class Command(StrEnum): +class Command(Enum): '''Constais path to command's script''' INSTALL_HYSTERIA2 = os.path.join(SCRIPT_DIR,'hysteria2' ,'install.sh') UNINSTALL_HYSTERIA2 = os.path.join(SCRIPT_DIR,'hysteria2', 'uninstall.sh') @@ -60,26 +61,26 @@ def cli(): @cli.command('install-hysteria2') @click.option('--port','-p', required=True, help='New port for Hysteria2',type=int,validate=validator.validate_port) def install_hysteria2(port:int): - run_cmd(['bash', Command.INSTALL_HYSTERIA2, str(port)]) + run_cmd(['bash', Command.INSTALL_HYSTERIA2.value, str(port)]) @cli.command('uninstall-hysteria2') def uninstall_hysteria2(): - run_cmd(['bash', Command.UNINSTALL_HYSTERIA2]) + run_cmd(['bash', Command.UNINSTALL_HYSTERIA2.value]) @cli.command('update-hysteria2') def update_hysteria2(): - run_cmd(['bash', Command.UPDATE_HYSTERIA2]) + run_cmd(['bash', Command.UPDATE_HYSTERIA2.value]) @cli.command('restart-hysteria2') def restart_hysteria2(): - run_cmd(['bash', Command.RESTART_HYSTERIA2]) + run_cmd(['bash', Command.RESTART_HYSTERIA2.value]) @cli.command('change-hysteria2-port') @click.option('--port','-p', required=True, help='New port for Hysteria2',type=int,validate=validator.validate_port) def change_hysteria2_port(port:int): - run_cmd(['bash', Command.CHANGE_PORT_HYSTERIA2, str(port)]) + run_cmd(['bash', Command.CHANGE_PORT_HYSTERIA2.value, str(port)]) @cli.command('add-user') @click.option('--username','-u', required=True, help='Username for the new user',type=str) @@ -97,24 +98,24 @@ def add_user(username:str, traffic_limit:float, expiration_days:int,password:str if not creation_date: creation_date = datetime.now().strftime('%Y-%m-%d') - run_cmd(['bash', Command.ADD_USER, username, str(traffic_limit), str(expiration_days), password, creation_date]) + run_cmd(['bash', Command.ADD_USER.value, username, str(traffic_limit), str(expiration_days), password, creation_date]) @cli.command('edit-user') @click.option('--username','-u', required=True, help='Username for the user to edit',type=str) @click.option('--traffic-limit','-t', required=True, help='Traffic limit for the new user in GB',type=float) @click.option('--expiration-days','-e', required=True, help='Expiration days for the new user',type=int) def edit_user(username:str, traffic_limit:float, expiration_days:int): - run_cmd(['bash', Command.EDIT_USER, username, str(traffic_limit), str(expiration_days)]) + run_cmd(['bash', Command.EDIT_USER.value, username, str(traffic_limit), str(expiration_days)]) @cli.command('remove-user') @click.option('--username','-u', required=True, help='Username for the user to remove',type=str) def remove_user(username:str): - run_cmd(['bash', Command.REMOVE_USER, username]) + run_cmd(['bash', Command.REMOVE_USER.value, username]) @cli.command('show-user-uri') @click.option('--username','-u', required=True, help='Username for the user to show the URI',type=str) def show_user_uri(username:str): - run_cmd(['bash', Command.SHOW_USER_URI, username]) + run_cmd(['bash', Command.SHOW_USER_URI.value, username]) @cli.command('traffic-status') def traffic_status(): @@ -122,7 +123,7 @@ def traffic_status(): @cli.command('list-users') def list_users(): - run_cmd(['bash',Command.LIST_USERS]) + run_cmd(['bash',Command.LIST_USERS.value]) # endregion @@ -130,21 +131,21 @@ def list_users(): @cli.command('install-tcp-brutal') def install_tcp_brutal(): - run_cmd(['bash', Command.INSTALL_TCP_BRUTAL]) + run_cmd(['bash', Command.INSTALL_TCP_BRUTAL.value]) @cli.command('install-warp') def install_warp(): - run_cmd(['bash', Command.INSTALL_WARP]) + run_cmd(['bash', Command.INSTALL_WARP.value]) @cli.command('uninstall-warp') def uninstall_warp(): - run_cmd(['bash', Command.UNINSTALL_WARP]) + run_cmd(['bash', Command.UNINSTALL_WARP.value]) @cli.command('configure-warp') @click.option('--warp-mode','-m', required=True, help='Warp mode',type=click.Choice(['proxy','direct','reject'])) @click.option('--block-porn','-p', required=False, help='Block porn',type=bool) def configure_warp(warp_mode:str, block_porn:bool): - run_cmd(['bash', Command.CONFIGURE_WARP, warp_mode, str(block_porn)]) + run_cmd(['bash', Command.CONFIGURE_WARP.value, warp_mode, str(block_porn)]) # endregion From 62ec44ee23513a0cdaf968edd28a79f05bc85f04 Mon Sep 17 00:00:00 2001 From: Sarina Date: Mon, 22 Jul 2024 16:13:17 +0330 Subject: [PATCH 42/91] Fix bug --- core/cli.py | 4 ++-- core/validator.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core/cli.py b/core/cli.py index 5573e9c..3ba5e4a 100644 --- a/core/cli.py +++ b/core/cli.py @@ -59,7 +59,7 @@ def cli(): # region hysteria2 menu options @cli.command('install-hysteria2') -@click.option('--port','-p', required=True, help='New port for Hysteria2',type=int,validate=validator.validate_port) +@click.option('--port','-p', required=True, help='New port for Hysteria2',type=int,callback=validator.validate_port) def install_hysteria2(port:int): run_cmd(['bash', Command.INSTALL_HYSTERIA2.value, str(port)]) @@ -78,7 +78,7 @@ def restart_hysteria2(): @cli.command('change-hysteria2-port') -@click.option('--port','-p', required=True, help='New port for Hysteria2',type=int,validate=validator.validate_port) +@click.option('--port','-p', required=True, help='New port for Hysteria2',type=int,callback=validator.validate_port) def change_hysteria2_port(port:int): run_cmd(['bash', Command.CHANGE_PORT_HYSTERIA2.value, str(port)]) diff --git a/core/validator.py b/core/validator.py index 1ede3d4..bd4f8b0 100644 --- a/core/validator.py +++ b/core/validator.py @@ -1,10 +1,10 @@ import os -def validate_port(p:int)-> bool: - if p < 1 or p > 65535: +def validate_port(ctx,param,value)-> bool: + if value < 1 or value > 65535: return False # check if port is in use - if os.system(f'lsof -i:{p}') == 0: + if os.system(f'lsof -i:{value}') == 0: return False return True \ No newline at end of file From 65817ade14e6b7b54d658e121dfd85c45ef4456c Mon Sep 17 00:00:00 2001 From: Sarina Date: Mon, 22 Jul 2024 16:28:19 +0330 Subject: [PATCH 43/91] Fix cli validator and scripts path --- core/cli.py | 7 ++++--- core/validator.py | 10 +++++----- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/core/cli.py b/core/cli.py index 3ba5e4a..f8fce50 100644 --- a/core/cli.py +++ b/core/cli.py @@ -11,7 +11,7 @@ import traffic import validator -SCRIPT_DIR = 'scripts' +SCRIPT_DIR = '/etc/hysteria/core/scripts' DEBUG = True class Command(Enum): @@ -39,7 +39,7 @@ def run_cmd(command:list[str]): Runs a command and returns the output. Could raise subprocess.CalledProcessError ''' - result = subprocess.check_output(command, shell=True) + result = subprocess.check_output(command, shell=False) if DEBUG: print(result.decode().strip()) @@ -48,7 +48,7 @@ def generate_password() -> str: Generates a random password using pwgen for user. Could raise subprocess.CalledProcessError ''' - return subprocess.check_output(['pwgen', '-s', '32', '1'], shell=True).decode().strip() + return subprocess.check_output(['pwgen', '-s', '32', '1'], shell=False).decode().strip() # endregion @@ -61,6 +61,7 @@ def cli(): @cli.command('install-hysteria2') @click.option('--port','-p', required=True, help='New port for Hysteria2',type=int,callback=validator.validate_port) def install_hysteria2(port:int): + print(f"bash {Command.INSTALL_HYSTERIA2.value} {str(port)}") run_cmd(['bash', Command.INSTALL_HYSTERIA2.value, str(port)]) diff --git a/core/validator.py b/core/validator.py index bd4f8b0..04c09a2 100644 --- a/core/validator.py +++ b/core/validator.py @@ -1,10 +1,10 @@ import os +import click - -def validate_port(ctx,param,value)-> bool: +def validate_port(ctx,param,value:int) -> int: if value < 1 or value > 65535: - return False + raise click.BadParameter('Port must be between 1 and 65535') # check if port is in use if os.system(f'lsof -i:{value}') == 0: - return False - return True \ No newline at end of file + raise click.BadParameter(f'Port {value} is in use') + return value \ No newline at end of file From a6374258040decd330080e78cccc985f6e4cef3b Mon Sep 17 00:00:00 2001 From: Sarina Date: Mon, 22 Jul 2024 16:48:22 +0330 Subject: [PATCH 44/91] Fix indentation error --- core/scripts/hysteria2/install.sh | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/core/scripts/hysteria2/install.sh b/core/scripts/hysteria2/install.sh index c278bc6..df8ee60 100644 --- a/core/scripts/hysteria2/install.sh +++ b/core/scripts/hysteria2/install.sh @@ -28,14 +28,24 @@ install_hysteria() { # Step 5: Generate the base64 encoded SHA-256 fingerprint echo "Generating base64 encoded SHA-256 fingerprint..." - echo "import re, base64, binascii - - hex_string = \"$fingerprint\" - binary_data = binascii.unhexlify(hex_string) - base64_encoded = base64.b64encode(binary_data).decode('utf-8') - - print(\"sha256/\" + base64_encoded)" > generate.py - + cat < generate.py +import base64 +import binascii + +# Hexadecimal string +hex_string = "$fingerprint" + +# Convert hex to binary +binary_data = binascii.unhexlify(hex_string) + +# Encode binary data to base64 +base64_encoded = base64.b64encode(binary_data).decode('utf-8') + +# Print the result prefixed with 'sha256/' +print('sha256/' + base64_encoded) +EOF + + # Execute the Python script and capture the output sha256=$(python3 generate.py) # Step 7: Ask for the port number and validate input From 061a85a167fedebb7710429d9cc737fc31e69a9a Mon Sep 17 00:00:00 2001 From: Sarina Date: Mon, 22 Jul 2024 16:55:24 +0330 Subject: [PATCH 45/91] Fix handling floating traffic limit in add_user.sh --- core/scripts/hysteria2/add_user.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/scripts/hysteria2/add_user.sh b/core/scripts/hysteria2/add_user.sh index d90ca10..90b3844 100644 --- a/core/scripts/hysteria2/add_user.sh +++ b/core/scripts/hysteria2/add_user.sh @@ -43,7 +43,7 @@ add_user() { fi # Convert GB to bytes (1 GB = 1073741824 bytes) - traffic=$((traffic_gb * 1073741824)) + traffic=$(echo "$traffic_gb * 1073741824" | bc) if [ ! -f "$USERS_FILE" ]; then echo "{}" > "$USERS_FILE" From f515a881a7901615784ae6208845e11d1acd5046 Mon Sep 17 00:00:00 2001 From: Sarina Date: Mon, 22 Jul 2024 17:03:41 +0330 Subject: [PATCH 46/91] Fix menu.sh and update.sh bugs --- core/scripts/hysteria2/update.sh | 12 ++++++------ menu.sh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/scripts/hysteria2/update.sh b/core/scripts/hysteria2/update.sh index 2b4e40b..ec371bc 100644 --- a/core/scripts/hysteria2/update.sh +++ b/core/scripts/hysteria2/update.sh @@ -8,7 +8,7 @@ echo "Backing up the current configuration..." cp "$CONFIG_FILE" /etc/hysteria/config_backup.json if [ $? -ne 0 ]; then echo "Error: Failed to back up configuration. Aborting update." - return 1 + exit 1 fi echo "Downloading and installing the latest version of Hysteria2..." @@ -17,21 +17,21 @@ if [ $? -ne 0 ]; then echo "Error: Failed to download or install the latest version. Restoring backup configuration." mv /etc/hysteria/config_backup.json "$CONFIG_FILE" python3 "$CLI_PATH" restart-hysteria2 > /dev/null 2>&1 - return 1 + exit 1 fi echo "Restoring configuration from backup..." mv /etc/hysteria/config_backup.json "$CONFIG_FILE" if [ $? -ne 0 ]; then echo "Error: Failed to restore configuration from backup." - return 1 + exit 1 fi echo "Modifying systemd service to use config.json..." sed -i "s|/etc/hysteria/config.yaml|$CONFIG_FILE|" /etc/systemd/system/hysteria-server.service if [ $? -ne 0 ]; then echo "Error: Failed to modify systemd service." - return 1 + exit 1 fi rm /etc/hysteria/config.yaml @@ -39,9 +39,9 @@ systemctl daemon-reload >/dev/null 2>&1 python3 "$CLI_PATH" restart-hysteria2 > /dev/null 2>&1 if [ $? -ne 0 ]; then echo "Error: Failed to restart Hysteria2 service." - return 1 + exit 1 fi echo "Hysteria2 has been successfully updated." echo "" -return 0 +exit 0 diff --git a/menu.sh b/menu.sh index d734f43..76e9f6a 100644 --- a/menu.sh +++ b/menu.sh @@ -73,7 +73,7 @@ hysteria2_change_port_handler() { break fi done - python3 $CLI_PATH change-port --port "$port" + python3 $CLI_PATH change-hysteria2-port --port "$port" } # TODO check it out From c8f125f7c176ebd1650c7140151f803baeac48ae Mon Sep 17 00:00:00 2001 From: Sarina Date: Mon, 22 Jul 2024 17:11:36 +0330 Subject: [PATCH 47/91] Fix typo "traffic_status" --- core/cli.py | 1 - menu.sh | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/core/cli.py b/core/cli.py index f8fce50..d9a4f89 100644 --- a/core/cli.py +++ b/core/cli.py @@ -61,7 +61,6 @@ def cli(): @cli.command('install-hysteria2') @click.option('--port','-p', required=True, help='New port for Hysteria2',type=int,callback=validator.validate_port) def install_hysteria2(port:int): - print(f"bash {Command.INSTALL_HYSTERIA2.value} {str(port)}") run_cmd(['bash', Command.INSTALL_HYSTERIA2.value, str(port)]) diff --git a/menu.sh b/menu.sh index 76e9f6a..abaf7f4 100644 --- a/menu.sh +++ b/menu.sh @@ -169,7 +169,7 @@ hysteria2_menu() { 2) hysteria2_add_user_handler ;; 3) hysteria2_modify_users ;; 4) hysteria2_show_user_uri_handler ;; - 5) python3 $CLI_PATH traffic_status ;; + 5) python3 $CLI_PATH traffic-status ;; 6) hysteria2_remove_user_handler ;; 0) return ;; *) echo "Invalid option. Please try again." ;; From a467160bbea46e258c4159f927c48747fee556e5 Mon Sep 17 00:00:00 2001 From: Sarina Date: Mon, 22 Jul 2024 17:21:27 +0330 Subject: [PATCH 48/91] Uninstall warp while uninstalling hysteria2 --- core/scripts/hysteria2/uninstall.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/scripts/hysteria2/uninstall.sh b/core/scripts/hysteria2/uninstall.sh index 5265833..b5f0371 100644 --- a/core/scripts/hysteria2/uninstall.sh +++ b/core/scripts/hysteria2/uninstall.sh @@ -1,8 +1,12 @@ +source /etc/hysteria/core/scripts/path.sh + echo "Uninstalling Hysteria2..." sleep 1 echo "Running uninstallation script..." bash <(curl -fsSL https://get.hy2.sh/) --remove >/dev/null 2>&1 sleep 1 +echo "Removing WARP" +python3 $CLI_PATH uninstall-warp echo "Removing Hysteria folder..." rm -rf /etc/hysteria >/dev/null 2>&1 sleep 1 From 6866b0030fa1c438e151ef034a5bea9edca15db9 Mon Sep 17 00:00:00 2001 From: Sarina Date: Mon, 22 Jul 2024 20:14:05 +0330 Subject: [PATCH 49/91] Add get_user.sh --- core/scripts/hysteria2/get_user.sh | 32 ++++++++++++++++++++++++++++++ install.sh | 7 ++++--- 2 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 core/scripts/hysteria2/get_user.sh diff --git a/core/scripts/hysteria2/get_user.sh b/core/scripts/hysteria2/get_user.sh new file mode 100644 index 0000000..d67b4c1 --- /dev/null +++ b/core/scripts/hysteria2/get_user.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +source /etc/hysteria/core/scripts/path.sh + + +# Check if a username is provided +if [ -z "$1" ]; then + echo "Usage: $0 " + exit 1 +fi + +USERNAME=$1 + +# Check if users.json file exists +if [ ! -f "$USERS_FILE" ]; then + echo "users.json file not found!" + exit 1 +fi + +# Extract user info using jq +USER_INFO=$(jq -r --arg username "$USERNAME" '.[$username] // empty' $USERS_FILE) + +# Check if user info is found +if [ -z "$USER_INFO" ]; then + echo "User '$USERNAME' not found." + exit 1 +fi + +# Print user info +echo "$USER_INFO" | jq . + +exit 0 diff --git a/install.sh b/install.sh index b69eb92..e213f87 100644 --- a/install.sh +++ b/install.sh @@ -13,15 +13,16 @@ if ! command -v jq &> /dev/null || ! command -v git &> /dev/null || ! command -v apt update && apt upgrade -y && apt install jq qrencode curl pwgen uuid-runtime python3 python3-pip git -y fi + +# TODO: change the url later +git clone https://github.com/Iam54r1n4/Hysteria2 /etc/hysteria + # Add alias 'hys2' for Hysteria2 if ! grep -q "alias hys2='/etc/hysteria/menu.sh'" ~/.bashrc; then echo "alias hys2='/etc/hysteria/menu.sh'" >> ~/.bashrc source ~/.bashrc fi -# TODO: change the url later -git clone https://github.com/Iam54r1n4/Hysteria2 /etc/hysteria - cd /etc/hysteria chmod +x menu.sh ./menu.sh From fe82616b7f54c960236621d26ad40b432ccfab0c Mon Sep 17 00:00:00 2001 From: Sarina Date: Mon, 22 Jul 2024 20:14:51 +0330 Subject: [PATCH 50/91] Add edit user (need fucking test) --- core/cli.py | 178 ++++++++++++++++++++-------- core/scripts/hysteria2/edit_user.sh | 154 ++++++++++++++++++++++++ 2 files changed, 280 insertions(+), 52 deletions(-) create mode 100644 core/scripts/hysteria2/edit_user.sh diff --git a/core/cli.py b/core/cli.py index d9a4f89..e74a519 100644 --- a/core/cli.py +++ b/core/cli.py @@ -14,35 +14,40 @@ import validator SCRIPT_DIR = '/etc/hysteria/core/scripts' DEBUG = True + class Command(Enum): '''Constais path to command's script''' - INSTALL_HYSTERIA2 = os.path.join(SCRIPT_DIR,'hysteria2' ,'install.sh') - UNINSTALL_HYSTERIA2 = os.path.join(SCRIPT_DIR,'hysteria2', 'uninstall.sh') - UPDATE_HYSTERIA2 = os.path.join(SCRIPT_DIR,'hysteria2', 'update.sh') - RESTART_HYSTERIA2 = os.path.join(SCRIPT_DIR,'hysteria2','restart.sh') - CHANGE_PORT_HYSTERIA2 = os.path.join(SCRIPT_DIR,'hysteria2' ,'change_port.sh') - ADD_USER = os.path.join(SCRIPT_DIR,'hysteria2' ,'add_user.sh') - EDIT_USER = os.path.join(SCRIPT_DIR,'hysteria2' ,'edit_user.sh') - REMOVE_USER = os.path.join(SCRIPT_DIR,'hysteria2' ,'remove_user.sh') - SHOW_USER_URI = os.path.join(SCRIPT_DIR,'hysteria2' ,'show_user_uri.sh') - TRAFFIC_STATUS = 'traffic.py' # won't be call directly (it's a python module) - LIST_USERS = os.path.join(SCRIPT_DIR,'hysteria2','list_users.sh') - INSTALL_TCP_BRUTAL = os.path.join(SCRIPT_DIR,'tcp-brutal', 'install.sh') - INSTALL_WARP = os.path.join(SCRIPT_DIR,'warp', 'install.sh') - UNINSTALL_WARP = os.path.join(SCRIPT_DIR,'warp', 'uninstall.sh') - CONFIGURE_WARP = os.path.join(SCRIPT_DIR,'warp', 'configure.sh') - + INSTALL_HYSTERIA2 = os.path.join(SCRIPT_DIR, 'hysteria2', 'install.sh') + UNINSTALL_HYSTERIA2 = os.path.join(SCRIPT_DIR, 'hysteria2', 'uninstall.sh') + UPDATE_HYSTERIA2 = os.path.join(SCRIPT_DIR, 'hysteria2', 'update.sh') + RESTART_HYSTERIA2 = os.path.join(SCRIPT_DIR, 'hysteria2', 'restart.sh') + CHANGE_PORT_HYSTERIA2 = os.path.join(SCRIPT_DIR, 'hysteria2', 'change_port.sh') + GET_USER = os.path.join(SCRIPT_DIR, 'hysteria2', 'get_user.sh') + ADD_USER = os.path.join(SCRIPT_DIR, 'hysteria2', 'add_user.sh') + EDIT_USER = os.path.join(SCRIPT_DIR, 'hysteria2', 'edit_user.sh') + REMOVE_USER = os.path.join(SCRIPT_DIR, 'hysteria2', 'remove_user.sh') + SHOW_USER_URI = os.path.join(SCRIPT_DIR, 'hysteria2', 'show_user_uri.sh') + TRAFFIC_STATUS = 'traffic.py' # won't be call directly (it's a python module) + LIST_USERS = os.path.join(SCRIPT_DIR, 'hysteria2', 'list_users.sh') + INSTALL_TCP_BRUTAL = os.path.join(SCRIPT_DIR, 'tcp-brutal', 'install.sh') + INSTALL_WARP = os.path.join(SCRIPT_DIR, 'warp', 'install.sh') + UNINSTALL_WARP = os.path.join(SCRIPT_DIR, 'warp', 'uninstall.sh') + CONFIGURE_WARP = os.path.join(SCRIPT_DIR, 'warp', 'configure.sh') + # region utils -def run_cmd(command:list[str]): +def run_cmd(command: list[str]): ''' Runs a command and returns the output. Could raise subprocess.CalledProcessError ''' + if DEBUG: + print(' '.join(command)) result = subprocess.check_output(command, shell=False) if DEBUG: print(result.decode().strip()) + def generate_password() -> str: ''' Generates a random password using pwgen for user. @@ -58,37 +63,48 @@ def cli(): pass # region hysteria2 menu options + + @cli.command('install-hysteria2') -@click.option('--port','-p', required=True, help='New port for Hysteria2',type=int,callback=validator.validate_port) -def install_hysteria2(port:int): +@click.option('--port', '-p', required=True, help='New port for Hysteria2', type=int, callback=validator.validate_port) +def install_hysteria2(port: int): run_cmd(['bash', Command.INSTALL_HYSTERIA2.value, str(port)]) - + @cli.command('uninstall-hysteria2') def uninstall_hysteria2(): run_cmd(['bash', Command.UNINSTALL_HYSTERIA2.value]) + @cli.command('update-hysteria2') def update_hysteria2(): run_cmd(['bash', Command.UPDATE_HYSTERIA2.value]) + @cli.command('restart-hysteria2') def restart_hysteria2(): run_cmd(['bash', Command.RESTART_HYSTERIA2.value]) @cli.command('change-hysteria2-port') -@click.option('--port','-p', required=True, help='New port for Hysteria2',type=int,callback=validator.validate_port) -def change_hysteria2_port(port:int): +@click.option('--port', '-p', required=True, help='New port for Hysteria2', type=int, callback=validator.validate_port) +def change_hysteria2_port(port: int): run_cmd(['bash', Command.CHANGE_PORT_HYSTERIA2.value, str(port)]) + +@cli.command('get-user') +@click.option('--username', '-u', required=True, help='Username for the user to get', type=str) +def get_user(username: str): + run_cmd(['bash', Command.GET_USER.value, username]) + + @cli.command('add-user') -@click.option('--username','-u', required=True, help='Username for the new user',type=str) -@click.option('--traffic-limit','-t', required=True, help='Traffic limit for the new user in GB',type=float) -@click.option('--expiration-days','-e', required=True, help='Expiration days for the new user',type=int) -@click.option('--password','-p',required=False, help='Password for the user',type=str) -@click.option('--creation-date','-c',required=False, help='Creation date for the user',type=str) -def add_user(username:str, traffic_limit:float, expiration_days:int,password:str,creation_date:str): +@click.option('--username', '-u', required=True, help='Username for the new user', type=str) +@click.option('--traffic-limit', '-t', required=True, help='Traffic limit for the new user in GB', type=float) +@click.option('--expiration-days', '-e', required=True, help='Expiration days for the new user', type=int) +@click.option('--password', '-p', required=False, help='Password for the user', type=str) +@click.option('--creation-date', '-c', required=False, help='Creation date for the user', type=str) +def add_user(username: str, traffic_limit: float, expiration_days: int, password: str, creation_date: str): if not password: try: password = generate_password() @@ -100,54 +116,112 @@ def add_user(username:str, traffic_limit:float, expiration_days:int,password:str run_cmd(['bash', Command.ADD_USER.value, username, str(traffic_limit), str(expiration_days), password, creation_date]) -@cli.command('edit-user') -@click.option('--username','-u', required=True, help='Username for the user to edit',type=str) -@click.option('--traffic-limit','-t', required=True, help='Traffic limit for the new user in GB',type=float) -@click.option('--expiration-days','-e', required=True, help='Expiration days for the new user',type=int) -def edit_user(username:str, traffic_limit:float, expiration_days:int): - run_cmd(['bash', Command.EDIT_USER.value, username, str(traffic_limit), str(expiration_days)]) -@cli.command('remove-user') -@click.option('--username','-u', required=True, help='Username for the user to remove',type=str) -def remove_user(username:str): +@click.command('edit-user') +@click.option('--username', '-u', required=True, help='Username for the user to edit', type=str) +@click.option('--new-username', '-nu', required=False, help='New username for the user', type=str) +@click.option('--new-traffic-limit', '-nt', required=False, help='Traffic limit for the new user in GB', type=float) +@click.option('--new-expiration-days', '-ne', required=False, help='Expiration days for the new user', type=int) +@click.option('--renew-password', '-rp', is_flag=True, help='Renew password for the user') +@click.option('--renew-creation-date', '-rc', is_flag=True, help='Renew creation date for the user') +@click.option('--blocked', '-b', is_flag=True, help='Block the user') +def edit_user(username: str, new_username: str, new_traffic_limit: float, new_expiration_days: int, renew_password: bool, renew_creation_date: bool, blocked: bool): + if not username: + print('Error: username is required') + exit(1) + + if not any([new_username, new_traffic_limit, new_expiration_days, renew_password, renew_creation_date, blocked is not None]): + print('Error: at least one option is required') + exit(1) + + if new_traffic_limit is not None and new_traffic_limit <= 0: + print('Error: traffic limit must be greater than 0') + exit(1) + + if new_expiration_days is not None and new_expiration_days <= 0: + print('Error: expiration days must be greater than 0') + exit(1) + + # Handle renewing password and creation date + if renew_password: + try: + password = generate_password() + except subprocess.CalledProcessError as e: + print(f'Error: failed to generate password\n{e}') + exit(1) + else: + password = "" + + if renew_creation_date: + creation_date = datetime.now().strftime('%Y-%m-%d') + else: + creation_date = "" + + # Prepare arguments for the command + command_args = [ + 'bash', + 'edit_user.sh', # Replace with the actual path to your script + username, + new_username or '', + str(new_traffic_limit) if new_traffic_limit is not None else '', + str(new_expiration_days) if new_expiration_days is not None else '', + password, + creation_date, + str(blocked).lower() if blocked is not None else 'false' + ] + + run_cmd(command_args) + + +@ cli.command('remove-user') +@ click.option('--username', '-u', required=True, help='Username for the user to remove', type=str) +def remove_user(username: str): run_cmd(['bash', Command.REMOVE_USER.value, username]) -@cli.command('show-user-uri') -@click.option('--username','-u', required=True, help='Username for the user to show the URI',type=str) -def show_user_uri(username:str): + +@ cli.command('show-user-uri') +@ click.option('--username', '-u', required=True, help='Username for the user to show the URI', type=str) +def show_user_uri(username: str): run_cmd(['bash', Command.SHOW_USER_URI.value, username]) -@cli.command('traffic-status') + +@ cli.command('traffic-status') def traffic_status(): traffic.traffic_status() -@cli.command('list-users') + +@ cli.command('list-users') def list_users(): - run_cmd(['bash',Command.LIST_USERS.value]) + run_cmd(['bash', Command.LIST_USERS.value]) # endregion # region advanced menu -@cli.command('install-tcp-brutal') + +@ cli.command('install-tcp-brutal') def install_tcp_brutal(): run_cmd(['bash', Command.INSTALL_TCP_BRUTAL.value]) -@cli.command('install-warp') + +@ cli.command('install-warp') def install_warp(): run_cmd(['bash', Command.INSTALL_WARP.value]) -@cli.command('uninstall-warp') + +@ cli.command('uninstall-warp') def uninstall_warp(): run_cmd(['bash', Command.UNINSTALL_WARP.value]) -@cli.command('configure-warp') -@click.option('--warp-mode','-m', required=True, help='Warp mode',type=click.Choice(['proxy','direct','reject'])) -@click.option('--block-porn','-p', required=False, help='Block porn',type=bool) -def configure_warp(warp_mode:str, block_porn:bool): + +@ cli.command('configure-warp') +@ click.option('--warp-mode', '-m', required=True, help='Warp mode', type=click.Choice(['proxy', 'direct', 'reject'])) +@ click.option('--block-porn', '-p', required=False, help='Block porn', type=bool) +def configure_warp(warp_mode: str, block_porn: bool): run_cmd(['bash', Command.CONFIGURE_WARP.value, warp_mode, str(block_porn)]) - + # endregion + if __name__ == '__main__': - cli() \ No newline at end of file + cli() diff --git a/core/scripts/hysteria2/edit_user.sh b/core/scripts/hysteria2/edit_user.sh new file mode 100644 index 0000000..b3044f3 --- /dev/null +++ b/core/scripts/hysteria2/edit_user.sh @@ -0,0 +1,154 @@ +#!/bin/bash + +source /etc/hysteria/core/scripts/utils.sh +source /etc/hysteria/core/scripts/path.sh + +# Function to validate all user input fields +validate_inputs() { + local new_username=$1 + local new_password=$2 + local new_traffic_limit=$3 + local new_expiration_days=$4 + local new_creation_date=$5 + local new_blocked=$6 + + # Validate username + if [ -n "$new_username" ]; then + if ! [[ "$new_username" =~ ^[a-z0-9]+$ ]]; then + echo -e "${red}Error:${NC} Username can only contain lowercase letters and numbers." + exit 1 + fi + fi + + # Validate traffic limit + if [ -n "$new_traffic_limit" ]; then + if ! [[ "$new_traffic_limit" =~ ^[0-9]+$ ]]; then + echo -e "${red}Error:${NC} Traffic limit must be a valid integer." + exit 1 + fi + fi + + # Validate expiration days + if [ -n "$new_expiration_days" ]; then + if ! [[ "$new_expiration_days" =~ ^[0-9]+$ ]]; then + echo -e "${red}Error:${NC} Expiration days must be a valid integer." + exit 1 + fi + fi + + # Validate date format + if [ -n "$new_creation_date" ]; then + if ! [[ "$new_creation_date" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]; then + echo "Invalid date format. Expected YYYY-MM-DD." + exit 1 + elif ! date -d "$new_creation_date" >/dev/null 2>&1; then + echo "Invalid date. Please provide a valid date in YYYY-MM-DD format." + exit 1 + fi + fi + + # Validate blocked status + if [ -n "$new_blocked" ]; then + if [ "$new_blocked" != "true" ] && [ "$new_blocked" != "false" ]; then + echo -e "${red}Error:${NC} Blocked status must be 'true' or 'false'." + exit 1 + fi + fi +} + +# Function to get user info +get_user_info() { + local username=$1 + python3 /etc/hysteria/core/scripts/get_user.py "$username" +} + +# Function to update user info in JSON +update_user_info() { + local old_username=$1 + local new_username=$2 + local new_password=$3 + local new_max_download_bytes=$4 + local new_expiration_days=$5 + local new_account_creation_date=$6 + local new_blocked=$7 + + if [ ! -f "$USERS_FILE" ]; then + echo "Error: File '$USERS_FILE' not found." + return 1 + fi + + # Check if the old username exists + user_exists=$(jq -e --arg username "$old_username" '.[$username]' "$USERS_FILE") + if [ $? -ne 0 ]; then + echo "Error: User '$old_username' not found." + return 1 + fi + + # Prepare jq filter to update the fields + jq_filter='.[$old_username] = + if $new_password != "" then .password = $new_password else . end | + if $new_max_download_bytes != null then .max_download_bytes = $new_max_download_bytes else . end | + if $new_expiration_days != null then .expiration_days = $new_expiration_days else . end | + if $new_account_creation_date != "" then .account_creation_date = $new_account_creation_date else . end | + if $new_blocked != null then .blocked = $new_blocked else . end' + + # Rename the user if new_username is provided + if [ -n "$new_username" ]; then + jq_filter=$(echo "$jq_filter" | sed "s|.$old_username|.$new_username|") + fi + + jq --arg old_username "$old_username" \ + --arg new_username "$new_username" \ + --arg new_password "$new_password" \ + --argjson new_max_download_bytes "$new_max_download_bytes" \ + --argjson new_expiration_days "$new_expiration_days" \ + --arg new_account_creation_date "$new_account_creation_date" \ + --argjson new_blocked "$new_blocked" \ + "$jq_filter" \ + "$USERS_FILE" > tmp.$$.json && mv tmp.$$.json "$USERS_FILE" + + echo "User '$old_username' updated successfully." +} + +# Main function to edit user +edit_user() { + local username=$1 + local new_username=$2 + local new_traffic_limit=$3 + local new_expiration_days=$4 + local new_password=$5 + local new_creation_date=$6 + local new_blocked=$7 + + # Get user info + user_info=$(get_user_info "$username") + if [ -z "$user_info" ]; then + echo -e "${red}Error:${NC} User '$username' not found." + exit 1 + fi + + # Extract user info + local password=$(echo "$user_info" | jq -r '.password') + local traffic_limit=$(echo "$user_info" | jq -r '.max_download_bytes') + local expiration_days=$(echo "$user_info" | jq -r '.expiration_days') + local creation_date=$(echo "$user_info" | jq -r '.account_creation_date') + local blocked=$(echo "$user_info" | jq -r '.blocked') + + # Validate all inputs + validate_inputs "$new_username" "$new_password" "$new_traffic_limit" "$new_expiration_days" "$new_creation_date" "$new_blocked" + + # Set new values with validation + new_username=${new_username:-$username} + new_password=${new_password:-$password} + new_traffic_limit=${new_traffic_limit:-$traffic_limit} + new_traffic_limit=$(echo "$new_traffic_limit * 1073741824" | bc) + new_expiration_days=${new_expiration_days:-$expiration_days} + new_creation_date=${new_creation_date:-$creation_date} + new_blocked=${new_blocked:-$blocked} + + # Update user info in JSON file + update_user_info "$username" "$new_username" "$new_password" "$new_traffic_limit" "$new_expiration_days" "$new_creation_date" "$new_blocked" +} + +# Run the script +edit_user "$1" "$2" "$3" "$4" "$5" "$6" "$7" From 6dac40d2b2fd64528bf1ca9ac3c79d7909db1299 Mon Sep 17 00:00:00 2001 From: Sarina Date: Mon, 22 Jul 2024 20:16:44 +0330 Subject: [PATCH 51/91] Fix bug in traffic limit calculating --- menu.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/menu.sh b/menu.sh index abaf7f4..529c02a 100644 --- a/menu.sh +++ b/menu.sh @@ -28,8 +28,6 @@ hysteria2_add_user_handler() { done read -p "Enter the traffic limit (in GB): " traffic_gb - # Convert GB to bytes (1 GB = 1073741824 bytes) - traffic=$((traffic_gb * 1073741824)) read -p "Enter the expiration days: " expiration_days password=$(pwgen -s 32 1) From 18468f2cfc9af999f3506fd6f51697e3ab69b918 Mon Sep 17 00:00:00 2001 From: Sarina Date: Mon, 22 Jul 2024 21:00:22 +0330 Subject: [PATCH 52/91] Add edit handler in menu.sh --- menu.sh | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 78 insertions(+), 8 deletions(-) diff --git a/menu.sh b/menu.sh index 529c02a..d11816f 100644 --- a/menu.sh +++ b/menu.sh @@ -74,15 +74,85 @@ hysteria2_change_port_handler() { python3 $CLI_PATH change-hysteria2-port --port "$port" } -# TODO check it out -# Function to modify users -hysteria2_modify_users() { - modify_script="/etc/hysteria/users/modify.py" - github_raw_url="https://raw.githubusercontent.com/ReturnFI/Hysteria2/main/modify.py" +hysteria2_edit_user() { + # Function to prompt for user input with validation + prompt_for_input() { + local prompt_message="$1" + local validation_regex="$2" + local default_value="$3" + local input_variable_name="$4" - [ -f "$modify_script" ] || wget "$github_raw_url" -O "$modify_script" >/dev/null 2>&1 + while true; do + read -p "$prompt_message" input + if [[ -z "$input" ]]; then + input="$default_value" + fi + if [[ "$input" =~ $validation_regex ]]; then + eval "$input_variable_name='$input'" + break + else + echo -e "\033[0;31mError:\033[0m Invalid input. Please try again." + fi + done + } - python3 "$modify_script" + # Prompt for username + prompt_for_input "Enter the username you want to edit: " '^[a-z0-9]+$' '' username + + # Check if user exists + if ! python3 $CLI_PATH get-user --username "$username" > /dev/null 2>&1; then + echo -e "\033[0;31mError:\033[0m User '$username' not found." + return 1 + fi + + # Prompt for new username + prompt_for_input "Enter the new username (leave empty to keep the current username): " '^[a-z0-9]*$' '' new_username + + # Prompt for new traffic limit + prompt_for_input "Enter the new traffic limit (in GB) (leave empty to keep the current limit): " '^[0-9]*$' '' new_traffic_limit_GB + + # Prompt for new expiration days + prompt_for_input "Enter the new expiration days (leave empty to keep the current expiration days): " '^[0-9]*$' '' new_expiration_days + + # Prompt for renewing password + while true; do + read -p "Do you want to generate a new password? (y/n): " renew_password + case "$renew_password" in + y|Y) renew_password=true; break ;; + n|N) renew_password=false; break ;; + *) echo -e "\033[0;31mError:\033[0m Please answer 'y' or 'n'." ;; + esac + done + + # Prompt for renewing creation date + while true; do + read -p "Do you want to generate a new creation date? (y/n): " renew_creation_date + case "$renew_creation_date" in + y|Y) renew_creation_date=true; break ;; + n|N) renew_creation_date=false; break ;; + *) echo -e "\033[0;31mError:\033[0m Please answer 'y' or 'n'." ;; + esac + done + + # Prompt for blocking user + while true; do + read -p "Do you want to block the user? (y/n): " block_user + case "$block_user" in + y|Y) blocked=true; break ;; + n|N) blocked=false; break ;; + *) echo -e "\033[0;31mError:\033[0m Please answer 'y' or 'n'." ;; + esac + done + + # Call the edit-user script with appropriate flags + python3 $CLI_PATH edit-user \ + --username "$username" \ + ${new_username:+--new-username "$new_username"} \ + ${new_traffic_limit_GB:+--new-traffic-limit "$new_traffic_limit_GB"} \ + ${new_expiration_days:+--new-expiration-days "$new_expiration_days"} \ + ${renew_password:+--renew-password} \ + ${renew_creation_date:+--renew-creation-date} \ + ${blocked:+--blocked} } warp_configure_handler() { @@ -165,7 +235,7 @@ hysteria2_menu() { case $choice in 1) hysteria2_install_handler ;; 2) hysteria2_add_user_handler ;; - 3) hysteria2_modify_users ;; + 3) hysteria2_edit_user ;; 4) hysteria2_show_user_uri_handler ;; 5) python3 $CLI_PATH traffic-status ;; 6) hysteria2_remove_user_handler ;; From ad43a0372cf0da58c428a6ba70e786c510d08696 Mon Sep 17 00:00:00 2001 From: Sarina Date: Tue, 23 Jul 2024 00:15:05 +0330 Subject: [PATCH 53/91] Fix bug in adding user --- menu.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/menu.sh b/menu.sh index d11816f..bf5b7fa 100644 --- a/menu.sh +++ b/menu.sh @@ -27,13 +27,13 @@ hysteria2_add_user_handler() { fi done - read -p "Enter the traffic limit (in GB): " traffic_gb + read -p "Enter the traffic limit (in GB): " traffic_limit_GB read -p "Enter the expiration days: " expiration_days password=$(pwgen -s 32 1) creation_date=$(date +%Y-%m-%d) - python3 $CLI_PATH add-user --username "$username" --traffic-limit "$traffic" --expiration-days "$expiration_days" --password "$password" --creation-date "$creation_date" + python3 $CLI_PATH add-user --username "$username" --traffic-limit "$traffic_limit_GB" --expiration-days "$expiration_days" --password "$password" --creation-date "$creation_date" } hysteria2_remove_user_handler() { From f61990a134997693a3dd31e1aa77a5b01cdc7bab Mon Sep 17 00:00:00 2001 From: Sarina Date: Tue, 23 Jul 2024 00:19:34 +0330 Subject: [PATCH 54/91] Fix typo bug --- core/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/cli.py b/core/cli.py index e74a519..ba23176 100644 --- a/core/cli.py +++ b/core/cli.py @@ -117,7 +117,7 @@ def add_user(username: str, traffic_limit: float, expiration_days: int, password run_cmd(['bash', Command.ADD_USER.value, username, str(traffic_limit), str(expiration_days), password, creation_date]) -@click.command('edit-user') +@cli.command('edit-user') @click.option('--username', '-u', required=True, help='Username for the user to edit', type=str) @click.option('--new-username', '-nu', required=False, help='New username for the user', type=str) @click.option('--new-traffic-limit', '-nt', required=False, help='Traffic limit for the new user in GB', type=float) From b9489077486c715134d8176a54bea1530a0c8952 Mon Sep 17 00:00:00 2001 From: Sarina Date: Tue, 23 Jul 2024 00:25:57 +0330 Subject: [PATCH 55/91] Fix chatgpt thing --- core/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/cli.py b/core/cli.py index ba23176..55ea25c 100644 --- a/core/cli.py +++ b/core/cli.py @@ -160,7 +160,7 @@ def edit_user(username: str, new_username: str, new_traffic_limit: float, new_ex # Prepare arguments for the command command_args = [ 'bash', - 'edit_user.sh', # Replace with the actual path to your script + Command.EDIT_USER.value, username, new_username or '', str(new_traffic_limit) if new_traffic_limit is not None else '', From 5bb8dbbf6103e54022ff8ce705c037ee89dd49a1 Mon Sep 17 00:00:00 2001 From: Sarina Date: Tue, 23 Jul 2024 00:30:15 +0330 Subject: [PATCH 56/91] Fix bug in edit_user.sh --- core/scripts/hysteria2/edit_user.sh | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/core/scripts/hysteria2/edit_user.sh b/core/scripts/hysteria2/edit_user.sh index b3044f3..21a3234 100644 --- a/core/scripts/hysteria2/edit_user.sh +++ b/core/scripts/hysteria2/edit_user.sh @@ -21,7 +21,7 @@ validate_inputs() { fi # Validate traffic limit - if [ -n "$new_traffic_limit" ]; then + if [[ ! "$new_traffic_limit" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then if ! [[ "$new_traffic_limit" =~ ^[0-9]+$ ]]; then echo -e "${red}Error:${NC} Traffic limit must be a valid integer." exit 1 @@ -59,7 +59,7 @@ validate_inputs() { # Function to get user info get_user_info() { local username=$1 - python3 /etc/hysteria/core/scripts/get_user.py "$username" + python3 $CLI_PATH get-user -u "$username" } # Function to update user info in JSON @@ -87,10 +87,10 @@ update_user_info() { # Prepare jq filter to update the fields jq_filter='.[$old_username] = if $new_password != "" then .password = $new_password else . end | - if $new_max_download_bytes != null then .max_download_bytes = $new_max_download_bytes else . end | - if $new_expiration_days != null then .expiration_days = $new_expiration_days else . end | + if $new_max_download_bytes != "" then .max_download_bytes = ($new_max_download_bytes|tonumber) else . end | + if $new_expiration_days != "" then .expiration_days = ($new_expiration_days|tonumber) else . end | if $new_account_creation_date != "" then .account_creation_date = $new_account_creation_date else . end | - if $new_blocked != null then .blocked = $new_blocked else . end' + if $new_blocked != "" then .blocked = ($new_blocked|test("true")) else . end' # Rename the user if new_username is provided if [ -n "$new_username" ]; then @@ -100,16 +100,17 @@ update_user_info() { jq --arg old_username "$old_username" \ --arg new_username "$new_username" \ --arg new_password "$new_password" \ - --argjson new_max_download_bytes "$new_max_download_bytes" \ - --argjson new_expiration_days "$new_expiration_days" \ + --arg new_max_download_bytes "$new_max_download_bytes" \ + --arg new_expiration_days "$new_expiration_days" \ --arg new_account_creation_date "$new_account_creation_date" \ - --argjson new_blocked "$new_blocked" \ + --arg new_blocked "$new_blocked" \ "$jq_filter" \ "$USERS_FILE" > tmp.$$.json && mv tmp.$$.json "$USERS_FILE" echo "User '$old_username' updated successfully." } + # Main function to edit user edit_user() { local username=$1 From b4b3d2249732067e3d1015eb70dd9377b0e9a8b6 Mon Sep 17 00:00:00 2001 From: Sarina Date: Tue, 23 Jul 2024 01:04:09 +0330 Subject: [PATCH 57/91] Change --traffic-limit argument to int as old version --- core/cli.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/cli.py b/core/cli.py index 55ea25c..2700601 100644 --- a/core/cli.py +++ b/core/cli.py @@ -100,11 +100,11 @@ def get_user(username: str): @cli.command('add-user') @click.option('--username', '-u', required=True, help='Username for the new user', type=str) -@click.option('--traffic-limit', '-t', required=True, help='Traffic limit for the new user in GB', type=float) +@click.option('--traffic-limit', '-t', required=True, help='Traffic limit for the new user in GB', type=int) @click.option('--expiration-days', '-e', required=True, help='Expiration days for the new user', type=int) @click.option('--password', '-p', required=False, help='Password for the user', type=str) @click.option('--creation-date', '-c', required=False, help='Creation date for the user', type=str) -def add_user(username: str, traffic_limit: float, expiration_days: int, password: str, creation_date: str): +def add_user(username: str, traffic_limit: int, expiration_days: int, password: str, creation_date: str): if not password: try: password = generate_password() @@ -120,12 +120,12 @@ def add_user(username: str, traffic_limit: float, expiration_days: int, password @cli.command('edit-user') @click.option('--username', '-u', required=True, help='Username for the user to edit', type=str) @click.option('--new-username', '-nu', required=False, help='New username for the user', type=str) -@click.option('--new-traffic-limit', '-nt', required=False, help='Traffic limit for the new user in GB', type=float) +@click.option('--new-traffic-limit', '-nt', required=False, help='Traffic limit for the new user in GB', type=int) @click.option('--new-expiration-days', '-ne', required=False, help='Expiration days for the new user', type=int) @click.option('--renew-password', '-rp', is_flag=True, help='Renew password for the user') @click.option('--renew-creation-date', '-rc', is_flag=True, help='Renew creation date for the user') @click.option('--blocked', '-b', is_flag=True, help='Block the user') -def edit_user(username: str, new_username: str, new_traffic_limit: float, new_expiration_days: int, renew_password: bool, renew_creation_date: bool, blocked: bool): +def edit_user(username: str, new_username: str, new_traffic_limit: int, new_expiration_days: int, renew_password: bool, renew_creation_date: bool, blocked: bool): if not username: print('Error: username is required') exit(1) From e304b9f5f8f7c66f82342ed8393bc4dfa7dd84df Mon Sep 17 00:00:00 2001 From: Sarina Date: Tue, 23 Jul 2024 01:05:48 +0330 Subject: [PATCH 58/91] Modify edit_user --- core/cli.py | 2 +- core/scripts/hysteria2/edit_user.sh | 62 +++++++++++++++++++---------- 2 files changed, 43 insertions(+), 21 deletions(-) diff --git a/core/cli.py b/core/cli.py index 2700601..ef9a4a3 100644 --- a/core/cli.py +++ b/core/cli.py @@ -41,7 +41,7 @@ def run_cmd(command: list[str]): Runs a command and returns the output. Could raise subprocess.CalledProcessError ''' - if DEBUG: + if DEBUG and Command.GET_USER.value not in command: print(' '.join(command)) result = subprocess.check_output(command, shell=False) if DEBUG: diff --git a/core/scripts/hysteria2/edit_user.sh b/core/scripts/hysteria2/edit_user.sh index 21a3234..3fc4c4d 100644 --- a/core/scripts/hysteria2/edit_user.sh +++ b/core/scripts/hysteria2/edit_user.sh @@ -77,35 +77,56 @@ update_user_info() { return 1 fi + + echo "checking if user exists" # Check if the old username exists user_exists=$(jq -e --arg username "$old_username" '.[$username]' "$USERS_FILE") if [ $? -ne 0 ]; then echo "Error: User '$old_username' not found." return 1 fi + echo "user exists done" - # Prepare jq filter to update the fields - jq_filter='.[$old_username] = - if $new_password != "" then .password = $new_password else . end | - if $new_max_download_bytes != "" then .max_download_bytes = ($new_max_download_bytes|tonumber) else . end | - if $new_expiration_days != "" then .expiration_days = ($new_expiration_days|tonumber) else . end | - if $new_account_creation_date != "" then .account_creation_date = $new_account_creation_date else . end | - if $new_blocked != "" then .blocked = ($new_blocked|test("true")) else . end' + echo "change key" + # If new_username is provided and different from old_username, rename the key + if [ -n "$new_username" ] && [ "$old_username" != "$new_username" ]; then + jq --arg old_username "$old_username" \ + --arg new_username "$new_username" \ + 'if .[$new_username] then error("User already exists with new username") else . end | + .[$new_username] = .[$old_username] | del(.[$old_username])' \ + "$USERS_FILE" > tmp.$$.json && mv tmp.$$.json "$USERS_FILE" - # Rename the user if new_username is provided - if [ -n "$new_username" ]; then - jq_filter=$(echo "$jq_filter" | sed "s|.$old_username|.$new_username|") + if [ $? -ne 0 ]; then + echo "Error: Failed to rename user '$old_username' to '$new_username'." + return 1 + fi fi + echo "change key done" - jq --arg old_username "$old_username" \ - --arg new_username "$new_username" \ - --arg new_password "$new_password" \ - --arg new_max_download_bytes "$new_max_download_bytes" \ - --arg new_expiration_days "$new_expiration_days" \ - --arg new_account_creation_date "$new_account_creation_date" \ - --arg new_blocked "$new_blocked" \ - "$jq_filter" \ - "$USERS_FILE" > tmp.$$.json && mv tmp.$$.json "$USERS_FILE" + echo "update user fields" + # print all new values + echo "Old username" "$old_username" + echo "New username: $new_username" + echo "New password: $new_password" + echo "New traffic limit: $new_max_download_bytes" + echo "New expiration days: $new_expiration_days" + echo "New creation date: $new_account_creation_date" + echo "New blocked status: $new_blocked" + + jq --arg username "$new_username" \ + --arg password "$new_password" \ + --argjson max_download_bytes "$new_max_download_bytes" \ + --argjson expiration_days "$new_expiration_days" \ + --arg account_creation_date "$new_account_creation_date" \ + --argjson blocked "$new_blocked" \ + '.[$username] |= (.password = $password | .max_download_bytes = $max_download_bytes | .expiration_days = $expiration_days | .account_creation_date = $account_creation_date | .blocked = $blocked)' \ + "$USERS_FILE" > tmp.$$.json && mv tmp.$$.json "$USERS_FILE" + + echo "update user fields done" + if [ $? -ne 0 ]; then + echo "Error: Failed to update user '$old_username'." + return 1 + fi echo "User '$old_username' updated successfully." } @@ -123,7 +144,7 @@ edit_user() { # Get user info user_info=$(get_user_info "$username") - if [ -z "$user_info" ]; then + if [ $? -ne 0 ] || [ -z "$user_info" ]; then echo -e "${red}Error:${NC} User '$username' not found." exit 1 fi @@ -147,6 +168,7 @@ edit_user() { new_creation_date=${new_creation_date:-$creation_date} new_blocked=${new_blocked:-$blocked} + # Update user info in JSON file update_user_info "$username" "$new_username" "$new_password" "$new_traffic_limit" "$new_expiration_days" "$new_creation_date" "$new_blocked" } From 22bb05d5a1aedd35417abf7bf4958a8ea47a8a80 Mon Sep 17 00:00:00 2001 From: Sarina Date: Tue, 23 Jul 2024 15:51:35 +0330 Subject: [PATCH 59/91] Change order of hysteria2 menu & Add Get user(complete) and List user (WIP) --- menu.sh | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/menu.sh b/menu.sh index bf5b7fa..46e9467 100644 --- a/menu.sh +++ b/menu.sh @@ -62,6 +62,18 @@ hysteria2_show_user_uri_handler() { python3 $CLI_PATH show-user-uri --username "$username" } +hysteria2_get_user_handler() { + while true; do + read -p "Enter the username: " username + if [[ "$username" =~ ^[a-z0-9]+$ ]]; then + break + else + echo -e "\033[0;31mError:\033[0m Username can only contain lowercase letters and numbers." + fi + done + python $CLI_PATH get-user --username "$username" +} + hysteria2_change_port_handler() { while true; do read -p "Enter the new port number you want to use: " port @@ -212,10 +224,12 @@ display_hysteria2_menu() { echo -e "${green}[1] ${NC}↝ Install and Configure Hysteria2" echo -e "${cyan}[2] ${NC}↝ Add User" - echo -e "${cyan}[3] ${NC}↝ Modify User" - echo -e "${cyan}[4] ${NC}↝ Show URI" - echo -e "${cyan}[5] ${NC}↝ Check Traffic Status" - echo -e "${cyan}[6] ${NC}↝ Remove User" + echo -e "${cyan}[3] ${NC}↝ Edit User" + echo -e "${cyan}[4] ${NC}↝ Remove User" + echo -e "${cyan}[5] ${NC}↝ Get User" + echo -e "${cyan}[6] ${NC}↝ List Users (WIP)" + echo -e "${cyan}[7] ${NC}↝ Check Traffic Status" + echo -e "${cyan}[8] ${NC}↝ Show User URI" echo -e "${red}[0] ${NC}↝ Back to Main Menu" @@ -236,9 +250,11 @@ hysteria2_menu() { 1) hysteria2_install_handler ;; 2) hysteria2_add_user_handler ;; 3) hysteria2_edit_user ;; - 4) hysteria2_show_user_uri_handler ;; - 5) python3 $CLI_PATH traffic-status ;; - 6) hysteria2_remove_user_handler ;; + 4) hysteria2_remove_user_handler ;; + 5) hysteria2_get_user_handler ;; + 6) python3 $CLI_PATH list-users ;; + 7) python3 $CLI_PATH traffic-status ;; + 8) hysteria2_show_user_uri_handler ;; 0) return ;; *) echo "Invalid option. Please try again." ;; esac From 63bcc9687021d3ceb9c4e3fed5df00b08e22ff6d Mon Sep 17 00:00:00 2001 From: Sarina Date: Tue, 23 Jul 2024 15:55:29 +0330 Subject: [PATCH 60/91] Fix typo --- menu.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/menu.sh b/menu.sh index 46e9467..878fa39 100644 --- a/menu.sh +++ b/menu.sh @@ -71,7 +71,7 @@ hysteria2_get_user_handler() { echo -e "\033[0;31mError:\033[0m Username can only contain lowercase letters and numbers." fi done - python $CLI_PATH get-user --username "$username" + python3 $CLI_PATH get-user --username "$username" } hysteria2_change_port_handler() { From 21077f046c90a00a3d856e5be50af3d8b2b641eb Mon Sep 17 00:00:00 2001 From: Sarina Date: Tue, 23 Jul 2024 17:29:17 +0330 Subject: [PATCH 61/91] Add list users (for test) --- core/scripts/hysteria2/list_users.sh | 6 ++ menu.sh | 123 ++++++++++++++++----------- 2 files changed, 78 insertions(+), 51 deletions(-) diff --git a/core/scripts/hysteria2/list_users.sh b/core/scripts/hysteria2/list_users.sh index e69de29..b3d3608 100644 --- a/core/scripts/hysteria2/list_users.sh +++ b/core/scripts/hysteria2/list_users.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +source /etc/hysteria/core/scripts/path.sh + + +cat "$USER_FILE" \ No newline at end of file diff --git a/menu.sh b/menu.sh index 878fa39..e144587 100644 --- a/menu.sh +++ b/menu.sh @@ -36,56 +36,6 @@ hysteria2_add_user_handler() { python3 $CLI_PATH add-user --username "$username" --traffic-limit "$traffic_limit_GB" --expiration-days "$expiration_days" --password "$password" --creation-date "$creation_date" } -hysteria2_remove_user_handler() { - while true; do - read -p "Enter the username: " username - - if [[ "$username" =~ ^[a-z0-9]+$ ]]; then - break - else - echo -e "\033[0;31mError:\033[0m Username can only contain lowercase letters and numbers." - fi - done - python3 $CLI_PATH remove-user --username "$username" -} - -hysteria2_show_user_uri_handler() { - while true; do - read -p "Enter the username: " username - - if [[ "$username" =~ ^[a-z0-9]+$ ]]; then - break - else - echo -e "\033[0;31mError:\033[0m Username can only contain lowercase letters and numbers." - fi - done - python3 $CLI_PATH show-user-uri --username "$username" -} - -hysteria2_get_user_handler() { - while true; do - read -p "Enter the username: " username - if [[ "$username" =~ ^[a-z0-9]+$ ]]; then - break - else - echo -e "\033[0;31mError:\033[0m Username can only contain lowercase letters and numbers." - fi - done - python3 $CLI_PATH get-user --username "$username" -} - -hysteria2_change_port_handler() { - while true; do - read -p "Enter the new port number you want to use: " port - if ! [[ "$port" =~ ^[0-9]+$ ]] || [ "$port" -lt 1 ] || [ "$port" -gt 65535 ]; then - echo "Invalid port number. Please enter a number between 1 and 65535." - else - break - fi - done - python3 $CLI_PATH change-hysteria2-port --port "$port" -} - hysteria2_edit_user() { # Function to prompt for user input with validation prompt_for_input() { @@ -167,6 +117,77 @@ hysteria2_edit_user() { ${blocked:+--blocked} } +hysteria2_remove_user_handler() { + while true; do + read -p "Enter the username: " username + + if [[ "$username" =~ ^[a-z0-9]+$ ]]; then + break + else + echo -e "\033[0;31mError:\033[0m Username can only contain lowercase letters and numbers." + fi + done + python3 $CLI_PATH remove-user --username "$username" +} + +hysteria2_get_user_handler() { + while true; do + read -p "Enter the username: " username + if [[ "$username" =~ ^[a-z0-9]+$ ]]; then + break + else + echo -e "\033[0;31mError:\033[0m Username can only contain lowercase letters and numbers." + fi + done + python3 $CLI_PATH get-user --username "$username" +} + +hysteria2_list_users_handler() { + users_json=$(python3 $CLI_PATH list-users) + users_array=($(echo "$users_json" | jq -r '.[] | .username')) + + if [[ ${#users_array[@]} -eq 0 ]]; then + echo -e "\033[0;31mError:\033[0m No users found." + return 1 + fi + + # Print headers + echo -e "\033[0;32mUsers:\033[0m" + printf "%-20s %-15s %-15s %-20s %-30s %-10s\n" "Username" "Traffic Limit (GB)" "Expiration (Days)" "Creation Date" "Password" "Blocked" + + # Print user details + echo "$users_json" | jq -r '.[] | "\(.username) \(.traffic_limit_GB) \(.expiration_days) \(.creation_date) \(.password) \(.blocked)"' | \ + while IFS= read -r line; do + IFS=' ' read -r username traffic_limit expiration_date creation_date password blocked <<< "$line" + printf "%-20s %-15s %-15s %-20s %-30s %-10s\n" "$username" "$traffic_limit" "$expiration_date" "$creation_date" "$password" "$blocked" + done +} + +hysteria2_show_user_uri_handler() { + while true; do + read -p "Enter the username: " username + + if [[ "$username" =~ ^[a-z0-9]+$ ]]; then + break + else + echo -e "\033[0;31mError:\033[0m Username can only contain lowercase letters and numbers." + fi + done + python3 $CLI_PATH show-user-uri --username "$username" +} + +hysteria2_change_port_handler() { + while true; do + read -p "Enter the new port number you want to use: " port + if ! [[ "$port" =~ ^[0-9]+$ ]] || [ "$port" -lt 1 ] || [ "$port" -gt 65535 ]; then + echo "Invalid port number. Please enter a number between 1 and 65535." + else + break + fi + done + python3 $CLI_PATH change-hysteria2-port --port "$port" +} + warp_configure_handler() { # Placeholder function, add implementation here if needed echo "empty" @@ -252,7 +273,7 @@ hysteria2_menu() { 3) hysteria2_edit_user ;; 4) hysteria2_remove_user_handler ;; 5) hysteria2_get_user_handler ;; - 6) python3 $CLI_PATH list-users ;; + 6) hysteria2_list_users_handler ;; 7) python3 $CLI_PATH traffic-status ;; 8) hysteria2_show_user_uri_handler ;; 0) return ;; From b13ee6c335ef4c0b016dc7e709d703708b51b10d Mon Sep 17 00:00:00 2001 From: Sarina Date: Tue, 23 Jul 2024 17:35:01 +0330 Subject: [PATCH 62/91] Remove dealy from uninstall.sh --- core/scripts/hysteria2/uninstall.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/core/scripts/hysteria2/uninstall.sh b/core/scripts/hysteria2/uninstall.sh index b5f0371..f5617b6 100644 --- a/core/scripts/hysteria2/uninstall.sh +++ b/core/scripts/hysteria2/uninstall.sh @@ -1,28 +1,28 @@ source /etc/hysteria/core/scripts/path.sh echo "Uninstalling Hysteria2..." -sleep 1 +#sleep 1 echo "Running uninstallation script..." bash <(curl -fsSL https://get.hy2.sh/) --remove >/dev/null 2>&1 -sleep 1 +#sleep 1 echo "Removing WARP" python3 $CLI_PATH uninstall-warp echo "Removing Hysteria folder..." rm -rf /etc/hysteria >/dev/null 2>&1 -sleep 1 +#sleep 1 echo "Deleting hysteria user..." userdel -r hysteria >/dev/null 2>&1 -sleep 1 +#sleep 1 echo "Removing systemd service files..." rm -f /etc/systemd/system/multi-user.target.wants/hysteria-server.service >/dev/null 2>&1 rm -f /etc/systemd/system/multi-user.target.wants/hysteria-server@*.service >/dev/null 2>&1 -sleep 1 +#sleep 1 echo "Reloading systemd daemon..." systemctl daemon-reload >/dev/null 2>&1 -sleep 1 +#sleep 1 echo "Removing cron jobs..." (crontab -l | grep -v "python3 /etc/hysteria/core/cli.py traffic-status" | crontab -) >/dev/null 2>&1 (crontab -l | grep -v "/etc/hysteria/core/scripts/hysteria2/kick.sh" | crontab -) >/dev/null 2>&1 -sleep 1 +#sleep 1 echo "Hysteria2 uninstalled!" echo "" \ No newline at end of file From f2c9cbf51670fdca11d7b87d389a2cc9a4ba8001 Mon Sep 17 00:00:00 2001 From: Sarina Date: Tue, 23 Jul 2024 17:36:25 +0330 Subject: [PATCH 63/91] Fix typo --- core/scripts/hysteria2/list_users.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/scripts/hysteria2/list_users.sh b/core/scripts/hysteria2/list_users.sh index b3d3608..ca76d18 100644 --- a/core/scripts/hysteria2/list_users.sh +++ b/core/scripts/hysteria2/list_users.sh @@ -3,4 +3,4 @@ source /etc/hysteria/core/scripts/path.sh -cat "$USER_FILE" \ No newline at end of file +cat "$USERS_FILE" \ No newline at end of file From 69a205a487b90a363a7e0e18c0b57b8821a3ebec Mon Sep 17 00:00:00 2001 From: Sarina Date: Tue, 23 Jul 2024 17:40:00 +0330 Subject: [PATCH 64/91] Improve error checking in listing users --- core/cli.py | 2 +- menu.sh | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/core/cli.py b/core/cli.py index ef9a4a3..62f2317 100644 --- a/core/cli.py +++ b/core/cli.py @@ -41,7 +41,7 @@ def run_cmd(command: list[str]): Runs a command and returns the output. Could raise subprocess.CalledProcessError ''' - if DEBUG and Command.GET_USER.value not in command: + if DEBUG and Command.GET_USER.value not in command and Command.LIST_USERS.value not in command: print(' '.join(command)) result = subprocess.check_output(command, shell=False) if DEBUG: diff --git a/menu.sh b/menu.sh index e144587..362cc74 100644 --- a/menu.sh +++ b/menu.sh @@ -143,7 +143,11 @@ hysteria2_get_user_handler() { } hysteria2_list_users_handler() { - users_json=$(python3 $CLI_PATH list-users) + users_json=$(python3 $CLI_PATH list-users 2>/dev/null) + if [ $? -ne 0 ] || [ -z "$users_json" ]; then + echo -e "\033[0;31mError:\033[0m Failed to list users." + return 1 + fi users_array=($(echo "$users_json" | jq -r '.[] | .username')) if [[ ${#users_array[@]} -eq 0 ]]; then From 6c2d6c0aaa8e6d4b50eff35c23c652a340818383 Mon Sep 17 00:00:00 2001 From: Sarina Date: Tue, 23 Jul 2024 17:51:25 +0330 Subject: [PATCH 65/91] Fix list_users_handler --- menu.sh | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/menu.sh b/menu.sh index 362cc74..87fa5af 100644 --- a/menu.sh +++ b/menu.sh @@ -148,25 +148,31 @@ hysteria2_list_users_handler() { echo -e "\033[0;31mError:\033[0m Failed to list users." return 1 fi - users_array=($(echo "$users_json" | jq -r '.[] | .username')) - if [[ ${#users_array[@]} -eq 0 ]]; then + # Extract keys (usernames) from JSON + users_keys=$(echo "$users_json" | jq -r 'keys[]') + + if [ -z "$users_keys" ]; then echo -e "\033[0;31mError:\033[0m No users found." return 1 fi # Print headers echo -e "\033[0;32mUsers:\033[0m" - printf "%-20s %-15s %-15s %-20s %-30s %-10s\n" "Username" "Traffic Limit (GB)" "Expiration (Days)" "Creation Date" "Password" "Blocked" + printf "%-20s %-20s %-15s %-20s %-30s %-10s\n" "Username" "Traffic Limit (GB)" "Expiration (Days)" "Creation Date" "Password" "Blocked" # Print user details - echo "$users_json" | jq -r '.[] | "\(.username) \(.traffic_limit_GB) \(.expiration_days) \(.creation_date) \(.password) \(.blocked)"' | \ - while IFS= read -r line; do - IFS=' ' read -r username traffic_limit expiration_date creation_date password blocked <<< "$line" - printf "%-20s %-15s %-15s %-20s %-30s %-10s\n" "$username" "$traffic_limit" "$expiration_date" "$creation_date" "$password" "$blocked" + for key in $users_keys; do + echo "$users_json" | jq -r --arg key "$key" ' + "\($key) \(.[$key].max_download_bytes / 1073741824) \(.[$key].expiration_days) \(.[$key].account_creation_date) \(.[$key].password) \(.[$key].blocked)"' | \ + while IFS= read -r line; do + IFS=' ' read -r username traffic_limit expiration_date creation_date password blocked <<< "$line" + printf "%-20s %-20s %-15s %-20s %-30s %-10s\n" "$username" "$traffic_limit" "$expiration_date" "$creation_date" "$password" "$blocked" + done done } + hysteria2_show_user_uri_handler() { while true; do read -p "Enter the username: " username From a1f58212a145a03be14aebb23d1b181009b4e6a3 Mon Sep 17 00:00:00 2001 From: Sarina Date: Tue, 23 Jul 2024 17:59:20 +0330 Subject: [PATCH 66/91] Refactor menu.sh --- menu.sh | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/menu.sh b/menu.sh index 87fa5af..22e472d 100644 --- a/menu.sh +++ b/menu.sh @@ -23,7 +23,7 @@ hysteria2_add_user_handler() { if [[ "$username" =~ ^[a-z0-9]+$ ]]; then break else - echo -e "\033[0;31mError:\033[0m Username can only contain lowercase letters and numbers." + echo -e "${red}Error:${NC} Username can only contain lowercase letters and numbers." fi done @@ -53,7 +53,7 @@ hysteria2_edit_user() { eval "$input_variable_name='$input'" break else - echo -e "\033[0;31mError:\033[0m Invalid input. Please try again." + echo -e "${red}Error:${NC} Invalid input. Please try again." fi done } @@ -63,7 +63,7 @@ hysteria2_edit_user() { # Check if user exists if ! python3 $CLI_PATH get-user --username "$username" > /dev/null 2>&1; then - echo -e "\033[0;31mError:\033[0m User '$username' not found." + echo -e "${red}Error:${NC} User '$username' not found." return 1 fi @@ -82,7 +82,7 @@ hysteria2_edit_user() { case "$renew_password" in y|Y) renew_password=true; break ;; n|N) renew_password=false; break ;; - *) echo -e "\033[0;31mError:\033[0m Please answer 'y' or 'n'." ;; + *) echo -e "${red}Error:${NC} Please answer 'y' or 'n'." ;; esac done @@ -92,7 +92,7 @@ hysteria2_edit_user() { case "$renew_creation_date" in y|Y) renew_creation_date=true; break ;; n|N) renew_creation_date=false; break ;; - *) echo -e "\033[0;31mError:\033[0m Please answer 'y' or 'n'." ;; + *) echo -e "${red}Error:${NC} Please answer 'y' or 'n'." ;; esac done @@ -102,7 +102,7 @@ hysteria2_edit_user() { case "$block_user" in y|Y) blocked=true; break ;; n|N) blocked=false; break ;; - *) echo -e "\033[0;31mError:\033[0m Please answer 'y' or 'n'." ;; + *) echo -e "${red}Error:${NC} Please answer 'y' or 'n'." ;; esac done @@ -124,7 +124,7 @@ hysteria2_remove_user_handler() { if [[ "$username" =~ ^[a-z0-9]+$ ]]; then break else - echo -e "\033[0;31mError:\033[0m Username can only contain lowercase letters and numbers." + echo -e "${red}Error:${NC} Username can only contain lowercase letters and numbers." fi done python3 $CLI_PATH remove-user --username "$username" @@ -136,7 +136,7 @@ hysteria2_get_user_handler() { if [[ "$username" =~ ^[a-z0-9]+$ ]]; then break else - echo -e "\033[0;31mError:\033[0m Username can only contain lowercase letters and numbers." + echo -e "${red}Error:${NC} Username can only contain lowercase letters and numbers." fi done python3 $CLI_PATH get-user --username "$username" @@ -145,7 +145,7 @@ hysteria2_get_user_handler() { hysteria2_list_users_handler() { users_json=$(python3 $CLI_PATH list-users 2>/dev/null) if [ $? -ne 0 ] || [ -z "$users_json" ]; then - echo -e "\033[0;31mError:\033[0m Failed to list users." + echo -e "${red}Error:${NC} Failed to list users." return 1 fi @@ -153,12 +153,11 @@ hysteria2_list_users_handler() { users_keys=$(echo "$users_json" | jq -r 'keys[]') if [ -z "$users_keys" ]; then - echo -e "\033[0;31mError:\033[0m No users found." + echo -e "${red}Error:${NC} No users found." return 1 fi # Print headers - echo -e "\033[0;32mUsers:\033[0m" printf "%-20s %-20s %-15s %-20s %-30s %-10s\n" "Username" "Traffic Limit (GB)" "Expiration (Days)" "Creation Date" "Password" "Blocked" # Print user details @@ -180,7 +179,7 @@ hysteria2_show_user_uri_handler() { if [[ "$username" =~ ^[a-z0-9]+$ ]]; then break else - echo -e "\033[0;31mError:\033[0m Username can only contain lowercase letters and numbers." + echo -e "${red}Error:${NC} Username can only contain lowercase letters and numbers." fi done python3 $CLI_PATH show-user-uri --username "$username" From b028d3fbc9ca828c751651a24916af33f3853c18 Mon Sep 17 00:00:00 2001 From: Sarina Date: Tue, 23 Jul 2024 18:15:57 +0330 Subject: [PATCH 67/91] Modify configure-warp in cli.py --- core/cli.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/core/cli.py b/core/cli.py index 62f2317..8b0666f 100644 --- a/core/cli.py +++ b/core/cli.py @@ -215,10 +215,12 @@ def uninstall_warp(): @ cli.command('configure-warp') -@ click.option('--warp-mode', '-m', required=True, help='Warp mode', type=click.Choice(['proxy', 'direct', 'reject'])) -@ click.option('--block-porn', '-p', required=False, help='Block porn', type=bool) -def configure_warp(warp_mode: str, block_porn: bool): - run_cmd(['bash', Command.CONFIGURE_WARP.value, warp_mode, str(block_porn)]) +@ click.option('--all', '-a', is_flag=True, help='Use WARP for all connections') +@ 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)') +def configure_warp(all: bool, popular_sites: bool, domestic_sites: bool, block_adult_sites: bool): + run_cmd(['bash', Command.CONFIGURE_WARP.value, str(all).lower(), str(popular_sites).lower(), str(domestic_sites).lower(), str(block_adult_sites).lower()]) # endregion From fe47551904954e55d7968a7daaead474a54d2760 Mon Sep 17 00:00:00 2001 From: Sarina Date: Tue, 23 Jul 2024 18:23:47 +0330 Subject: [PATCH 68/91] Error handling for get_user --- menu.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/menu.sh b/menu.sh index 22e472d..6bee8bf 100644 --- a/menu.sh +++ b/menu.sh @@ -139,7 +139,12 @@ hysteria2_get_user_handler() { echo -e "${red}Error:${NC} Username can only contain lowercase letters and numbers." fi done - python3 $CLI_PATH get-user --username "$username" + + # Run the command and suppress error output + if ! python3 "$CLI_PATH" get-user --username "$username" > /dev/null 2>&1; then + echo -e "${red}Error:${NC} User '$username' not found." + return 1 + fi } hysteria2_list_users_handler() { From 2b0020121a737b11bc08ad4fb9e4464f6ddcd177 Mon Sep 17 00:00:00 2001 From: Sarina Date: Mon, 29 Jul 2024 17:09:01 +0330 Subject: [PATCH 69/91] Refactor configure.sh --- core/scripts/warp/configure.sh | 139 ++++++++++++++++++++------------- 1 file changed, 83 insertions(+), 56 deletions(-) diff --git a/core/scripts/warp/configure.sh b/core/scripts/warp/configure.sh index 249748c..0f3a5eb 100644 --- a/core/scripts/warp/configure.sh +++ b/core/scripts/warp/configure.sh @@ -3,20 +3,28 @@ # Source the path.sh script to load the CONFIG_FILE and CLI_PATH variables source /etc/hysteria/core/scripts/path.sh -# Check if wg-quick@wgcf.service is active -if ! systemctl is-active --quiet wg-quick@wgcf.service; then - echo "WARP is not active. Please install WARP before configuring." - exit 1 -fi +check_warp_service() { + if ! systemctl is-active --quiet wg-quick@wgcf.service; then + echo "WARP is not active. Please install WARP before configuring." + exit 1 + fi +} -# Check if the config file exists -if [ -f "$CONFIG_FILE" ]; then - # Check the current status of WARP configurations +check_config_file() { + if [ ! -f "$CONFIG_FILE" ]; then + echo "Error: Config file $CONFIG_FILE not found." + exit 1 + fi +} + +get_status() { warp_all_status=$(jq -r 'if .acl.inline | index("warps(all)") then "WARP active" else "Direct" end' "$CONFIG_FILE") google_openai_status=$(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") iran_status=$(jq -r 'if (.acl.inline | index("warps(geosite:ir)")) and (.acl.inline | index("warps(geoip:ir)")) then "Use WARP" else "Reject" end' "$CONFIG_FILE") adult_content_status=$(jq -r 'if .acl.inline | index("reject(geosite:category-porn)") then "Blocked" else "Not blocked" end' "$CONFIG_FILE") +} +display_menu() { echo "===== Configuration Menu =====" echo "1. Use WARP for all traffic ($warp_all_status)" echo "2. Use WARP for Google, OpenAI, etc. ($google_openai_status)" @@ -24,55 +32,74 @@ if [ -f "$CONFIG_FILE" ]; then echo "4. Block adult content ($adult_content_status)" echo "5. Back to Advance Menu" echo "===================================" +} - read -p "Enter your choice: " choice +update_config() { + local jq_command=$1 + jq "$jq_command" "$CONFIG_FILE" > "${CONFIG_FILE}.temp" && mv "${CONFIG_FILE}.temp" "$CONFIG_FILE" +} + +configure_warp_all() { + if [ "$warp_all_status" == "WARP active" ]; then + update_config 'del(.acl.inline[] | select(. == "warps(all)"))' + echo "Traffic configuration changed to Direct." + else + update_config '.acl.inline += ["warps(all)"]' + echo "Traffic configuration changed to WARP." + fi +} + +configure_google_openai() { + if [ "$google_openai_status" == "WARP active" ]; then + update_config '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)"))' + echo "WARP configuration for Google, OpenAI, etc. removed." + else + update_config '.acl.inline += ["warps(geoip:google)", "warps(geosite:google)", "warps(geosite:netflix)", "warps(geosite:spotify)", "warps(geosite:openai)", "warps(geoip:openai)"]' + echo "WARP configured for Google, OpenAI, etc." + fi +} + +configure_iran() { + if [ "$iran_status" == "Use WARP" ]; then + update_config '(.acl.inline[] | select(. == "warps(geosite:ir)")) = "reject(geosite:ir)" | (.acl.inline[] | select(. == "warps(geoip:ir)")) = "reject(geoip:ir)"' + echo "Configuration changed to Reject for geosite:ir and geoip:ir." + else + update_config '(.acl.inline[] | select(. == "reject(geosite:ir)")) = "warps(geosite:ir)" | (.acl.inline[] | select(. == "reject(geoip:ir)")) = "warps(geoip:ir)"' + echo "Configuration changed to Use WARP for geosite:ir and geoip:ir." + fi +} + +configure_adult_content() { + if [ "$adult_content_status" == "Blocked" ]; then + update_config 'del(.acl.inline[] | select(. == "reject(geosite:category-porn)"))' + update_config '.resolver.tls.addr = "1.1.1.1:853"' + echo "Adult content blocking removed and resolver updated." + else + update_config '.acl.inline += ["reject(geosite:category-porn)"]' + update_config '.resolver.tls.addr = "1.1.1.3:853"' + echo "Adult content blocked and resolver updated." + fi +} + +handle_choice() { case $choice in - 1) - if [ "$warp_all_status" == "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 - ;; - 2) - if [ "$google_openai_status" == "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 - ;; - 3) - if [ "$iran_status" == "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 - ;; - 4) - if [ "$adult_content_status" == "Blocked" ]; then - jq 'del(.acl.inline[] | select(. == "reject(geosite:category-porn)"))' "$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:category-porn)"]' "$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 - ;; - 5) - exit 0 - ;; - *) - echo "Invalid option. Please try again." - ;; + 1) configure_warp_all ;; + 2) configure_google_openai ;; + 3) configure_iran ;; + 4) configure_adult_content ;; + 5) exit 0 ;; + *) echo "Invalid option. Please try again." ;; esac python3 "$CLI_PATH" restart-hysteria2 > /dev/null 2>&1 -else - echo "Error: Config file $CONFIG_FILE not found." -fi +} + +main() { + check_warp_service + check_config_file + get_status + display_menu + read -p "Enter your choice: " choice + handle_choice +} + +main From a80573ebf73cf5faa762ce5a5d7dff7c4922bbe1 Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Mon, 29 Jul 2024 19:18:31 +0330 Subject: [PATCH 70/91] Update URL --- install.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/install.sh b/install.sh index e213f87..e4cd4c0 100644 --- a/install.sh +++ b/install.sh @@ -13,9 +13,7 @@ if ! command -v jq &> /dev/null || ! command -v git &> /dev/null || ! command -v apt update && apt upgrade -y && apt install jq qrencode curl pwgen uuid-runtime python3 python3-pip git -y fi - -# TODO: change the url later -git clone https://github.com/Iam54r1n4/Hysteria2 /etc/hysteria +git clone https://github.com/ReturnFI/Hysteria2 /etc/hysteria # Add alias 'hys2' for Hysteria2 if ! grep -q "alias hys2='/etc/hysteria/menu.sh'" ~/.bashrc; then From 5a8f022f64d6a80684315735caf90bb2b337e8f2 Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Mon, 29 Jul 2024 19:19:52 +0330 Subject: [PATCH 71/91] Update Timeout --- config.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config.json b/config.json index 81afeba..7dcdceb 100644 --- a/config.json +++ b/config.json @@ -21,7 +21,7 @@ "maxStreamReceiveWindow": 8388608, "initConnReceiveWindow": 20971520, "maxConnReceiveWindow": 20971520, - "maxIdleTimeout": "60s", + "maxIdleTimeout": "20s", "maxIncomingStreams": 60, "disablePathMTUDiscovery": false }, @@ -31,7 +31,7 @@ }, "ignoreClientBandwidth": false, "disableUDP": false, - "udpIdleTimeout": "60s", + "udpIdleTimeout": "20s", "resolver": { "type": "tls", "tcp": { @@ -80,4 +80,4 @@ "listen": "127.0.0.1:25413", "secret": "$UUID" } -} \ No newline at end of file +} From 4fe406ef38af64730030edf068bd394f00b9bfdd Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Mon, 29 Jul 2024 22:42:01 +0330 Subject: [PATCH 72/91] Update Warp configure --- core/cli.py | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/core/cli.py b/core/cli.py index 8b0666f..3f1aea2 100644 --- a/core/cli.py +++ b/core/cli.py @@ -214,13 +214,22 @@ def uninstall_warp(): run_cmd(['bash', Command.UNINSTALL_WARP.value]) -@ cli.command('configure-warp') -@ click.option('--all', '-a', is_flag=True, help='Use WARP for all connections') -@ 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)') +@cli.command('configure-warp') +@click.option('--all', '-a', is_flag=True, help='Use WARP for all connections') +@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)') def configure_warp(all: bool, popular_sites: bool, domestic_sites: bool, block_adult_sites: bool): - run_cmd(['bash', Command.CONFIGURE_WARP.value, str(all).lower(), str(popular_sites).lower(), str(domestic_sites).lower(), str(block_adult_sites).lower()]) + options = { + "all": all, + "popular_sites": popular_sites, + "domestic_sites": domestic_sites, + "block_adult_sites": block_adult_sites + } + + options = {k: 'true' if v else 'false' for k, v in options.items()} + run_cmd(['bash', Command.CONFIGURE_WARP.value, + options['all'], options['popular_sites'], options['domestic_sites'], options['block_adult_sites']]) # endregion From d9ef3f38d3914e3925e643cead1a6586350fa80b Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Mon, 29 Jul 2024 22:43:36 +0330 Subject: [PATCH 73/91] Update configure.sh --- core/scripts/warp/configure.sh | 131 +++++++++++---------------------- 1 file changed, 41 insertions(+), 90 deletions(-) diff --git a/core/scripts/warp/configure.sh b/core/scripts/warp/configure.sh index 0f3a5eb..439409c 100644 --- a/core/scripts/warp/configure.sh +++ b/core/scripts/warp/configure.sh @@ -1,105 +1,56 @@ #!/bin/bash -# Source the path.sh script to load the CONFIG_FILE and CLI_PATH variables source /etc/hysteria/core/scripts/path.sh -check_warp_service() { - if ! systemctl is-active --quiet wg-quick@wgcf.service; then - echo "WARP is not active. Please install WARP before configuring." - exit 1 +warp_configure_handler() { + local all=$1 + local popular_sites=$2 + local domestic_sites=$3 + local block_adult_sites=$4 + + 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 -} -check_config_file() { - if [ ! -f "$CONFIG_FILE" ]; then - echo "Error: Config file $CONFIG_FILE not found." - exit 1 + 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 -} -get_status() { - warp_all_status=$(jq -r 'if .acl.inline | index("warps(all)") then "WARP active" else "Direct" end' "$CONFIG_FILE") - google_openai_status=$(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") - iran_status=$(jq -r 'if (.acl.inline | index("warps(geosite:ir)")) and (.acl.inline | index("warps(geoip:ir)")) then "Use WARP" else "Reject" end' "$CONFIG_FILE") - adult_content_status=$(jq -r 'if .acl.inline | index("reject(geosite:category-porn)") then "Blocked" else "Not blocked" end' "$CONFIG_FILE") -} - -display_menu() { - echo "===== Configuration Menu =====" - echo "1. Use WARP for all traffic ($warp_all_status)" - echo "2. Use WARP for Google, OpenAI, etc. ($google_openai_status)" - echo "3. Use WARP for geosite:ir and geoip:ir ($iran_status)" - echo "4. Block adult content ($adult_content_status)" - echo "5. Back to Advance Menu" - echo "===================================" -} - -update_config() { - local jq_command=$1 - jq "$jq_command" "$CONFIG_FILE" > "${CONFIG_FILE}.temp" && mv "${CONFIG_FILE}.temp" "$CONFIG_FILE" -} - -configure_warp_all() { - if [ "$warp_all_status" == "WARP active" ]; then - update_config 'del(.acl.inline[] | select(. == "warps(all)"))' - echo "Traffic configuration changed to Direct." - else - update_config '.acl.inline += ["warps(all)"]' - echo "Traffic configuration changed to WARP." + 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 -} -configure_google_openai() { - if [ "$google_openai_status" == "WARP active" ]; then - update_config '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)"))' - echo "WARP configuration for Google, OpenAI, etc. removed." - else - update_config '.acl.inline += ["warps(geoip:google)", "warps(geosite:google)", "warps(geosite:netflix)", "warps(geosite:spotify)", "warps(geosite:openai)", "warps(geoip:openai)"]' - echo "WARP configured for Google, OpenAI, etc." + if [ "$block_adult_sites" == "true" ]; then + if [ "$(jq -r 'if .acl.inline | index("reject(geosite:category-porn)") then "Blocked" else "Not blocked" end' "$CONFIG_FILE")" == "Blocked" ]; then + jq 'del(.acl.inline[] | select(. == "reject(geosite:category-porn)"))' "$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:category-porn)"]' "$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 -} -configure_iran() { - if [ "$iran_status" == "Use WARP" ]; then - update_config '(.acl.inline[] | select(. == "warps(geosite:ir)")) = "reject(geosite:ir)" | (.acl.inline[] | select(. == "warps(geoip:ir)")) = "reject(geoip:ir)"' - echo "Configuration changed to Reject for geosite:ir and geoip:ir." - else - update_config '(.acl.inline[] | select(. == "reject(geosite:ir)")) = "warps(geosite:ir)" | (.acl.inline[] | select(. == "reject(geoip:ir)")) = "warps(geoip:ir)"' - echo "Configuration changed to Use WARP for geosite:ir and geoip:ir." - fi -} - -configure_adult_content() { - if [ "$adult_content_status" == "Blocked" ]; then - update_config 'del(.acl.inline[] | select(. == "reject(geosite:category-porn)"))' - update_config '.resolver.tls.addr = "1.1.1.1:853"' - echo "Adult content blocking removed and resolver updated." - else - update_config '.acl.inline += ["reject(geosite:category-porn)"]' - update_config '.resolver.tls.addr = "1.1.1.3:853"' - echo "Adult content blocked and resolver updated." - fi -} - -handle_choice() { - case $choice in - 1) configure_warp_all ;; - 2) configure_google_openai ;; - 3) configure_iran ;; - 4) configure_adult_content ;; - 5) exit 0 ;; - *) echo "Invalid option. Please try again." ;; - esac python3 "$CLI_PATH" restart-hysteria2 > /dev/null 2>&1 } -main() { - check_warp_service - check_config_file - get_status - display_menu - read -p "Enter your choice: " choice - handle_choice -} - -main +warp_configure_handler "$1" "$2" "$3" "$4" From d45188f0617996800ae96ead790653300659ad45 Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Mon, 29 Jul 2024 22:44:36 +0330 Subject: [PATCH 74/91] Fix Warp Configure --- menu.sh | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/menu.sh b/menu.sh index 6bee8bf..f820275 100644 --- a/menu.sh +++ b/menu.sh @@ -203,8 +203,30 @@ hysteria2_change_port_handler() { } warp_configure_handler() { - # Placeholder function, add implementation here if needed - echo "empty" + local service_name="wg-quick@wgcf.service" + + if systemctl is-active --quiet "$service_name"; then + echo "Configure WARP Options:" + echo "1. Use WARP for all traffic" + echo "2. Use WARP for popular sites" + echo "3. Use WARP for domestic sites" + echo "4. Block adult content" + echo "0. Cancel" + + read -p "Select an option: " option + + case $option in + 1) python3 $CLI_PATH configure-warp --all ;; + 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 ;; + 0) echo "WARP configuration canceled." ;; + *) echo "Invalid option. Please try again." ;; + esac + else + # Notify user if the service is not active + echo "$service_name is not active. Please start the service before configuring WARP." + fi } # Function to display the main menu From 4be0791aee677f51754b6d12f728c4fc6e10717e Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Mon, 29 Jul 2024 22:45:04 +0330 Subject: [PATCH 75/91] fix main menu --- menu.sh | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/menu.sh b/menu.sh index f820275..6ed764b 100644 --- a/menu.sh +++ b/menu.sh @@ -362,10 +362,5 @@ advance_menu() { } # Main function to run the script -main() { - main_menu -} - -define_colors -# Run the main function main + From 5b723c42ca62e9e323ed51af2bd1a9431495b372 Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Mon, 29 Jul 2024 22:46:47 +0330 Subject: [PATCH 76/91] Update regex pattern --- menu.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/menu.sh b/menu.sh index 6ed764b..5a3bbc8 100644 --- a/menu.sh +++ b/menu.sh @@ -20,10 +20,10 @@ hysteria2_add_user_handler() { while true; do read -p "Enter the username: " username - if [[ "$username" =~ ^[a-z0-9]+$ ]]; then + if [[ "$username" =~ ^[a-zA-Z0-9]+$ ]]; then break else - echo -e "${red}Error:${NC} Username can only contain lowercase letters and numbers." + echo -e "${red}Error:${NC} Username can only contain letters and numbers." fi done @@ -121,10 +121,10 @@ hysteria2_remove_user_handler() { while true; do read -p "Enter the username: " username - if [[ "$username" =~ ^[a-z0-9]+$ ]]; then + if [[ "$username" =~ ^[a-zA-Z0-9]+$ ]]; then break else - echo -e "${red}Error:${NC} Username can only contain lowercase letters and numbers." + echo -e "${red}Error:${NC} Username can only contain letters and numbers." fi done python3 $CLI_PATH remove-user --username "$username" @@ -133,10 +133,10 @@ hysteria2_remove_user_handler() { hysteria2_get_user_handler() { while true; do read -p "Enter the username: " username - if [[ "$username" =~ ^[a-z0-9]+$ ]]; then + if [[ "$username" =~ ^[a-zA-Z0-9]+$ ]]; then break else - echo -e "${red}Error:${NC} Username can only contain lowercase letters and numbers." + echo -e "${red}Error:${NC} Username can only contain letters and numbers." fi done @@ -181,10 +181,10 @@ hysteria2_show_user_uri_handler() { while true; do read -p "Enter the username: " username - if [[ "$username" =~ ^[a-z0-9]+$ ]]; then + if [[ "$username" =~ ^[a-zA-Z0-9]+$ ]]; then break else - echo -e "${red}Error:${NC} Username can only contain lowercase letters and numbers." + echo -e "${red}Error:${NC} Username can only contain letters and numbers." fi done python3 $CLI_PATH show-user-uri --username "$username" From 01338a62901fcff6c369fecdae4925d27482b5d5 Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Mon, 29 Jul 2024 22:47:36 +0330 Subject: [PATCH 77/91] Check installation --- menu.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/menu.sh b/menu.sh index 5a3bbc8..e141846 100644 --- a/menu.sh +++ b/menu.sh @@ -5,6 +5,12 @@ source /etc/hysteria/core/scripts/path.sh # OPTION HANDLERS (ONLY NEEDED ONE) hysteria2_install_handler() { + if systemctl is-active --quiet hysteria-server.service; then + echo "The hysteria-server.service is currently active." + echo "If you need to update the core, please use the 'Update Core' option." + return + fi + while true; do read -p "Enter the new port number you want to use: " port if ! [[ "$port" =~ ^[0-9]+$ ]] || [ "$port" -lt 1 ] || [ "$port" -gt 65535 ]; then @@ -13,6 +19,7 @@ hysteria2_install_handler() { break fi done + python3 $CLI_PATH install-hysteria2 --port "$port" } From fe8ae2a30df5e91f27f22c73e0e45ac853278fe0 Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Mon, 29 Jul 2024 22:49:29 +0330 Subject: [PATCH 78/91] Update regex pattern --- core/scripts/hysteria2/add_user.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/scripts/hysteria2/add_user.sh b/core/scripts/hysteria2/add_user.sh index 90b3844..be326fa 100644 --- a/core/scripts/hysteria2/add_user.sh +++ b/core/scripts/hysteria2/add_user.sh @@ -37,8 +37,8 @@ add_user() { fi # Validate the username - if ! [[ "$username" =~ ^[a-z0-9]+$ ]]; then - echo -e "${red}Error:${NC} Username can only contain lowercase letters and numbers." + if ! [[ "$username" =~ ^[a-zA-Z0-9]+$ ]]; then + echo -e "${red}Error:${NC} Username can only contain letters and numbers." exit 1 fi From 837f0fe6ce10cb16e3e09a17b22678ecc48ca65b Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Mon, 29 Jul 2024 22:49:50 +0330 Subject: [PATCH 79/91] Update regex pattern --- core/scripts/hysteria2/edit_user.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/scripts/hysteria2/edit_user.sh b/core/scripts/hysteria2/edit_user.sh index 3fc4c4d..66459be 100644 --- a/core/scripts/hysteria2/edit_user.sh +++ b/core/scripts/hysteria2/edit_user.sh @@ -14,8 +14,8 @@ validate_inputs() { # Validate username if [ -n "$new_username" ]; then - if ! [[ "$new_username" =~ ^[a-z0-9]+$ ]]; then - echo -e "${red}Error:${NC} Username can only contain lowercase letters and numbers." + if ! [[ "$new_username" =~ ^[a-zA-Z0-9]+$ ]]; then + echo -e "${red}Error:${NC} Username can only contain letters and numbers." exit 1 fi fi From c92526f4ec79506584af83628ccad0acbeeadb7f Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Mon, 29 Jul 2024 22:50:42 +0330 Subject: [PATCH 80/91] Update Install URL --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0db083d..814d96c 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ This shell script provides a menu-driven interface to manage Hysteria2 server op ### Install command : ```shell -bash <(curl https://raw.githubusercontent.com/ReturnFI/Hysteria2/main/menu.sh) +bash <(curl https://raw.githubusercontent.com/ReturnFI/Hysteria2/main/install.sh) ```

From c2fa6280308b043b7f909203d89a0b94b7bacb33 Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Mon, 29 Jul 2024 22:57:50 +0330 Subject: [PATCH 81/91] Beta Clone --- install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.sh b/install.sh index e4cd4c0..279e22b 100644 --- a/install.sh +++ b/install.sh @@ -13,7 +13,7 @@ if ! command -v jq &> /dev/null || ! command -v git &> /dev/null || ! command -v apt update && apt upgrade -y && apt install jq qrencode curl pwgen uuid-runtime python3 python3-pip git -y fi -git clone https://github.com/ReturnFI/Hysteria2 /etc/hysteria +git clone -b beta https://github.com/ReturnFI/Hysteria2 /etc/hysteria # Add alias 'hys2' for Hysteria2 if ! grep -q "alias hys2='/etc/hysteria/menu.sh'" ~/.bashrc; then From 475c74638d19ce6e6d2c7fcda5e956631cff4b6e Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Mon, 29 Jul 2024 23:00:31 +0330 Subject: [PATCH 82/91] call main_menu --- menu.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/menu.sh b/menu.sh index e141846..49d639f 100644 --- a/menu.sh +++ b/menu.sh @@ -369,5 +369,5 @@ advance_menu() { } # Main function to run the script -main +main_menu From 65b76bb18453ac4e6ccdf5ed71f5faf8d43f884a Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Mon, 29 Jul 2024 23:10:33 +0330 Subject: [PATCH 83/91] Update menu.sh --- menu.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/menu.sh b/menu.sh index 49d639f..4c63818 100644 --- a/menu.sh +++ b/menu.sh @@ -370,4 +370,4 @@ advance_menu() { # Main function to run the script main_menu - +define_colors From 632826a69bf49ffc9e6361b8dec105e98d3ca35a Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Mon, 29 Jul 2024 23:11:50 +0330 Subject: [PATCH 84/91] Fix define colors --- menu.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/menu.sh b/menu.sh index 4c63818..32ef8db 100644 --- a/menu.sh +++ b/menu.sh @@ -369,5 +369,5 @@ advance_menu() { } # Main function to run the script -main_menu define_colors +main_menu From ada839714d4c152c7b958637ba3397d59f4a041e Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Thu, 1 Aug 2024 23:24:02 +0330 Subject: [PATCH 85/91] Fix Edit user --- core/cli.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/cli.py b/core/cli.py index 3f1aea2..4c8421f 100644 --- a/core/cli.py +++ b/core/cli.py @@ -167,12 +167,13 @@ def edit_user(username: str, new_username: str, new_traffic_limit: int, new_expi str(new_expiration_days) if new_expiration_days is not None else '', password, creation_date, - str(blocked).lower() if blocked is not None else 'false' + 'true' if blocked else 'false' ] run_cmd(command_args) + @ cli.command('remove-user') @ click.option('--username', '-u', required=True, help='Username for the user to remove', type=str) def remove_user(username: str): From 1075a3616be23673849d3f936e7177983e2a1223 Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Thu, 1 Aug 2024 23:25:03 +0330 Subject: [PATCH 86/91] Fix Edit user --- menu.sh | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/menu.sh b/menu.sh index 32ef8db..59fb3e3 100644 --- a/menu.sh +++ b/menu.sh @@ -83,7 +83,7 @@ hysteria2_edit_user() { # Prompt for new expiration days prompt_for_input "Enter the new expiration days (leave empty to keep the current expiration days): " '^[0-9]*$' '' new_expiration_days - # Prompt for renewing password + # Determine if we need to renew password while true; do read -p "Do you want to generate a new password? (y/n): " renew_password case "$renew_password" in @@ -93,7 +93,7 @@ hysteria2_edit_user() { esac done - # Prompt for renewing creation date + # Determine if we need to renew creation date while true; do read -p "Do you want to generate a new creation date? (y/n): " renew_creation_date case "$renew_creation_date" in @@ -103,7 +103,7 @@ hysteria2_edit_user() { esac done - # Prompt for blocking user + # Determine if user should be blocked while true; do read -p "Do you want to block the user? (y/n): " block_user case "$block_user" in @@ -113,15 +113,17 @@ hysteria2_edit_user() { esac done - # Call the edit-user script with appropriate flags - python3 $CLI_PATH edit-user \ - --username "$username" \ - ${new_username:+--new-username "$new_username"} \ - ${new_traffic_limit_GB:+--new-traffic-limit "$new_traffic_limit_GB"} \ - ${new_expiration_days:+--new-expiration-days "$new_expiration_days"} \ - ${renew_password:+--renew-password} \ - ${renew_creation_date:+--renew-creation-date} \ - ${blocked:+--blocked} + # Construct the arguments for the edit-user command + args=() + if [[ -n "$new_username" ]]; then args+=("--new-username" "$new_username"); fi + if [[ -n "$new_traffic_limit_GB" ]]; then args+=("--new-traffic-limit" "$new_traffic_limit_GB"); fi + if [[ -n "$new_expiration_days" ]]; then args+=("--new-expiration-days" "$new_expiration_days"); fi + if [[ "$renew_password" == "true" ]]; then args+=("--renew-password"); fi + if [[ "$renew_creation_date" == "true" ]]; then args+=("--renew-creation-date"); fi + if [[ "$blocked" == "true" ]]; then args+=("--blocked"); fi + + # Call the edit-user script with the constructed arguments + python3 $CLI_PATH edit-user --username "$username" "${args[@]}" } hysteria2_remove_user_handler() { From a9197fc05af9c6220e56645cddcd3b0d288c22cc Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Thu, 1 Aug 2024 23:25:39 +0330 Subject: [PATCH 87/91] Update edit user --- core/scripts/hysteria2/edit_user.sh | 97 ++++++++++++++++------------- 1 file changed, 52 insertions(+), 45 deletions(-) diff --git a/core/scripts/hysteria2/edit_user.sh b/core/scripts/hysteria2/edit_user.sh index 66459be..f078f3c 100644 --- a/core/scripts/hysteria2/edit_user.sh +++ b/core/scripts/hysteria2/edit_user.sh @@ -21,7 +21,7 @@ validate_inputs() { fi # Validate traffic limit - if [[ ! "$new_traffic_limit" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then + if [ -n "$new_traffic_limit" ]; then if ! [[ "$new_traffic_limit" =~ ^[0-9]+$ ]]; then echo -e "${red}Error:${NC} Traffic limit must be a valid integer." exit 1 @@ -49,13 +49,24 @@ validate_inputs() { # Validate blocked status if [ -n "$new_blocked" ]; then - if [ "$new_blocked" != "true" ] && [ "$new_blocked" != "false" ]; then - echo -e "${red}Error:${NC} Blocked status must be 'true' or 'false'." + if [ "$new_blocked" != "true" ] && [ "$new_blocked" != "false" ] && [ "$new_blocked" != "y" ] && [ "$new_blocked" != "n" ]; then + echo -e "${red}Error:${NC} Blocked status must be 'true', 'false', 'y', or 'n'." exit 1 fi fi } +# Convert 'y'/'n' to 'true'/'false' +convert_blocked_status() { + local status=$1 + case "$status" in + y|Y) echo "true" ;; + n|N) echo "false" ;; + true|false) echo "$status" ;; + *) echo "false" ;; # Default to false if something unexpected + esac +} + # Function to get user info get_user_info() { local username=$1 @@ -77,52 +88,43 @@ update_user_info() { return 1 fi - - echo "checking if user exists" - # Check if the old username exists + echo "Checking if user exists" user_exists=$(jq -e --arg username "$old_username" '.[$username]' "$USERS_FILE") if [ $? -ne 0 ]; then echo "Error: User '$old_username' not found." return 1 fi - echo "user exists done" + echo "User exists." - echo "change key" - # If new_username is provided and different from old_username, rename the key - if [ -n "$new_username" ] && [ "$old_username" != "$new_username" ]; then - jq --arg old_username "$old_username" \ - --arg new_username "$new_username" \ - 'if .[$new_username] then error("User already exists with new username") else . end | - .[$new_username] = .[$old_username] | del(.[$old_username])' \ - "$USERS_FILE" > tmp.$$.json && mv tmp.$$.json "$USERS_FILE" + # Debugging output + echo "Updating user:" + echo "Username: $new_username" + echo "Password: $new_password" + echo "Max Download Bytes: $new_max_download_bytes" + echo "Expiration Days: $new_expiration_days" + echo "Creation Date: $new_account_creation_date" + echo "Blocked: $new_blocked" - if [ $? -ne 0 ]; then - echo "Error: Failed to rename user '$old_username' to '$new_username'." - return 1 - fi - fi - echo "change key done" + # Update user fields, only if new values are provided + jq --arg old_username "$old_username" \ + --arg new_username "$new_username" \ + --arg password "${new_password:-null}" \ + --argjson max_download_bytes "${new_max_download_bytes:-null}" \ + --argjson expiration_days "${new_expiration_days:-null}" \ + --arg account_creation_date "${new_creation_date:-null}" \ + --argjson blocked "$(convert_blocked_status "${new_blocked:-false}")" \ + ' + .[$new_username] = .[$old_username] | + del(.[$old_username]) | + .[$new_username] |= ( + .password = ($password // .password) | + .max_download_bytes = ($max_download_bytes // .max_download_bytes) | + .expiration_days = ($expiration_days // .expiration_days) | + .account_creation_date = ($account_creation_date // .account_creation_date) | + .blocked = $blocked + )' "$USERS_FILE" > tmp.$$.json && mv tmp.$$.json "$USERS_FILE" - echo "update user fields" - # print all new values - echo "Old username" "$old_username" - echo "New username: $new_username" - echo "New password: $new_password" - echo "New traffic limit: $new_max_download_bytes" - echo "New expiration days: $new_expiration_days" - echo "New creation date: $new_account_creation_date" - echo "New blocked status: $new_blocked" - jq --arg username "$new_username" \ - --arg password "$new_password" \ - --argjson max_download_bytes "$new_max_download_bytes" \ - --argjson expiration_days "$new_expiration_days" \ - --arg account_creation_date "$new_account_creation_date" \ - --argjson blocked "$new_blocked" \ - '.[$username] |= (.password = $password | .max_download_bytes = $max_download_bytes | .expiration_days = $expiration_days | .account_creation_date = $account_creation_date | .blocked = $blocked)' \ - "$USERS_FILE" > tmp.$$.json && mv tmp.$$.json "$USERS_FILE" - - echo "update user fields done" if [ $? -ne 0 ]; then echo "Error: Failed to update user '$old_username'." return 1 @@ -131,7 +133,6 @@ update_user_info() { echo "User '$old_username' updated successfully." } - # Main function to edit user edit_user() { local username=$1 @@ -162,16 +163,22 @@ edit_user() { # Set new values with validation new_username=${new_username:-$username} new_password=${new_password:-$password} - new_traffic_limit=${new_traffic_limit:-$traffic_limit} - new_traffic_limit=$(echo "$new_traffic_limit * 1073741824" | bc) + + # Convert traffic limit to bytes if provided, otherwise keep existing + if [ -n "$new_traffic_limit" ]; then + new_traffic_limit=$(echo "$new_traffic_limit * 1073741824" | bc) + else + new_traffic_limit=$traffic_limit + fi + new_expiration_days=${new_expiration_days:-$expiration_days} new_creation_date=${new_creation_date:-$creation_date} - new_blocked=${new_blocked:-$blocked} - + new_blocked=$(convert_blocked_status "${new_blocked:-$blocked}") # Update user info in JSON file update_user_info "$username" "$new_username" "$new_password" "$new_traffic_limit" "$new_expiration_days" "$new_creation_date" "$new_blocked" } + # Run the script edit_user "$1" "$2" "$3" "$4" "$5" "$6" "$7" From cbed8ae1b518c247b3942e90fd45d22fc733eb20 Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Fri, 2 Aug 2024 11:58:58 +0330 Subject: [PATCH 88/91] Update regex pattern --- menu.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/menu.sh b/menu.sh index 59fb3e3..f1e3ee5 100644 --- a/menu.sh +++ b/menu.sh @@ -66,7 +66,7 @@ hysteria2_edit_user() { } # Prompt for username - prompt_for_input "Enter the username you want to edit: " '^[a-z0-9]+$' '' username + prompt_for_input "Enter the username you want to edit: " '^[a-zA-Z0-9]+$' '' username # Check if user exists if ! python3 $CLI_PATH get-user --username "$username" > /dev/null 2>&1; then @@ -75,7 +75,7 @@ hysteria2_edit_user() { fi # Prompt for new username - prompt_for_input "Enter the new username (leave empty to keep the current username): " '^[a-z0-9]*$' '' new_username + prompt_for_input "Enter the new username (leave empty to keep the current username): " '^[a-zA-Z0-9]*$' '' new_username # Prompt for new traffic limit prompt_for_input "Enter the new traffic limit (in GB) (leave empty to keep the current limit): " '^[0-9]*$' '' new_traffic_limit_GB From 3f7f25eba1dc2053e8813fc12098152766236a5a Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Fri, 2 Aug 2024 12:03:06 +0330 Subject: [PATCH 89/91] Fix color --- core/scripts/hysteria2/install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/scripts/hysteria2/install.sh b/core/scripts/hysteria2/install.sh index df8ee60..c473285 100644 --- a/core/scripts/hysteria2/install.sh +++ b/core/scripts/hysteria2/install.sh @@ -108,9 +108,9 @@ EOF # Step 13: Check if the hysteria-server.service is active if systemctl is-active --quiet hysteria-server.service; then - echo "${cyan}Hysteria2${green} has been successfully installed." + echo -e "${cyan}Hysteria2${green} has been successfully installed." else - echo "${red}Error:${NC} hysteria-server.service is not active." + echo -e "${red}Error:${NC} hysteria-server.service is not active." exit 1 fi From 103551a5948d00ceeadd436d05d67d058e112ff0 Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Fri, 2 Aug 2024 20:35:18 +0330 Subject: [PATCH 90/91] Update README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 814d96c..65f714d 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,12 @@ This shell script provides a menu-driven interface to manage Hysteria2 server op ```shell bash <(curl https://raw.githubusercontent.com/ReturnFI/Hysteria2/main/install.sh) ``` +After installation, simply use the command `hys2` to run the Hysteria2 script. +There is no need to execute the installation command again. + + +

From c97bb48d7a7efc80652a2236f0d3aca4a39499b4 Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Fri, 2 Aug 2024 20:36:01 +0330 Subject: [PATCH 91/91] Update README-fa.md --- README-fa.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README-fa.md b/README-fa.md index 17bca75..b4454ef 100644 --- a/README-fa.md +++ b/README-fa.md @@ -9,7 +9,9 @@ ```shell bash <(curl https://raw.githubusercontent.com/ReturnFI/Hysteria2/main/menu.sh) ``` +بعد از نصب کافیه از دستور `hys2` برای اجرای اسکریپت Hysteria2 استفاده کنید و نیازی به اجرا دستور نصب نیست. +